Data consistency in distributed systems is hard. Most resort to eventual consistency so that all data across sources match after a while.
In this blog, we'll dive into the types of eventual consistency and their tradeoffs.
What is Eventual Consistency?
Eventual consistency is not a first choice. Strongly consistent systems are easy to understand and debug. Users love to see their actions reflected in underlying systems immediately (If you hit the like button and press refresh, you expect the new LIKE count to reflect it).
However, as engineers, we must expect the worst. Systems fail. Networks break. Clocks go askew.
In these cases, delayed data updates help systems survive incoming loads.
Types of Eventual Consistency
Read-your-writes Consistency
If a user performs a write operation and then reads from the system, they will see their newly written data.
It's a crucial level of consistency for user-facing applications where users expect to see their own updates immediately.
Monotonic Reads Consistency
A user's read operations will never "move backward" in time. If a user reads a value with timestamp X, subsequent reads will only show values that have a timestamp greater than X.
Monotonic Writes ConsistencY
Writes from a user are processed in the order of arrival. This helps maintain a logical order of events.
For example, take the operations: (X = 10), (Y = 10/X), (X -=10)
Only one sequence of operations will result in success.
Causal Consistency
This consistency level captures the cause-and-effect relationship between events. Two events related to each other must be processed in an ordered fashion.
For example, if (X = 10), (Y = 10/X), (X -=10), (P = SUM(TABLE))
The sum of the table depends on the values of X and Y. Hence, these operations must be ordered to get the right value for P.
Eventual Consistency
The most relaxed level of eventual consistency requires that all replicas eventually agree on the order of updates. However, there's no strict guarantee about when this convergence will occur.

How requests are sent in parallel and processed concurrently. Notice that the request ordering on the server is not strict.
Tradeoffs
Every engineering decision comes with tradeoffs, and eventual consistency is no exception. Your application's specific (non-functional) requirements drive your system's design tradeoffs.
These tradeoffs often revolve around three primary factors:
Latency vs. Consistency: Striking a balance between low latency and data consistency is a core design tradeoff. Stronger consistency guarantees typically come at the cost of increased latency due to the coordination and synchronization overhead.
Availability vs. Consistency: Imagine a video streaming service that stops displaying movies because your reaction didn't register on chat. When availability is paramount, we relax consistency.
Scalability vs. Consistency: Strong consistency can hinder horizontal scalability due to increased inter-node synchronization overheads. Eventual consistency allows for more scalability but requires handling potential data conflicts.
Conclusion
Understanding the nuances of eventual consistency and the associated tradeoffs helps engineers fulfill their roles. They design systems that align with application requirements and create robust architectures to withstand failures.
Understanding the underlying engineering helps you lead your team!
Unlock your potential as a distributed systems architect with us here: https://interviewready.io/learn/system-design-course/consistency-in-distributed-systems/ Happy engineering!