We all know the CAP theorem, but there is another trio that competes in streaming and real-time data systems, and it does not get nearly as much attention. The triad is
- consistency (everyone sees the same value)
- availability (system always responds to requests)
- freshness (how up-to-date the data is)
These three goals pull against each other in various ways.
If you prioritize consistency and freshness, you need tight coordination across nodes. That coordination introduces latency and can cause the system to stall when a node is slow or unreachable, hurting availability.
If you prioritize availability and freshness, you let data flow fast and keep every node accepting writes. But with no coordination, different nodes can briefly diverge, breaking consistency guarantees. This is how Kafka behaves under high throughput with acks=1 (kind of, nuances exist).
If you prioritize consistency and availability, you typically introduce buffering or batching to allow coordination without blocking. That buffering is what kills freshness and pushes your end-to-end latency from seconds into minutes.
Popular real-time systems like Apache Flink, Kafka Streams, and Spark Streaming all make different bets here.
As always, there is no free lunch.
So, it is super important to understand which two you are optimizing for and clarify every architecture decision downstream: replication factor, commit strategy, windowing approach, and how you handle late-arriving data, and so much more.
Pick your two. Design around the one you are giving up.