CRDTs use Math to ensure consistency in a distributed cluster, without worrying about consensus and the associated latency / inaccessibility.
The set of values that CRDT can take at any time belongs to the category of half-lattices (in particular, connection half-lattices), which is POSET (partially ordered set) with the smallest upper limit function (LUB).
Simply put, POSET is a collection of elements in which not all are comparable. For example. in the array of pairs: {(2,4), (4, 5), (2, 1), (6, 3)} , (2,4) is equal to < (4,5) , but cannot be compared with (6,3) (since one element is larger and the other is smaller). Now the semilattice is a POSET in which 2 pairs are given, even if you cannot compare them, you can find an element that is larger than both.
Another condition is that updates of this data type must increase, CRDTs have a monotonously increasing state when clients never see a rollback of the state.
This great article uses an array, which I used above as an example. For a CRDT that supports these values, if 2 replicas try to reach a consensus between (4,5) and (6,3) , they can choose LUB = (6,5) as consensus and assign it as replicas. As the values increase, this is a good value to calculate.
There are two ways to synchronize CRDT between replicas, they can transmit state through periodically (converged type of replicated data) or can transmit updates (delta) as they are received (switched type of replicated data), the first one uses a lot of bandwidth.
SoundCloud Roshi is a good example (although apparently it no longer works), they store data associated with a timestamp, where the timestamp is obviously increasing. Any updates that are in the timestamp less than or equal to the one stored are discarded, which guarantees idempotency (repeated entries in order) and commutativity (due to the lack of entries in order. Commutativity - a=b means b=a , which in in this case means update1 followed by update2 matches update2 and then update1)
The scripts are sent to all clusters, and if certain nodes cannot respond due to a problem, such as slowness or partition, they are expected to be reached later through read-repair , which guarantees convergence of values. Convergence can be achieved using two protocols, as I mentioned above, state propagation or updates to other replicas. I believe that Roshi is doing the first. As part of read-repair , the state of exchange of replicas, and because the data corresponds to the semi-lattice property, they converge.
PS. Systems using CRDTs are ultimately consistent, meaning they accept APs (highly accessible and partition resistant) in the CAP theorem .
Another great review on the topic.