State Management & Consensus
Managing state in distributed systems requires explicit failure semantics. Stateless handlers are generally easier to replace and scale when their dependencies have headroom. Stateful services require deliberate placement, durability, consistency, and recovery choices; some designs use replication and consensus, but not all do.
# Stateless vs Stateful Services
Stateless Services
A stateless service does not depend on instance-local state retained from earlier requests. It may read or write shared external state, and any healthy instance can handle a request without session affinity.
Advantages:
- Easier to route and scale: requests can go to any healthy instance, subject to shared bottlenecks and available headroom
- Easier to replace: no instance-local session state must migrate, although external state still must persist
- Less per-instance reconciliation: there is no local session copy to conflict, but shared backends retain their own consistency requirements
Potential examples when implemented without instance-local session state: REST-conforming API handlers, web frontends using self-contained tokens, CDN request handlers, and proxy servers.
Stateful Services
A stateful service depends on state retained across operations, whether stored locally or on attached storage. Authoritative or correctness-critical state must be durable or recoverable across failures; disposable cached state can be rebuilt.
Challenges:
- Scaling: may require partitioning, rebalancing, read replicas, caching, or scaling up rather than adding interchangeable handlers
- Failure: requires a chosen durability and recovery model, such as replication, failover, reconstruction, or durable storage
- Consistency: replicas need an explicit consistency and conflict model; some systems use consensus
Examples: Databases, caches (if used as source of truth), session stores, distributed locks, leader election services.
# Quorum and Split-Brain Scenarios
When a network partition occurs, how do you ensure only one group continues operating? Quorum solves this. Split-brain happens when quorum fails.
Quorum Basics
A quorum is the minimum number of nodes required to make decisions. Typically: majority (N/2 + 1).
Why majority? Two groups can't both have majority. This prevents conflicting decisions.
Split-Brain Scenario
Split-brain occurs when a partition allows both sides to operate independently, creating conflicting state.
Prevention: Use quorum. With 3 nodes, only the side with 2+ nodes can elect a leader.
# Case Study: GitHub Cross-Region Failover (October 2018)
A 43-second interruption between GitHub's East Coast network hub and primary East Coast datacenter caused the East Orchestrator leader to deselect under Raft. West Coast and East Coast public-cloud Orchestrator nodes formed a quorum and began cross-region promotion. Brief unreplicated East writes followed by writes to the promoted West primaries produced divergent datasets; GitHub kept West canonical and rebuilt East.
The incident shows that a valid consensus quorum does not make every database promotion safe. Promotion boundaries must reflect application topology, old writers must be fenced, and the complete failover policy must be tested. See Notable Incidents & Lessons for the full chronology and recovery.
# Consensus Protocols (High-Level)
Consensus protocols help distributed systems agree on state despite failures and partitions.
Raft
Raft is a consensus algorithm designed to be understandable. Used in etcd, Consul, CockroachDB.
Key concepts:
- Leader election: Cluster elects one leader. Only leader accepts writes.
- Log replication: Leader appends entries to log, replicates to followers.
- Quorum: Write is committed when majority of nodes acknowledge.
- Leader failure: Followers detect timeout, start new election.
Paxos
Paxos predates Raft. Chubby uses a Paxos-based replicated state machine, and Cassandra uses Paxos for lightweight transactions.
Key idea: Basic Paxos uses prepare/promise and accept/accepted exchanges to choose a value; learners then learn the chosen value. Replicated-log variants repeat and optimize that process, and production implementations remain non-trivial.
When to Use Consensus
Consensus is expensive (latency, coordination overhead). Use when you need:
- Leader election (who's the primary?)
- Configuration management (distribute config changes consistently)
- Distributed locks (ensure only one process holds lock)
- Strongly consistent metadata (file locations, shard assignments)
Avoid for: High-throughput data plane operations. Use consensus for control plane, not data plane.
# State Replication Strategies
Synchronous Replication
Write completes only after replicas acknowledge. Guarantees consistency but adds latency.
Asynchronous Replication
With asynchronous replication, the primary can acknowledge after its own commit without waiting for a replica; replicas receive or apply the change later. This reduces commit-path latency, but failover to a lagging replica can lose acknowledged transactions.
Semi-Synchronous Replication
In MySQL 8.4 semi-synchronous replication, the source waits until the configured number of replicas (one by default) acknowledge receiving and logging the transaction, then returns. The acknowledgement does not mean the replica has applied or committed the transaction.
# Key Takeaways
- Stateless handlers are often easier to replace and scale, but shared backends and workload bottlenecks still set limits
- Stateful services require explicit placement, durability, consistency, and failure handling; replication or quorum may be appropriate for some designs
- Quorum (majority) prevents split-brain—two groups can't both have majority
- GitHub 2018: A valid Raft quorum initiated an unsafe cross-region promotion; quorum, topology-aware promotion, and writer fencing solve different parts of failover safety
- Consensus protocols (Raft, Paxos) enable agreement despite failures, but add latency
- Use consensus for control plane (leader election, config), not high-throughput data plane
- Replication trade-offs: sync (consistent, slow), async (lower commit latency, possible loss on lagging-replica failover), semi-sync (implementation-specific acknowledgement trade-off)