CAP Theorem in System Design

By Oleksandr Andrushchenko — Published on — Modified on

The CAP theorem explains one of the most important trade-offs in distributed system design: when a network partition happens, a system must choose between consistency and availability. This article explains what CAP really means, why partition tolerance is unavoidable in distributed systems, and how to reason about CP and AP designs in practice.

Table of Contents

What Is CAP Theorem?

The CAP theorem is one of the foundational ideas in distributed systems. It describes the trade-off between three properties: consistency, availability, and partition tolerance.

The most practical version of the theorem is this:

In the presence of a network partition, a distributed system must choose between consistency and availability.

This does not mean that a system can never be consistent and available at the same time. During normal operation, many systems provide both. CAP becomes important when part of the system cannot communicate with another part.

The Core Idea

Imagine a database replicated across two regions. Under normal conditions, both regions communicate and stay synchronized.

Region A
   │
   ▼
Replication
   │
   ▼
Region B

Now imagine the network between the regions fails.

Region A     X     Region B
        network partition

If both regions continue accepting writes, they may diverge. If one region refuses requests to avoid divergence, the system sacrifices availability for consistency.

Why Partitions Matter

In distributed systems, network partitions are not theoretical. Networks fail, packets are delayed, nodes restart, regions become isolated, and cloud infrastructure has incidents.

Because partitions can happen, distributed systems usually cannot ignore partition tolerance. The real design question becomes: when communication fails, should the system prefer correctness or responsiveness?

The Three CAP Properties

Consistency

Consistency means every read receives the most recent write or an error. In other words, users should not read stale data after a successful write.

For example, in a banking system, if a transfer reduces an account balance from $500 to $400, future reads should not show the old $500 balance.

Availability

Availability means every request receives a response, even if the response may not contain the latest data.

For example, a social media feed may continue showing posts during a partial outage, even if some likes, comments, or counters are temporarily stale.

Partition Tolerance

Partition tolerance means the system continues operating despite network failures between nodes.

In real distributed systems, partition tolerance is usually mandatory because network failures are unavoidable. This is why practical CAP discussions often focus on CP versus AP systems.

CAP Combinations

Combination What It Means Common Examples
CA Consistent and available, but does not tolerate partitions Single-node relational database
CP Consistent and partition tolerant, but may reject requests during partitions etcd, ZooKeeper, HBase
AP Available and partition tolerant, but may return stale or conflicting data temporarily Cassandra, DynamoDB-style systems, CouchDB, Riak

CA Systems

CA systems provide consistency and availability when there are no partitions. A single-node relational database is often a simple example because there is no network split between replicas.

However, once a system becomes distributed across nodes or regions, partitions become possible. At that point, pure CA is no longer realistic.

CP Systems

CP systems prefer correctness during partitions. If the system cannot safely confirm the latest state, it may reject reads or writes rather than return potentially incorrect data.

This is common for coordination systems, leader election, distributed locks, and configuration stores. Returning stale coordination data can be more dangerous than temporarily refusing requests.

AP Systems

AP systems prefer responsiveness during partitions. They continue accepting requests even if replicas may temporarily disagree.

This works well for workloads where temporary inconsistency is acceptable, such as social feeds, likes, analytics counters, shopping carts, or cached data.

CAP in Practice

Normal Operation

During normal operation, many distributed systems appear both consistent and available. Replicas communicate, writes propagate, and reads return expected values.

This is why CAP should not be interpreted as “you can only ever have two of three.” The real trade-off appears when the network breaks.

During a Network Partition

When a partition happens, the system has two basic choices.

  • Prefer consistency: reject or block some requests to avoid returning stale or conflicting data.
  • Prefer availability: continue serving requests and resolve conflicts later.

For example, a payment ledger should usually prefer consistency. A recommendation feed can usually prefer availability.

Real-World Examples

CP Example

A CP system such as etcd or ZooKeeper may reject writes during a partition if it cannot reach a quorum. This protects correctness.

def write_consistent(cluster, key, value):
    quorum = len(cluster) // 2 + 1
    acknowledgements = 0

    for node in cluster:
        if node.reachable():
            node.store[key] = value
            acknowledgements += 1

    if acknowledgements >= quorum:
        return "Write committed"

    raise Exception("Not enough nodes for consistency")

This design is useful when stale or conflicting data would be dangerous. Configuration systems, leader election, and distributed locks often need this behavior.

AP Example

An AP system may accept writes locally even when other replicas are unreachable. The system stays available, and replicas converge later.

def write_available(node, key, value):
    node.local_store[key] = value
    node.replicate_async(key, value)

    return "Write accepted"

This design is useful when responsiveness matters more than immediate global agreement. For example, a like counter can accept updates during a partition and reconcile counts later.

Beyond CAP: PACELC

CAP focuses on what happens during network partitions. PACELC extends this idea by pointing out that even when there is no partition, systems still trade latency against consistency.

If a Partition occurs, choose between Availability and Consistency. Else, choose between Latency and Consistency.

This means distributed systems constantly make trade-offs, not only during failures. A globally distributed database can wait for cross-region confirmation to improve consistency, or it can respond faster with weaker guarantees.

Choosing the Right Balance

The right choice depends on the business requirement.

Use Case Preferred Behavior Reason
Bank account balance CP Incorrect balances are unacceptable
Configuration store CP Stale configuration can break systems
Shopping cart Often AP Temporary inconsistency can be reconciled
Social feed AP Availability and responsiveness are more important than perfect freshness
Analytics dashboard AP or eventual consistency Delayed data is usually acceptable

A good system may use different consistency choices for different parts. Payments may be strongly consistent, while notifications, analytics, and recommendations may be eventually consistent.

Guidelines for System Designers

  • Assume network partitions can happen.
  • Identify which operations require correctness and which can tolerate stale data.
  • Use CP behavior for critical invariants such as money, permissions, and configuration.
  • Use AP behavior for feeds, counters, analytics, recommendations, and non-critical user experience paths.
  • Document consistency behavior clearly for API consumers.
  • Use monitoring and failure testing to understand how the system behaves during partitions.

Summary

The CAP theorem does not tell engineers exactly what database to choose. It explains the unavoidable trade-off that appears when distributed systems experience network partitions.

In practice, partition tolerance is usually required, so architects often choose between CP and AP behavior depending on the use case. CP systems protect correctness by rejecting or blocking some requests during failures. AP systems preserve availability by accepting temporary inconsistency and reconciling later.

The most important lesson is simple: CAP is not about choosing a label for the whole system. It is about deciding which parts of the system must remain correct and which parts can remain available during failure.

Comments (0)