CAP Theorem: What It Actually Means for System Design
CAP theorem says you can only pick 2 of 3 properties. But what does that mean in practice? And which systems are CP vs AP vs CA?
CAP theorem (Brewer's theorem) states that a distributed data store can only provide two of the following three guarantees simultaneously:
- Consistency β every read receives the most recent write
- Availability β every request receives a response (not an error)
- Partition tolerance β the system continues operating despite network partitions
The critical insight
In a distributed system, network partitions will happen β nodes will lose communication. This means you're not really choosing between C, A, and P. You're choosing between C and A when a partition occurs.
CP Systems (Consistency over Availability)
When a partition occurs, the system refuses to respond rather than risk returning stale data.
Examples: HBase, Zookeeper, etcd, MongoDB (with strong read concern)
Use when: Financial transactions, distributed coordination, anything where stale data is wrong
AP Systems (Availability over Consistency)
When a partition occurs, nodes continue serving requests, but some nodes might return stale data.
Examples: Cassandra, DynamoDB, CouchDB, DNS
Use when: Shopping carts, user preferences, social feeds β stale data is acceptable
CA Systems (Consistency + Availability, no partitions)
These only work on a single node or in a trusted network without partitions. In practice, this means a traditional RDBMS on a single server.
Examples: PostgreSQL, MySQL (single-node)
Interview cheat sheet
| System | Type | Reason |
|---|---|---|
| Cassandra | AP | Eventual consistency by design |
| MongoDB | CP (configurable) | Default write concern gives consistency |
| DynamoDB | AP | Available and eventually consistent |
| PostgreSQL | CA | Single-node consistency, no partitions |
| Zookeeper | CP | Used for distributed coordination |
Beyond CAP: PACELC
CAP only considers partition scenarios. PACELC extends this: even without partitions, you trade latency vs consistency. This is often more relevant in practice.
Related Posts
How to Design a System for 1 Million Requests per Second
A step-by-step system design for 1M requests/sec β capacity math with Little's Law, edge caching, load balancing, multi-level caching, consistent-hash sharding, async queues, rate limiting, circuit breakers and autoscaling, with Java examples and the mistakes most designs make.
Kafka for Backend Engineers: Partitions, Ordering and Delivery Guarantees
How Kafka topics, partitions and consumer groups actually work, why ordering is only per partition, and what at-least-once and exactly-once really mean for your Spring Boot services.
Designing a Rate Limiter: Token Bucket, Sliding Window and Redis
The algorithms behind API rate limiting, their trade-offs, and how to build a distributed limiter with an atomic Redis Lua script β a classic system design interview question, solved end to end.
Microservices Patterns Every Senior Engineer Should Know
Saga, circuit breaker, API gateway, event sourcing β the design patterns that make microservices work at scale and that interviewers ask about.