Your technical library
System Design
11 modules · 76 topics
About this book
System Design
This course teaches how the systems behind a modern product actually work — databases, caches, replicas, queues, consensus services — from the hardware facts up, so that you can design one, debug one at 3 a.m., and argue a trade-off in a design review with numbers rather than adjectives. It is written for a working software engineer who ships code every day and wants the theory underneath it: no prior distributed-systems background is assumed, and nothing is used before the topic that teaches it.
It builds on the DBMS course, which teaches everything a single database machine does — storage engines, indexes, transactions, isolation, MVCC and the write-ahead log — and links back to it rather than repeating it.
It is built as one chain of problems. Foundations gives you the laws that decide whether a system is fast — latency, queueing, tails, scaling. Data models and encoding shows how data is shaped and survives a deploy. The serving path puts load balancers, caches and rate limits in front of it all.
Then the data leaves one machine. Replication keeps copies — and meets failover, lag, conflicting writes and why no clock can order them. Consistency models then name precisely what a reader may see once there is more than one copy. Partitioning splits data that no longer fits on one machine and places each key, leaderless replication then removes the leader entirely. Coordination starts from a transaction that spans machines — two-phase commit, sagas and the outbox — and answers the question all of those leave open — how machines decide one thing, once, for certain — with leases, consensus and Raft. Queues, batch and streams hand work off to be done later and keep derived copies correct.
The last two modules turn the understanding into practice: the interview method is a disciplined way to work a design problem, and the design catalogue works classic systems — a rate limiter, a key-value store, a chat service, a news feed — using everything before. Along the way each topic says what it inherits, what it leaves open, who invented the idea and when, and how it shows up in decisions engineers make.
76 topics across 11 modules, in dependency order.
Work a module top to bottom. Topics are ordered so each one only needs what came before it: every topic states what it assumes, and nothing is used before the topic that derives it.
Answer the “Check yourself” questions before opening them. Recalling an answer is what makes it stick; re-reading is not.
Mark a topic complete when you can explain it without the page. The public course shares progress through D1, so your completion state is available across devices without a login.
Topics still being written are labelled. They are excluded from progress, so the count reflects what is actually finished.
Read at your own pace. Each topic is one continuous page; mark it done as you finish.
Start with 01.1 · Latency numbers & the memory hierarchyReview what you have finished↷ 0 skipped topics- 01.1Latency numbers & the memory hierarchy
- 01.2Throughput, latency & Little's Law
- 01.3Random variables in a system: counts, durations & the tail integral
- 01.4Poisson arrivals & exponential service: the M/M assumptions
- 01.5Queueing: why latency explodes near saturation
- 01.6Tail latency & percentiles
- 01.7Fan-out amplification & hedged requests
- 01.8Vertical vs horizontal scaling: Amdahl & the USL
- 01.9Back-of-envelope estimation
- 01.10Idempotency & retry safety
- 04.1Partial failure & the limits of a timeout
- 04.2Why replicate: leader–follower
- 04.3Sync, async & semi-sync
- 04.4Replication lag & read-your-writes
- 04.5Failover, split-brain & fencing
- 04.6Multi-leader replication
- 04.7Physical clocks, NTP & why wall time lies
- 04.8Logical clocks: happens-before & Lamport timestamps
- 04.9Vector clocks & version vectors: detecting concurrency
- 04.10Conflict resolution: LWW and CRDTs
01.2Throughput, latency & Little's Law
01.3Random variables in a system: counts, durations & the tail integral
01.4Poisson arrivals & exponential service: the M/M assumptions
01.5Queueing: why latency explodes near saturation
01.6Tail latency & percentiles
01.7Fan-out amplification & hedged requests
01.8Vertical vs horizontal scaling: Amdahl & the USL
01.9Back-of-envelope estimation
01.10Idempotency & retry safety
02.1Relational, document & graph models
02.2Schema-on-write vs schema-on-read
02.3Encoding formats & schema evolution
03.1Load balancing
03.2Caching: where and why
03.3Write policies: through, back, around
03.4Staleness: TTL, stampede & eviction
03.5Rate limiting algorithms
03.6CDN, API gateway & the front door
04.1Partial failure & the limits of a timeout
04.2Why replicate: leader–follower
04.3Sync, async & semi-sync
04.4Replication lag & read-your-writes
04.5Failover, split-brain & fencing
04.6Multi-leader replication
04.7Physical clocks, NTP & why wall time lies
04.8Logical clocks: happens-before & Lamport timestamps
04.9Vector clocks & version vectors: detecting concurrency
04.10Conflict resolution: LWW and CRDTs
05.1What "consistency" means: the model hierarchy
05.2Linearizability
05.3CAP: the theorem and its proof
05.4PACELC: the latency side
05.5Eventual consistency & session guarantees
06.1Sharding & the partition key
06.2Range vs hash partitioning
06.3Consistent hashing
06.4Hot partitions & skew
06.5Secondary indexes across partitions
07.1Leaderless replication & the quorum condition
07.2Read repair
07.3Merkle trees & anti-entropy
07.4Gossip & failure detection
07.5Sloppy quorums & hinted handoff
08.1Distributed transactions: 2PC, sagas & outbox
08.2Leases & fencing tokens
08.3Consensus: the problem, FLP, Paxos & quorum intersection
08.4Raft
08.5Distributed locks & leader election
09.1Message queues: decoupling in time
09.2Delivery guarantees & queue operations
09.3Batch processing & distributed dataflow
09.4MapReduce: map, shuffle, reduce
09.5Streams, partitioned logs & offsets
09.6Event time, watermarks & windowing
09.7CDC & event sourcing
09.8Derived data & correctness
10.1The framework
10.2Requirements
10.3Estimation
10.4API design
10.5High-level design
10.6Deep dives
10.7Bottlenecks & trade-offs
11.1Rate limiter
11.2Key-value store
11.3Unique ID generator
11.4Web crawler
11.5Notification system
11.6News feed
11.7Chat system
11.8Search autocomplete
11.9Video platform
11.10Cloud file sync
11.11Cross-cutting production decisions
11.12Observability & operability
Skipped topics
Moved past without finishing. A skipped topic still closes its module, and Continue goes on without it — open one to read it or mark it understood.
Glossary
Important system-design terms, with definitions and links back to the lesson where each idea is used.
Little's Law
L = λW: concurrency equals throughput times latency.
More detail
Holds for any arrival pattern and service distribution in a stable system. Forwards it turns a throughput target into a concurrency requirement (2 000 QPS at 50 ms needs 100 in-flight slots); backwards it distinguishes 'requests are queueing' from 'concurrency is capped', which look identical on a latency graph.
Utilisation (ρ)
The fraction of time a server is busy: ρ = λ/μ.
More detail
The variable that governs queueing. M/M/1 time in system is W = E[S]/(1−ρ), so latency rises hyperbolically rather than linearly — the same 5% of extra traffic costs 3 ms at 50% utilisation and 100 ms at 90%. Provision against utilisation, never against throughput.
Queueing Delay
Waiting that forms below capacity because arrivals are random.
More detail
Requests do not arrive evenly spaced, so they cluster and queue even when a server is idle on average. This is why latency degrades long before 100% utilisation and why systems fail suddenly rather than gradually.
Tail Latency
The slow end of the latency distribution, reported as a high percentile.
More detail
Latency has a floor and no ceiling, so the mean is dragged by a few slow requests and describes an experience nobody had. The tail disproportionately affects the heaviest users, since more data means slower requests.
Percentile
A value below which a stated fraction of observations fall.
More detail
p99 = 250 ms means 99% of requests finished within 250 ms. Percentiles do not average across servers and do not add along a call chain — both are common monitoring errors. A usable p_q needs roughly 10/(1−q) samples.
Hedged Request
A duplicate request sent after the first misses a deadline.
More detail
Sent only when the first attempt exceeds, say, the p95, so extra load is ~5% while the tail collapses — the request is only still slow if the duplicate is slow too. A tied request sends both immediately and cancels the loser.
Fan-out Amplification
Rare slowness becoming common when a request waits on many parallel calls.
More detail
P(slow) = 1 − (1−p_slow)^n. With each of 100 backends slow just 1% of the time, the request is slow 63% of the time — so the required component percentile is set by the fan-out, not by taste.
Amdahl's Law
Speedup is capped by the fraction of work that cannot be parallelised.
More detail
G(N) = 1/((1−p_parallel) + p_parallel/N), with a ceiling of 1/(1−p_parallel). At 95% parallel, 100 machines give 17× and no number ever exceeds 20×. The serial fraction is usually a shared resource — one database, one lock, one coordinator.
Universal Scalability Law
Amdahl plus a coherency term, so throughput can decline with more nodes.
More detail
C(N) = N / (1 + σ(N−1) + κN(N−1)). The κN² term makes the curve peak at N* = √((1−σ)/κ) and fall beyond it, which is why adding nodes to a struggling cluster can reduce throughput. The fix is less coordination, not more hardware.
Skip List
A probabilistically balanced ordered structure, common as a memtable.
More detail
Gives O(log n) expected search and insert like a balanced tree, but an insert splices a node into a few linked lists rather than rotating subtrees — which makes lock-free and fine-grained-locking implementations practical. That matters because the memtable is the hottest shared structure in an LSM engine.
Bitcask
An append-only log plus an in-memory hash index.
More detail
The simplest workable storage engine: one hash lookup plus one seek per read. Bounded by distinct key count rather than data size (~68 bytes per key), and structurally incapable of range queries — which is what motivates sorting the data instead.
Covering Index
An index containing every column a query needs.
More detail
The query is answered from the index alone, removing one random read per result row. The trade is a wider index: more pages, fewer entries per page, and more write amplification — read amplification traded for write amplification at the query level.
Clustered Index
An index whose leaf pages hold the full rows, stored in key order.
More detail
The table's data lives inside the index, so rows with nearby keys sit on the same or adjacent pages. Rows can have only one physical order, so a table has at most one clustered index. Primary-key reads and ranges are cheap, but the key choice becomes a physical-layout decision. InnoDB tables are always clustered, normally on the primary key.
Non-Clustered Index
An index stored apart from the rows, pointing to them via a row locator.
More detail
Leaf entries hold the indexed values plus a row locator: a physical row address on a heap, or the clustered key on a clustered table. Reaching the full row takes a second lookup unless the index covers the query. A table can have many. SQL Server uses the term for every secondary index.
Heap Table
A table whose rows are stored in no particular order.
More detail
A row is placed wherever there is free space, and every index on the table is secondary, pointing at the row's physical location. PostgreSQL tables are heaps; its CLUSTER command reorders a table once but does not maintain that order for later writes.
RUM Conjecture
Optimising any two of read, update and memory costs you the third.
More detail
The organising constraint of storage engine design. Tiering optimises update cost and pays in read amplification; leveling optimises read and space and pays in write amplification; Bloom filters buy read performance with memory.
PACELC
If Partition then A or C; Else L or C.
More detail
Extends CAP with the normal case CAP ignores. The E half dominates because partitions are rare while replication latency is charged on every request — ~150 ms against ~1 ms across continents. Real systems expose the choice per query rather than per system.
Session Guarantee
A consistency guarantee scoped to one client's own activity.
More detail
Read-your-writes, monotonic reads, monotonic writes and writes-follow-reads. Each rules out an anomaly users actually notice, and each is enforced by routing or a carried version token rather than by coordination — so latency and availability are preserved.
Read Repair
Writing the newest value back to stale replicas during a quorum read.
More detail
Nearly free, because the read already holds several versions and knows which replicas are behind. It only ever fixes keys that are read, so the cold majority of the keyspace stays stale — which is why background anti-entropy is required as well.
Phi Accrual Failure Detector
A detector reporting a continuous suspicion level rather than up/down.
More detail
φ = −log₁₀ P(a heartbeat is later than the current gap), computed from the observed arrival distribution. Each consumer picks its own threshold according to what a mistake costs it, and the detector adapts to a slow network without a hand-tuned constant.
CRDT
A data type whose merge is commutative, associative and idempotent.
More detail
Those three properties make replicas converge regardless of the order, grouping or repetition of updates — exactly what an unreliable network does. A G-counter merges by elementwise max; an OR-set tags additions so a concurrent add survives a remove.
Happens-Before
The partial order capturing which events could have influenced which.
More detail
a → b if they are on the same node in that order, or a is a send and b its receipt, or transitively. Events with neither direction are concurrent — neither could have known of the other, which is the property conflict detection needs and a timestamp destroys.
Zipf Distribution
A power law where the r-th most popular item gets traffic ∝ 1/r^s.
More detail
The shape real access patterns take. With s = 1 over 10⁶ items the top item takes ~7% of all traffic and the top ten ~20%, so skew is the expected case rather than an anomaly — and any design assuming uniform access is assuming something that has never been true.
Salting
Splitting one hot key into k physical keys to spread its load.
More detail
Writes are distributed across k partitions; reads must query all k and merge. It trades a write hotspot for read fan-out, so it is applied selectively to identified hot keys rather than globally.
MVCC
Keeping multiple versions of a row so readers never block writers.
More detail
Each version is tagged with the transactions that created and superseded it, and a snapshot plus one visibility predicate yields snapshot isolation. It is the append-only insight applied to concurrency — and it owes the same debt, needing vacuum to reclaim versions that no open transaction can see.
Two-Phase Locking
Acquire locks in a growing phase, release in a shrinking phase, never mix.
More detail
The pessimistic route to serializability. The discipline guarantees an acyclic precedence graph, since a cycle would require acquiring after releasing. Costs waiting, unpredictable latency and deadlocks that the application must retry.
Serializable Snapshot Isolation
Optimistic serializability: run at snapshot isolation and abort cycles at commit.
More detail
Uses the result that every cycle under snapshot isolation contains two consecutive rw-dependencies, so the engine tracks a constant amount of state per transaction rather than building a global graph. Readers never block writers; the cost is an abort rate that rises with contention.
Precedence Graph
A graph of the orderings a schedule requires between transactions.
More detail
An edge T1 → T2 whenever T1 must precede T2. A schedule is serializable exactly when the graph is acyclic — a cycle means no serial order exists. Every concurrency mechanism either prevents or detects such a cycle.
FLP Impossibility
No deterministic algorithm solves consensus asynchronously with one possible crash.
More detail
Because a crashed node and an arbitrarily slow one are indistinguishable. Real systems escape by keeping safety unconditional and sacrificing guaranteed termination — an unavailable consensus system is an inconvenience, an inconsistent one has two leaders.
Quorum Intersection
Any two majorities share a node, which is where consensus safety comes from.
More detail
Two sets each larger than N/2 cannot be disjoint, so a new decision always consults a node from the previous one. Hence ⌊N/2⌋+1 and N = 2f+1 to tolerate f failures — and why even-sized clusters add cost without adding tolerance.
Raft
A consensus algorithm designed to be understandable.
More detail
Decomposes into leader election, log replication and safety. Terms act as a logical clock and a fencing token; randomised election timeouts avoid split votes; and the election restriction plus quorum intersection guarantee a new leader holds every committed entry.
Lamport Timestamp
A single counter that respects causality but cannot detect concurrency.
More detail
Increment on every event; on receive take the max then increment. a → b implies C(a) < C(b), but not the converse — a smaller counter may be an unrelated event. With a node-id tie-break it gives a total order every node computes identically.
Hybrid Logical Clock
A timestamp combining physical time with a logical counter.
More detail
Stays within a bounded distance of wall-clock time so it is human-meaningful, while still guaranteeing that causally ordered events compare correctly. Used by CockroachDB and MongoDB where causally sound timestamps must also look like times.
TrueTime
A clock API returning an interval guaranteed to contain the true time.
More detail
Keeps the uncertainty NTP discards. Disjoint intervals order definitively; overlapping ones are explicitly unknown. Spanner waits out the interval before releasing locks, buying strong consistency by measuring uncertainty and paying it as latency.
Watermark
An explicit bet that all events before a given event time have arrived.
More detail
Completeness is unknowable on a stream, so a window must be closed on an assumption. Allowed lateness trades latency against accuracy — there is no correct value, only a stated one, and late data is then dropped, used to update the result, or sent to a side output.
Combiner
Map-side pre-aggregation that shrinks the shuffle.
More detail
Collapses many records into one per mapper per key before they cross the network — the highest-value optimisation in a distributed job. Requires the reduce function to be associative and commutative, the same algebraic condition a CRDT merge needs.
Crypto-shredding
Deleting data by destroying its encryption key.
More detail
How an append-only event log satisfies a right to erasure: encrypt personal data per subject and delete the key, rendering the events unreadable without mutating the log. It must be designed in from the start, as retrofitting is close to impossible.
Cardinality
The number of distinct series a metric produces.
More detail
The product of its label domains, and the cost driver for a metrics system. Endpoint × status × region × instance is manageable; adding a user id multiplies it by the user count and takes the metrics system down. High-cardinality identifiers belong in traces and logs.
Golden Signals
Latency, traffic, errors and saturation — the four symptom metrics to alert on.
More detail
User-facing by construction, which is why they wear well. Alerting on causes such as CPU produces pages for conditions nobody experiences, and every alert that fires without needing action trains responders to ignore alerts.
Error Budget
The allowed unreliability implied by an SLO.
More detail
Alerting on burn rate — how fast the budget is being consumed — rather than on instantaneous thresholds. A brief blip consuming 1% of a monthly budget needs no one awake; a slow degradation that will exhaust it in a day does, and a threshold alert catches the wrong one.
Power of Two Choices
Sample two servers at random and send to the less loaded.
More detail
Improves maximum load from Θ(log n / log log n) to Θ(log log n) — an exponential gain from one extra sample — and needs no shared state, so parallel balancers cannot all converge on the same 'least loaded' server and stampede it.
W-TinyLFU
An eviction policy with an admission filter.
More detail
Admits a new item only if a compact frequency sketch suggests it is more valuable than the entry it would displace. This defeats LRU's central weakness — a single batch scan evicting the entire hot set — since a once-seen item loses that comparison and never enters.
QPS
Queries per second — the unit system design estimation is done in.
More detail
Queries per second — the standard unit for sizing a system, used instead of "users" because one user generates many operations. Always derive QPS from a write-volume input and a read:write ratio (see 1.7).
Latency
The time for one operation to complete.
More detail
The time a single operation takes from start to finish. Decoupled from throughput via parallelism — see 1.2. A redirect's latency budget is "tens of milliseconds" because it sits in front of a page load.
Throughput
Operations completed per unit time.
More detail
The rate of operations a system completes, independent of any single operation's latency. Raised by adding parallel workers/servers/partitions.
CAP Theorem
During a partition, choose Consistency or Availability — not both.
More detail
Formalized by Eric Brewer (2000), proven by Gilbert & Lynch (2002). Consistency = linearizability (every read sees the latest write). Availability = every request to a live node gets a response. Partition tolerance is not optional — the real choice is C vs A, and only during an active partition.
Linearizability
Every read sees the latest write, as if there were only one copy of the data.
More detail
The strongest common consistency model: the system behaves as though there's a single, up-to-date copy of the data and every operation appears to take effect instantaneously at some point between its start and end. This is what "Consistency" means in the CAP theorem. It's expensive to guarantee across a network, which is exactly why weaker models (eventual, read-your-writes, monotonic reads, causal) exist as cheaper compromises.
Read-Your-Writes Consistency
A user always sees their own writes, even if others see stale data.
More detail
A consistency guarantee weaker than linearizability but stronger than plain eventual consistency: after a user writes a value, that same user's subsequent reads are guaranteed to reflect it, typically implemented by routing that user's reads to the primary (or the replica that served their write) for a short window.
Monotonic Reads
A user never sees data go "backwards" in time.
More detail
A consistency guarantee ensuring that once a user has seen a value, they never see an older value on a later read — even if that later read happens to hit a more-lagged replica. Without it, refreshing a page could show a comment disappearing and reappearing.
Causal Consistency
Causally related writes are seen in the same order by everyone.
More detail
A consistency guarantee that preserves cause-and-effect ordering (e.g. a reply is never seen before the comment it replies to) without requiring the full ordering guarantees of linearizability. Sits between eventual consistency and linearizability on the consistency spectrum.
CP System
Rejects writes/reads during a partition to stay consistent.
More detail
A system that chooses Consistency over Availability during a network partition — it will refuse requests rather than risk serving stale or conflicting data. Examples: ZooKeeper, etcd, HBase, MongoDB in its default configuration.
AP System
Keeps serving requests during a partition, risking staleness.
More detail
A system that chooses Availability over Consistency during a network partition — it keeps accepting reads/writes even if replicas may disagree temporarily. Examples: Cassandra, DynamoDB, Riak, CouchDB.
Eventual Consistency
Replicas converge to the same value once writes stop; reads may be stale until then.
More detail
The consistency model that AP systems provide: given no new writes, all replicas eventually agree. There's no bound on how long convergence takes. Stronger variants: read-your-writes, monotonic reads, causal consistency.
Idempotency
Performing an operation N times leaves the same end state as performing it once.
More detail
The precise definition (not "doing it again does nothing"). GET/PUT/DELETE are naturally idempotent; POST is not. Fixed for non-idempotent operations via an idempotency key + stored result. See the crash-in-the-gap problem for why no implementation is perfectly safe.
Idempotency Key
A client-supplied key used to detect and dedupe retried requests.
More detail
A unique key (often client-generated, e.g. a UUID) sent with a request so the server can recognize a retry and return the previously stored result instead of redoing the side effect. Popularized by the Stripe API for payments.
Vertical Scaling
Scaling by using a bigger machine.
More detail
Adding more CPU/RAM to a single machine. Operationally simple — no distributed-systems problems — but hits a hard, increasingly expensive ceiling.
Horizontal Scaling
Scaling by using more machines.
More detail
Adding more machines rather than upgrading one. No hard ceiling, but introduces every distributed-systems tax: coordination, partial failure, consistency.
Functional Requirement
A declarative statement of what the system does.
More detail
States a capability the system provides ("a user can shorten a URL"). Declarative, not interrogative — a clarifying question ("do links expire?") is not itself a requirement.
Non-Functional Requirement
A quality constraint: availability, latency, scalability, consistency, durability.
More detail
Describes the qualities the system must have rather than what it does. Often drives the architecture more than functional requirements — two systems with identical features diverge entirely based on their non-functional targets.
Round Robin
A load-balancing algorithm that cycles through servers in fixed order.
More detail
Sends the 1st request to server A, 2nd to B, 3rd to C, then back to A — blind to how busy each server actually is. Simple and fair when requests are roughly equal cost; poor when request cost varies a lot, since a server can get piled up with expensive requests purely by bad luck of the rotation.
Least Connections
A load-balancing algorithm that routes to the server with the fewest active connections.
More detail
Tracks in-flight requests per server and routes each new request to whichever server currently has the fewest, which adapts naturally to uneven request costs — unlike round robin, a server bogged down with slow requests simply stops receiving new ones until it catches up.
Load Balancer
Distributes incoming requests across a pool of servers.
More detail
Sits between clients and app servers, using an algorithm (round robin, least connections) to pick a target, and health checks to eject unhealthy servers. Examples: NGINX, HAProxy, Envoy, AWS ALB/NLB.
Layer 4 Load Balancing
Routes on IP/port — fast, opaque to content.
More detail
Operates at the transport layer, routing based on IP address and port without inspecting the payload. Faster than Layer 7 but can't route on path or header.
Layer 7 Load Balancing
Routes on HTTP content — smarter, slower.
More detail
Operates at the application layer, parsing HTTP to route by path, header, or cookie. More flexible than Layer 4 but adds parsing overhead.
Sticky Session
Pins a user to one server for their session.
More detail
A load-balancing mode that routes a given user's requests to the same server every time, usually via a cookie. Fragile: breaks if that server dies, and creates uneven load across the fleet.
Stateless Server
A server holding no per-user session data locally.
More detail
A server design where session state lives externally (e.g. in Redis) instead of in the server's own memory, so any server in the pool can handle any request — the fix for the sticky-session trap.
Cache
A copy of hot data kept closer/faster than the source of truth.
More detail
Trades storage cost and staleness risk for speed. Exists at multiple layers: browser, CDN, application (Redis/Memcached), and database buffer pool.
Cache-Aside
App checks cache first; on miss, reads the DB and populates the cache.
More detail
Also called lazy loading. The most common read pattern because it survives cache death — the cache sits outside the critical write path.
Write-Through Cache
Writes to cache and DB together.
More detail
Keeps the cache always fresh at the cost of slower writes, since every write pays the latency of both stores.
Write-Back Cache
Writes to cache immediately, flushes to DB later.
More detail
Also called write-behind. Fast writes, but risks data loss if the process crashes before the deferred flush completes.
Cache Stampede
A hot key expires and thousands of requests hit the DB at once.
More detail
Also called thundering herd. Fixed with a repopulation lock, early refresh before expiry, or TTL jitter so keys don't all expire together.
TTL (Time To Live)
How long a cache entry lives before automatic expiry.
More detail
The safety net for staleness — even if invalidation is missed on a write, the entry self-heals once its TTL elapses.
Buffer Pool / Page Cache
A database's own in-memory cache of recently used disk pages.
More detail
Every relational database keeps a region of RAM (Postgres's shared_buffers, MySQL's InnoDB buffer pool) holding recently accessed disk pages, so repeat reads of hot rows avoid disk I/O entirely. It's the reason RDS memory-optimized (R-family) instances are the default choice for databases: a bigger buffer pool means a bigger fraction of the working set never touches disk.
Pareto Principle (80/20 Rule)
A small fraction of keys account for most of the traffic.
More detail
The empirical observation that access patterns are rarely uniform — roughly 20% of keys (the "hot set") tend to account for roughly 80% of requests. This is what makes caching a cheap, high-leverage win: a cache sized for only the hot set, not the whole dataset, still absorbs most traffic. It's why the URL shortener's ~1-2GB cache handles ~4,000 QPS against an 18TB dataset.
LRU / LFU Eviction
Policies for what a full cache drops to make room.
More detail
LRU (least recently used) evicts the entry untouched for longest — the default, works well since access is temporally clustered. LFU (least frequently used) evicts by access count — better when popularity is stable over time.
Replication
Keeping copies of data on multiple machines for read scaling and fault tolerance.
More detail
Solves availability and read throughput, not write throughput or storage (that's sharding). Dominant topology: leader-follower, where a single leader establishes write order and followers replay its log.
Leader-Follower Replication
All writes go through one leader; followers copy its log.
More detail
Also called primary-replica. The leader gives writes an authoritative order; followers replay that order to converge. Examples: Postgres streaming replication, MySQL binlog replication, MongoDB replica sets.
Synchronous Replication
The leader waits for a follower ack before confirming a write.
More detail
Durable (a follower is guaranteed to have the data before the write is acked) but slower, since every write pays the round-trip to the follower.
Asynchronous Replication
The leader does not wait for follower acks.
More detail
Fast, but introduces replication lag and can lose acked writes if the leader crashes before the follower catches up.
Semi-Synchronous Replication
The leader waits for acknowledgment from just one follower before confirming a write.
More detail
A middle ground between full synchronous (wait for all followers) and asynchronous (wait for none) replication: the write is guaranteed to survive on at least one other node before being acked, without paying the latency cost of waiting on every replica.
Write-Ahead Log (WAL)
An append-only log of changes, written before they're applied to the actual data.
More detail
The mechanism underlying most durable databases and replication systems: every change is first appended to a sequential log on durable storage, and only then applied to the in-memory/on-disk data structures. Because the log is the single source of truth for "what happened and in what order," followers can replay it to reconstruct the same state — it's usually the actual unit of replication, not the final table data.
Replication Lag
The delay between a write landing on the leader and appearing on a follower.
More detail
Causes "read-your-writes" bugs — a user writes, then immediately reads a stale replica and doesn't see their own change. Route to the primary for the simple fix, or carry a commit position/session token and choose a replica that has reached it.
Split-Brain
Two nodes both believe they are the leader and accept conflicting writes.
More detail
A failover hazard. Majority agreement and a new epoch or term choose the current owner, while fencing at the protected resource rejects delayed work from an old leader.
Quorum (W + R > N)
Leaderless replication rule ensuring read and write sets overlap under assumptions.
More detail
In leaderless replication, requiring the write set (W_write) plus read set (R_read) to exceed the total replica count (N_replicas) makes the sets overlap under the model. It does not alone guarantee linearizability: concurrent writes, sloppy quorums, conflict resolution, and repair behavior still matter.
Consensus Algorithm
Protocol (Raft, Paxos) for nodes to agree on values, leaders, or log entries.
More detail
Consensus establishes an irrevocable decision under an explicit failure model. Terms or epochs reject stale leaders, and a majority makes progress possible when enough nodes can communicate. Consensus chooses authority; fencing prevents delayed old authority from acting.
Multi-Leader Replication
More than one node accepts writes, later reconciled.
More detail
Useful for multi-region writes but introduces conflict resolution when two leaders accept conflicting writes to the same record.
Leaderless Replication
Any replica can accept a write; consistency comes from quorum reads/writes.
More detail
No single leader orders writes. Correctness relies on the W_write + R_read > N_replicas quorum rule. Used by Cassandra and DynamoDB.
Sharding (Partitioning)
Splitting data across machines so each holds only a slice.
More detail
Solves write throughput and storage limits, which replication does not (replication only scales reads). Real systems layer both: each shard is itself a replicated cluster.
Partition Key (Shard Key)
The field used to decide which shard a row lives on.
More detail
The hardest, most-tested sharding decision: it must distribute load evenly AND align with the dominant query pattern, or queries without it become expensive scatter-gathers.
Hot Partition
A shard receiving disproportionate load.
More detail
Caused by a partition key that concentrates traffic — e.g. shard-by-userID plus a celebrity user, or shard-by-timestamp with everyone writing to "now."
Scatter-Gather
A sharded query that must fan out to every shard.
More detail
Happens when a query doesn't include the partition key. Expensive — avoided by choosing a partition key that matches the dominant query pattern.
Range Partitioning
Shards data by contiguous key ranges.
More detail
Good for range queries (e.g. "all orders from March") but hotspot-prone when writes cluster at one end of the range (e.g. always-increasing timestamps).
Hash Partitioning
Shards data by hash(key) — even spread, but reshuffles on resize.
More detail
Distributes load evenly but naive hash(key) % N reshuffles nearly every key when N changes, since N is the divisor. See Consistent Hashing for the fix.
Consistent Hashing
Ring-based key/node assignment so changing node count remaps only ~1/N keys.
More detail
Introduced by Karger et al. (1997). Places nodes and keys on a ring; each key belongs to the next node clockwise. Because node positions are independent of N, adding/removing a node disturbs only one arc of the ring. Used by Cassandra, DynamoDB, and memcached client-side sharding.
Virtual Nodes
Many ring points per physical node — gives even distribution and smoother rebalancing.
More detail
Plain consistent hashing does not distribute evenly on its own; virtual nodes fix this by giving each physical node many points on the ring, so a removed node's load spreads across many neighbors instead of dumping onto one.
AMQP
Advanced Message Queuing Protocol — a wire-level standard for message queuing.
More detail
A standardized, broker-based messaging protocol (as opposed to Kafka's custom protocol over a partitioned log). RabbitMQ is the canonical AMQP implementation, offering flexible routing (exchanges, bindings, per-message routing keys) that lean it toward the work-queue / point-to-point model, though it can do pub-sub too via fanout exchanges.
Message Queue
A buffer decoupling a producer from a consumer in time.
More detail
Lets a producer hand off work and move on; a consumer processes whenever it can. Buys fast producer responses, spike buffering, and consumer fail/restart safety.
Work Queue (Point-to-Point)
Each message is consumed by exactly one worker.
More detail
The "done once by someone" model. Examples: Celery, AWS SQS.
Pub-Sub
Each message is delivered to every subscriber.
More detail
The "everyone notified" model. Examples: Kafka, AWS SNS.
At-Least-Once Delivery
A message is delivered one or more times; never lost, can duplicate.
More detail
What real messaging systems provide. Requires consumers to be idempotent, since a message may be redelivered after a crash-in-the-gap between processing and acking.
Exactly-Once Delivery
A guarantee that only has meaning inside a defined processing boundary.
More detail
Some brokers and stream processors can provide exactly-once effects inside a transaction boundary. A worker can still crash between an external side effect and its acknowledgement, so arbitrary side effects need idempotency keys, an outbox, or reconciliation.
Dead-Letter Queue (DLQ)
Holds messages that repeatedly fail processing.
More detail
Prevents a poison message from blocking the main queue by routing it aside after a bounded number of failed processing attempts.
Visibility Timeout
How long an un-acked message is hidden before redelivery.
More detail
The redelivery window: if a consumer doesn't ack within this window, the message becomes visible again and another consumer may pick it up.
Backpressure
Signaling upstream to slow down instead of buffering forever.
More detail
An unbounded queue is not a fix for structural overload — it delays failure rather than preventing it. If the consumer is structurally slower than the producer, the real fix is adding consumers.
Rate Limiting
Bounding how many requests a client can make in a time window.
More detail
Implemented via token bucket, leaky bucket, or sliding window algorithms. Redis is the canonical store, using atomic INCR+TTL or a sorted-set sliding window.
Token Bucket
A rate-limiting algorithm allowing controlled bursts up to a capped bucket size.
More detail
Tokens refill into a bucket at a fixed rate (e.g. 10/sec); each request consumes one token, and requests are rejected once the bucket is empty. Unlike a strict fixed rate, unused tokens accumulate up to the bucket's capacity, so a client can burst above the average rate briefly if it hasn't been using its full allowance. The most commonly used rate-limiting algorithm because it naturally tolerates bursty, real-world traffic.
Leaky Bucket
A rate-limiting algorithm that processes requests at a strictly constant output rate.
More detail
Incoming requests fill a fixed-size queue ("bucket"); the bucket "leaks" (processes) requests at a constant rate regardless of how bursty the input was, and new requests are dropped once the bucket is full. Unlike token bucket, it smooths bursts out into a steady rate rather than allowing them through — useful when the downstream system genuinely can't handle spikes at all.
Sliding Window Rate Limiter
Counts requests in a moving time window rather than a fixed one, avoiding edge-of-window bursts.
More detail
A fixed window (e.g. "100 requests per minute, reset on the minute") allows a client to send 100 requests at 0:59 and another 100 at 1:00 — 200 in two seconds. A sliding window instead counts requests in the trailing N seconds at all times, closing that loophole. Commonly implemented in Redis with a sorted set keyed by timestamp.
CDN
A network of edge nodes serving cached content near the user.
More detail
Content Delivery Network. Answers the ~150ms transcontinental latency problem by serving static (and sometimes dynamic) content from a node physically close to the requester. Examples: Cloudflare, Akamai, CloudFront, Fastly.
API Gateway
The single front door for cross-cutting concerns: auth, rate limiting, routing.
More detail
A superset of a reverse proxy/load balancer's role, centralizing authentication, rate limiting, SSL termination, and routing for all backend services. Examples: Kong, AWS API Gateway, Envoy.
Bloom Filter
A probabilistic set-membership test with no false negatives.
More detail
Answers "is this key definitely absent?" cheaply, at the cost of occasional false positives (never false negatives). Cassandra uses one per SSTable to skip disk reads for keys that certainly aren't present.
Distributed Lock
A lock coordinated across multiple machines so only one holds it at a time.
More detail
Needed whenever exactly one node must own a piece of work. Implementations: Redlock (Redis-based), ZooKeeper (ephemeral znodes), etcd (lease-based).
Ephemeral Znode
A ZooKeeper node tied to a client session, auto-deleted when the session ends.
More detail
ZooKeeper's primitive for leader election and distributed locking: a client creates an ephemeral znode, which ZooKeeper automatically removes if that client disconnects or crashes (its session expires). Other nodes watch for that deletion to detect failure and trigger a new election — turning "is the leader still alive?" into a problem ZooKeeper's session mechanism answers for you, rather than something each service has to implement with heartbeats and timeouts itself.
SSTable
An immutable, sorted, on-disk file of key-value pairs used by LSM-tree storage engines.
More detail
Short for "Sorted String Table." Cassandra (and other LSM-tree-based stores) write incoming data to an in-memory structure first, then periodically flush it to disk as an immutable, sorted SSTable file. Because SSTables are immutable and sorted, lookups can binary-search them and a per-file Bloom filter can cheaply rule out files that definitely don't contain a given key, avoiding needless disk reads across old files.
Base62 Encoding
Encoding a number using 62 characters (a–z, A–Z, 0–9) for compact, URL-safe codes.
More detail
Used to turn an incrementing counter or hash into a short, URL-safe string. A 7-character base62 code covers 62⁷ ≈ 3.5 trillion values.
Key Generation Service (KGS)
A service that pre-generates and hands out unique short codes.
More detail
One approach to the URL shortener's uniqueness problem: generate a large pool of unused codes ahead of time and dispense them on demand, avoiding collision retries at write time.
HTTP Redirect
An HTTP response that sends the client to another URL through the Location header.
More detail
A URL shortener normally handles GET /{short_code} and returns a 301 or 302 response with the destination in the Location header. 301 allows browsers and intermediaries to cache the redirect; 302 keeps more clicks flowing through the service for analytics and control.
Vector Clock
Version metadata used to distinguish causally ordered writes from concurrent conflicts.
More detail
A vector clock stores a counter per participating replica. If every counter in version B is at least version A's counters, A is an ancestor of B. If neither dominates, the versions are concurrent siblings and require conflict resolution.
Gossip Protocol
A decentralized protocol for spreading membership and heartbeat information.
More detail
Nodes periodically send their membership view and heartbeat counters to random peers. Missing heartbeats eventually mark a node suspect or failed, while updates spread through the cluster without a single monitoring coordinator.
Sloppy Quorum
A temporary quorum that writes to the first healthy nodes instead of the intended replicas.
More detail
When an intended replica is unavailable, the system preserves availability by using another healthy node. The temporary holder records a hint so the value can be handed back when the original replica recovers.
Hinted Handoff
Returning temporarily misplaced replica data to its intended node after recovery.
More detail
A temporary replica stores a hint identifying the unavailable destination. Once that node is healthy, the hint is replayed and the temporary copy can be discarded or reconciled.
Anti-Entropy
A background process that compares replicas and repairs permanent divergence.
More detail
Replicas periodically compare their contents and copy newer or missing values. Merkle trees make this practical by narrowing comparison to ranges whose hashes differ.
Merkle Tree
A hash tree that identifies which data ranges differ between replicas.
More detail
Leaf hashes summarize data ranges; parent hashes summarize child hashes; the root summarizes the replica. Matching roots mean the compared ranges match, while differing branches guide a small repair instead of a full dataset copy.
Snowflake ID
A compact distributed ID composed of time, worker identity, and a sequence number.
More detail
A common layout uses timestamp bits, datacenter and machine or worker bits, and sequence bits for multiple IDs generated in one millisecond. It is roughly time-sortable, but requires unique worker assignment and clock rollback handling.
URL Frontier
The prioritized queue of URLs waiting to be downloaded by a crawler.
More detail
A frontier separates waiting URLs from visited URLs and combines priority, freshness, host routing, and politeness. It is usually durable enough to resume after a worker or process failure.
Crawler Politeness
Rate and concurrency controls that prevent a crawler from overwhelming a host.
More detail
Route URLs for the same host to controlled queues and add delays or concurrency limits between downloads. Politeness is both an operational requirement and a way to avoid looking like a denial-of-service attack.
Robots.txt
A site-provided policy describing which crawler paths may be downloaded.
More detail
Before crawling a host, fetch and cache its robots.txt rules, then apply the relevant user-agent and allow/disallow directives. It is a cooperation protocol, not a security boundary.
Fanout on Write
Precomputing followers' feeds when a post is published.
More detail
A publish event is copied into each follower's feed cache before they read. This gives fast reads but creates high write amplification and hot-key problems for accounts with enormous audiences.
Fanout on Read
Building a feed when a user requests it by merging followed accounts' posts.
More detail
The system stores posts once and assembles a user's stream at read time. It avoids work for inactive users and celebrities, but increases read latency and query complexity.
WebSocket
A persistent, bidirectional connection between a client and server.
More detail
After an HTTP upgrade, either side can send messages over the live connection. WebSockets suit chat and presence, but live connection state must be routed to the correct server and durable messages must live elsewhere.
Online Presence
A time-bounded estimate of whether a user or device is currently connected.
More detail
Presence services use connection state and heartbeats. A user is online while heartbeats arrive within a lease window; after the timeout, the status expires rather than relying on a clean disconnect event.
Trie
A prefix tree for fast string lookup and autocomplete.
More detail
Each edge represents a character and each node represents a prefix. Store the top k completions at each node to answer common autocomplete queries without traversing the entire subtree.
Pre-Signed Upload URL
A time-limited, scoped URL that lets a client upload directly to object storage.
More detail
The API authorizes an upload and returns a URL with a short expiry and constrained object key or method. The client sends the large payload to storage instead of consuming API-server bandwidth.
DAG Transcoding Pipeline
A directed acyclic graph of dependent media-processing tasks.
More detail
A video pipeline can split, decode, encode, package, and publish artifacts as separate tasks. The DAG scheduler runs independent tasks in parallel, retries failed work, and tracks dependencies so one failure does not restart everything.
Resumable Upload
An upload protocol that can continue after a connection or process failure.
More detail
The server creates an upload session and records confirmed byte ranges or blocks. A client reconnects, asks for the current state, and sends only the missing portion instead of restarting a large file.
Delta Sync
Transferring only the file blocks that changed since the previous version.
More detail
Split a file into content-addressed blocks and compare hashes between versions. Upload only changed blocks, then write new metadata that references the complete block set.
Database Choice
Selecting relational, key-value, document, or object storage from access patterns.
More detail
Start with transactions, query shapes, relationships, consistency, size, and latency. Relational databases fit constraints and joins; key-value or document stores fit known-key access and flexible large-scale records; object storage fits large immutable blobs.
Multi-Datacenter Replication
Keeping data or services available across independent geographic failure domains.
More detail
Cross-region copies improve availability and user latency, but add replication lag, failover routing, conflict resolution, data residency, and recovery-point decisions. State whether writes are active-active or routed to one primary region.
ACID
Atomicity, Consistency, Isolation, and Durability guarantees for transactions.
More detail
Atomicity makes a transaction all-or-nothing; consistency preserves declared invariants; isolation controls concurrent visibility; durability keeps committed data after failure. These guarantees are valuable for metadata and permission changes but may cost scale or latency.
Cold Storage
Lower-cost storage for data that is accessed rarely.
More detail
Move old versions, backups, or infrequently watched media to an archival tier. Cost savings come with higher retrieval latency and sometimes additional restore fees, so lifecycle rules should match retention and recovery requirements.
Relational Model
Tables, rows, relationships, constraints, and declarative queries.
More detail
A data model built around relations and sets of rows. It is a strong fit when relationships, joins, constraints, and multi-object transactions are central. The model is independent of one particular relational database product.
Document Model
Self-contained nested records optimized for aggregate reads.
More detail
Stores related values together as a document. It can simplify reads and schema changes when the aggregate is read as one unit, but duplicated or cross-document relationships need explicit update and consistency handling.
Graph Model
Nodes and edges optimized for relationship traversal.
More detail
Represents entities and their relationships directly. It is useful when the important queries follow paths through a connected graph rather than filtering independent records.
Schema-on-Read
Interpret data structure when reading rather than enforcing it at write time.
More detail
The storage accepts flexible records and readers apply the expected shape later. It improves ingestion flexibility but moves malformed-data handling and compatibility work into readers and transformations.
Schema-on-Write
Validate and store data against an explicit schema at write time.
More detail
The writer must satisfy the declared structure before data is accepted. This protects downstream readers and invariants, but schema changes need a rollout plan.
Declarative Query
Describe the result required while the engine chooses the execution plan.
More detail
SQL is the common example: the query states what rows or result set are wanted, while the optimizer chooses indexes, joins, scans, and parallelism. This differs from procedural code that specifies each transformation step.
Materialized View
Persisted derived results maintained from source data.
More detail
A materialized view precomputes a query, join, or aggregate for faster reads. It is a deliberate copy, so refresh lag, invalidation, backfill, and rebuild behavior are part of the design.
OLTP
Online transaction processing with many small interactive operations.
More detail
User-facing workloads typically read or update a small number of records and need predictable latency, indexes, concurrency control, and transactional integrity.
OLAP
Online analytical processing over large scans and aggregates.
More detail
Analytical workloads issue fewer but heavier queries over many records. Column storage, compression, parallel scans, and precomputed aggregates often fit better than point-lookup indexes.
Hash Index
An index that maps a key hash to a record location or bucket.
More detail
Efficient for equality lookups when the key is known, but it does not naturally support ordered range scans. Hashing also needs collision handling and durability rules.
B-tree
A balanced ordered index organized into fixed-size pages.
More detail
B-trees keep keys ordered and bounded in height, making point lookups and range scans predictable. Updates modify or split pages in place, which trades read simplicity for random-write work and page contention.
LSM-Tree
An append-oriented storage engine that merges immutable sorted files.
More detail
Writes land in a memory table and later flush to immutable SSTables. Background compaction merges files and removes obsolete versions. It can make writes efficient while increasing read and compaction work.
Compaction
Background merging of immutable files or obsolete records.
More detail
Compaction rewrites storage to reduce duplicate versions, improve locality, and reclaim space. It consumes I/O and CPU, so compaction scheduling is part of tail-latency and capacity planning.
Memtable
The in-memory sorted table that receives every write in an LSM engine.
More detail
An in-memory sorted structure (commonly a skip list or red-black tree) holding the most recent writes. Sorting in RAM costs no I/O, which is what lets an LSM engine write only sequentially and still flush a file that is already in key order. It is flushed to an immutable SSTable when it reaches a size threshold, and it is backed by the write-ahead log so a crash does not lose it (see 3.3).
Tombstone
A marker recording that a key was deleted, since nothing is erased in place.
More detail
In an append-only engine there is no way to erase a record, so a delete appends a marker that shadows every older value for the key. A tombstone may only be discarded once compaction covers every file that could still hold an older value; dropping it early makes a deleted row reappear. Delete-heavy workloads therefore grow before they shrink (see 3.3).
Sorted Run
A set of files whose keys are sorted and non-overlapping, searchable as one unit.
More detail
A run behaves like a single sorted file for lookup purposes. Leveling keeps one run per level; tiering allows up to T runs per level. The number of runs a query must consult is what read amplification counts (see 3.3).
Leveled Compaction
A policy keeping one sorted run per level: cheaper reads, more rewriting.
More detail
Merging into level i rewrites the overlapping part of that level, so an entry is rewritten about T times per level, giving write amplification of order T·L and point-lookup cost of order L. It also keeps space amplification low. This is the RocksDB and LevelDB default (see 3.3).
Size-Tiered Compaction
A policy letting T runs accumulate per level: cheaper writes, more reading.
More detail
Runs pile up at a level and are merged only when the level is full, so an entry is written about once per level — write amplification of order L — at the cost of checking up to T·L runs per lookup and holding up to T copies per level. This is the Cassandra default (see 3.3).
Size Ratio (T)
The growth factor between adjacent LSM levels, and the main compaction dial.
More detail
With data size N and memtable size M, the level count is L = ceil(log_T(N/M)). T appears in every amplification term: raising it makes leveling write more and read less, lowering it does the reverse. There is no value that makes both cheap (see 3.3).
Space Amplification
Bytes physically stored divided by bytes logically live.
More detail
The third amplification alongside read and write. LSM engines pay it in obsolete versions and uncollected tombstones until compaction runs; B-trees pay it in page fragmentation from splits. Leveling keeps it low, tiering allows up to T copies per level (see 3.3).
Sparse Index
One index offset every few kilobytes rather than one per key.
More detail
Because an SSTable is sorted, an index does not need an entry per key: a sparse set of offsets narrows a lookup to one small block that is then scanned. This is what keeps the in-memory index small enough to hold for a large file — sorting is what makes the index cheap (see 3.3).
Fanout (B-tree)
The number of children per node, set by how much fits in one page.
More detail
Fanout B is roughly page size divided by (key size + pointer size), so a 4 KB page with 32-byte entries gives B of about 128. Lookup cost is the tree height, about log_B(N), so a large fanout is the whole point: a billion rows sit about 5 levels deep instead of the ~30 a binary tree would need (see 3.3).
Read Amplification
One logical read requires checking multiple physical structures.
More detail
LSM engines may check memory and several SSTables; indexes may require multiple page reads. Bloom filters, caches, and compaction reduce the number of structures visited.
Write Amplification
One logical write causes multiple physical writes.
More detail
Page splits, WAL records, replication, compaction, and index maintenance can all multiply physical work. Measure it when sizing storage bandwidth and SSD endurance.
Column-Oriented Storage
Store values from the same column together for analytical scans.
More detail
Column storage improves compression and lets an analytical query read only the columns it needs. It is usually a complement to an OLTP store, not a universal replacement.
Backward Compatibility
New code can read data written by older code.
More detail
Required during rolling upgrades and long-lived data retention. New readers should understand old fields and preserve old meanings while the fleet migrates.
Forward Compatibility
Old code can read data written by newer code.
More detail
Usually requires old readers to ignore unknown fields and new writers to avoid changing the meaning of existing fields until all readers are upgraded.
Schema Evolution
Changing a data contract while old and new participants coexist.
More detail
Safe evolution requires compatibility rules, rollout order, ownership, and a deprecation window. The same concern applies to database rows, RPC messages, queue events, and client payloads.
Rolling Upgrade
Gradually replace instances while the old and new versions run together.
More detail
Rolling upgrades reduce downtime and blast radius, but require mixed-version compatibility. Deploy readers before writers when introducing new fields or event shapes.
Dataflow
A sequence of transformations that moves data between systems.
More detail
Dataflow makes the producer, encoding, transformation, destination, lag, and retry behavior explicit. It is the common shape connecting databases, queues, streams, indexes, and analytics.
System of Record
The authoritative source from which other state is derived.
More detail
A system of record owns the durable truth for a fact. Caches, search indexes, analytics tables, and notifications should have a defined relationship to that source and a way to recover from drift.
Derived Data
Data computed from another source rather than written as primary truth.
More detail
Derived data includes caches, indexes, materialized views, aggregates, and machine-learning features. Retain enough input history or snapshots to rebuild it when code or requirements change.
Change Data Capture
Publish database changes as an ordered or replayable change stream.
More detail
CDC commonly reads a database log so inserts, updates, and deletes can feed search, caches, warehouses, or services. Consumers still need schema evolution, duplicate handling, transaction ordering, and replay rules.
Event Sourcing
Treat an append-only event history as the primary record of changes.
More detail
Current state is reconstructed by replaying events. Event sourcing improves auditability and replay, but event schemas, snapshots, privacy, corrections, and projection rebuilds become long-lived design obligations.
Log Compaction
Retain the latest value per key while preserving a compacted log.
More detail
Compaction removes obsolete records while keeping the newest state for each key. It supports rebuilding a key-value view without retaining every historical update forever.
Isolation Level
A contract describing what concurrent transactions may observe.
More detail
Isolation is a spectrum. Weaker levels permit more anomalies but usually allow more concurrency; stronger levels prevent more anomalies but may block or abort transactions.
Read Committed
Each statement reads data committed before that statement began.
More detail
Two statements in one transaction may see different committed states. It prevents dirty reads but does not by itself prevent lost updates, read skew, or predicate anomalies.
Snapshot Isolation
A transaction reads from a stable snapshot of committed data.
More detail
Readers see a consistent version while writers continue. It prevents many read anomalies, but write skew and some lost-update patterns still require stronger protection or explicit coordination.
Serializable Isolation
The result is equivalent to some serial execution of transactions.
More detail
Serializable execution preserves the strongest general concurrency contract, often through locking or conflict detection. Applications must expect blocking or serialization failures and retry safely.
Lost Update
A concurrent write overwrites another write based on stale data.
More detail
Two actors read the same old value, compute independent updates, and the later write erases the earlier one. Use atomic updates, compare-and-set, locks, or a transaction that detects the conflict.
Write Skew
Independent valid writes together violate a multi-record invariant.
More detail
Each transaction observes a valid state and changes a different row, but both commits make the combined state invalid. Serializable isolation or explicit locking of the invariant is required.
Phantom Read
A repeated predicate query sees rows appear or disappear.
More detail
Another transaction inserts, deletes, or changes a row so it enters or leaves the predicate result. Range locking or serializable conflict detection protects the predicate when needed.
Two-Phase Commit
A coordinator prepares participants, then asks all to commit.
More detail
2PC provides distributed atomic commit when participants support the protocol, but adds coordinator state, blocking paths, timeouts, and operational coupling. It is not a universal substitute for local transactions and asynchronous workflows.
Saga
A distributed workflow composed of local transactions and compensating actions.
More detail
Each step commits locally and emits the next action. If a later step fails, compensating work attempts to restore the business outcome. Sagas need idempotency, durable progress, and explicit intermediate states.
Transactional Outbox
Store an outgoing event beside the state change in one local transaction.
More detail
The transaction writes business state and an outbox row atomically. A separate publisher retries unsent rows, preventing the dual-write gap between committing a database change and publishing a message.
Partial Failure
One part of a distributed operation fails while other parts continue.
More detail
A request may be delayed, duplicated, accepted without its response, or processed by a node that another node considers dead. Robust designs make retries, ownership, and recovery explicit.
Failure Detector
A mechanism that suspects whether another process or node is unavailable.
More detail
In an asynchronous network, a timeout cannot prove that a node crashed; it may only be slow or partitioned. Failure detectors therefore produce suspicions that need quorum, epochs, or fencing before authority changes.
Timeout
A local deadline after which a caller stops waiting.
More detail
A timeout bounds caller patience; it does not cancel remote work or prove the outcome. Pair it with request identity, idempotency, cancellation where supported, and reconciliation.
Clock Skew
Different nodes disagree about the current wall-clock time.
More detail
NTP reduces skew but does not create a perfectly shared clock. Do not use wall-clock timestamps as sole proof of causality or ownership without an error bound and a safer protocol.
Monotonic Clock
A local clock that moves forward for measuring elapsed time.
More detail
Monotonic clocks are appropriate for timeouts, durations, and retry backoff because wall-clock adjustments should not make elapsed time negative or unexpectedly long.
Lease
Time-bounded ownership that expires unless renewed.
More detail
A lease lets a system act on temporary ownership, but a paused owner may resume after expiry. The protected resource should validate a fencing token or epoch rather than trusting the lease holder alone.
Fencing Token
A monotonically increasing ownership number checked by the protected resource.
More detail
When ownership changes, the new owner receives a higher token. Storage or the external resource rejects operations carrying an older token, preventing delayed work from acting after a lease expires.
Process Pause
A process stops making progress and later resumes with stale assumptions.
More detail
Garbage collection, scheduler stalls, resource pressure, or a debugger can pause a process long enough for another node to take ownership. Fencing protects against its late return.
Epoch / Term
A monotonically increasing generation number for leadership or membership.
More detail
A new leader or configuration receives a higher term. Messages from an older term are rejected, which prevents a delayed former leader from being treated as current authority.
Byzantine Fault
A component behaves arbitrarily or maliciously rather than simply crashing.
More detail
Byzantine tolerance matters when nodes or communication may be adversarial or independently operated. Ordinary service architectures usually assume crash and omission faults instead, but should state that assumption.
Batch Processing
Process a bounded dataset through a parallel transformation.
More detail
Batch jobs partition input, move related records together, perform joins or aggregations, and emit derived output. Deterministic operators and materialized checkpoints make failed work recomputable.
Map
Apply an independent transformation to each input record.
More detail
Map stages are naturally parallel because each input can be processed independently. They commonly emit intermediate key-value pairs for a later grouping stage.
Shuffle
Repartition intermediate data so equal keys meet at one worker.
More detail
Shuffle is the network-heavy boundary between independent transformation and grouped processing. It determines parallelism, skew, ordering, and often the dominant batch cost.
Reduce
Group related records to aggregate or join them.
More detail
Reduce consumes all or many values for a key and produces a smaller result. It must handle skew, retries, memory pressure, and the desired ordering of grouped input.
Partitioned Log
A durable append-only stream split into ordered partitions.
More detail
Partitions provide parallelism and define the normal ordering boundary. Events with the same key can be routed together; consumers track progress independently by offset.
Consumer Group
Workers that share partitions of a stream between them.
More detail
Each partition is assigned to one active consumer in a group at a time, while different groups can independently replay the same events for different purposes.
Offset
A position identifying progress through a partitioned log.
More detail
Consumers checkpoint offsets so they can resume after failure. The checkpoint must be coordinated with processing state or duplicate processing remains possible.
Event Time
The time an event occurred at its source.
More detail
Event time supports historically correct windows when events arrive late or out of order. It requires a policy for watermarks, late data, corrections, and result revisions.
Processing Time
The time a processor handles an event.
More detail
Processing time is simple and low-latency but can produce different answers when network delay or replay changes arrival order. It is appropriate when approximate real-time behavior is acceptable.
Stream Join
Combine one or more event streams using keys and time or state.
More detail
Stream joins keep state for matching records and must define retention, out-of-order behavior, late data, and what happens when one side is absent.
Stateful Stream Processing
Process events while maintaining durable intermediate state.
More detail
Aggregations, windows, joins, and sessions are stateful. Recovery uses checkpoints, changelog replication, or replay from the input stream.
Checkpoint
Durable progress and operator state used for recovery.
More detail
A checkpoint lets a processor resume from a consistent point instead of starting over. Correctness depends on coordinating the checkpoint with input offsets and output effects.
Cache line
They track fixed-size blocks called cache lines, and on essentially every x86-64 and ARM64 machine a line is 64 bytes.
Go to Latency numbers & the memory hierarchy →memory-level parallelism
Keeping several memory accesses in flight at once is called memory-level parallelism.
Go to Latency numbers & the memory hierarchy →Survival function
The tail is the survival function : the fraction of requests whose duration exceeds , read as "still unfinished at time ".
Go to Random variables in a system: counts, durations & the tail integral →coefficient of variation
What system design compares services by is the ratio of the two, the coefficient of variation:
Go to Random variables in a system: counts, durations & the tail integral →Exponential distribution
Now the specific distribution. is exponentially distributed with rate when
Go to Poisson arrivals & exponential service: the M/M assumptions →memorylessness
The defining property is memorylessness.
Go to Poisson arrivals & exponential service: the M/M assumptions →Erlang distribution
What this earns: the Erlang distribution — the time of the -th arrival is the sum of independent exponential gaps.
Go to Poisson arrivals & exponential service: the M/M assumptions →Poisson process
A Poisson process of rate is a stream of events in time that meets the three assumptions above: a constant average rate, independent counts in non-overlapping windows, and arrivals one at a time.
Go to Poisson arrivals & exponential service: the M/M assumptions →Kendall's notation
The shorthand is Kendall's notation, : arrival process, service distribution, number of servers, introduced by the British statistician David Kendall in a 1953 paper on queueing processes.
Go to Poisson arrivals & exponential service: the M/M assumptions →utilisation
The utilisation of a server is the long-run fraction of time it is busy.
Go to Queueing: why latency explodes near saturation →headroom
The remaining fraction is its headroom.
Go to Queueing: why latency explodes near saturation →fan-out
A request that waits on calls made in parallel has a fan-out of .
Go to Fan-out amplification & hedged requests →tied request
A tied request is sent to two replicas at once, each copy tagged with the identity of the other; whichever begins executing first tells its twin to cancel.
Go to Fan-out amplification & hedged requests →Idempotent operation
An operation is idempotent when performing it times leaves the same end state as performing it once:
Go to Idempotency & retry safety →data model
That shape is a data model: the kinds of structure an application can express — tables of rows, nested documents, nodes and edges — and the operations the database offers over them.
Go to Relational, document & graph models →Normalisation
Data is normalised into tables — each fact stored in exactly one row, and every other place that needs it holding that row's key instead of a copy — and relationships are reconstructed at query time by joins.
Go to Relational, document & graph models →schema
A schema is the description of a record's structure: which fields it has, which are required, and what type each holds.
Go to Schema-on-write vs schema-on-read →rolling deployment
A rolling deployment — replacing a service's instances a few at a time, so the service never goes fully down — makes that concrete: old and new code run simultaneously, so data written by one version must be readable by the other — in both directions.
Go to Encoding formats & schema evolution →backward compatible
A change to a schema is backward compatible when code using the new schema can read data written under the old one, and forward compatible when code using the old schema can read data written under the new one. "Backward" and "forward" are named from the reader's point of view: new code looking back at old data, old code looking forward at new data.
Go to Encoding formats & schema evolution →forward compatible
A change to a schema is backward compatible when code using the new schema can read data written under the old one, and forward compatible when code using the old schema can read data written under the new one. "Backward" and "forward" are named from the reader's point of view: new code looking back at old data, old code looking forward at new data.
Go to Encoding formats & schema evolution →schema registry
A schema registry provides that: a small service that stores every version of a schema under a numeric id, so each file or message carries only the id and a reader fetches the schema it names.
Go to Encoding formats & schema evolution →varint
Each value is preceded by a key written as a varint — a variable-length integer that uses the low seven bits of each byte for the number and the top bit to say whether another byte follows, so small numbers take one byte.
Go to Encoding formats & schema evolution →Stateless service
That is why stateless services are the standard pattern: a stateless server keeps nothing about a client in its own memory between requests, so session state belongs in a shared store, not in a server's memory.
Go to Load balancing →TLS termination
Terminating TLS means the balancer holds the certificate, decrypts the client's connection, and opens its own connection to the backend — which is what lets it read the request at all.
Go to Load balancing →Origin
A cache is a store that holds copies of data whose authoritative version lives elsewhere — in the origin, the system of record the cache sits in front of — placed where reading the copy is cheaper than reading the origin.
Go to Caching: where and why →Cache hit
A read the cache can answer is a hit; one it cannot, which must go to the origin, is a miss.
Go to Caching: where and why →Cache miss
A read the cache can answer is a hit; one it cannot, which must go to the origin, is a miss.
Go to Caching: where and why →hit ratio
The hit ratio is the fraction of reads that are hits.
Go to Caching: where and why →Zipf's law
A workload follows Zipf's law with exponent when, ranking items from most to least requested, the item of rank receives a share of requests proportional to .
Go to Caching: where and why →write-through
In write-through, write to the cache and the database together, synchronously, before acknowledging.
Go to Write policies: through, back, around →write-behind
In write-behind (also called write-back), write to the cache, acknowledge immediately, flush to the database asynchronously.
Go to Write policies: through, back, around →write-around
In write-around, write only to the database and leave the cache alone; the entry populates on the next read.
Go to Write policies: through, back, around →TTL
A time-to-live (TTL) is an expiry duration attached to a cache entry when it is filled; once it has elapsed the cache treats the entry as absent, so the next read misses and refetches from the origin.
Go to Staleness: TTL, stampede & eviction →Eviction
A full cache must evict — discard an entry that has not expired to make room for a new one.
Go to Staleness: TTL, stampede & eviction →Negative caching
Negative caching is caching the answer "this key does not exist".
Go to Staleness: TTL, stampede & eviction →rate limiter
A rate limiter counts the requests each client has made recently, under some key (a user, an API key, an address), and rejects immediately — rather than queues — any request that would take that client past an allowance for a time interval.
Go to Rate limiting algorithms →Point of presence
A content delivery network (CDN) is a shared, geographically distributed cache operated in front of many origins: servers in many cities — each site a point of presence (PoP) — terminate users' connections close to them, answer from their cache when they can, and fetch from the customer's origin over long-lived connections when they cannot.
Go to CDN, API gateway & the front door →Content-addressed URL
The standard answer avoids invalidation entirely: content-addressed URLs — app.3f9a2c.js, where the name includes a hash of the file's contents — so a change produces a new URL, so nothing ever needs purging and assets can be cached effectively forever.
Go to CDN, API gateway & the front door →Leader–follower replication
Leader–follower replication keeps a copy of the data, a replica, on each of several nodes and designates exactly one of them the leader: every write is sent to the leader, which applies it and streams the resulting changes, in its own order, to the other replicas, the followers, which apply them in that same order.
Go to Why replicate: leader–follower →leader
Leader–follower replication keeps a copy of the data, a replica, on each of several nodes and designates exactly one of them the leader: every write is sent to the leader, which applies it and streams the resulting changes, in its own order, to the other replicas, the followers, which apply them in that same order.
Go to Why replicate: leader–follower →Follower
Leader–follower replication keeps a copy of the data, a replica, on each of several nodes and designates exactly one of them the leader: every write is sent to the leader, which applies it and streams the resulting changes, in its own order, to the other replicas, the followers, which apply them in that same order.
Go to Why replicate: leader–follower →read-your-writes
The promise it breaks is read-your-writes: a read reflects every write the same client made before it.
Go to Replication lag & read-your-writes →Failover
Failover is replacing a failed leader with one of its followers, so that writes can resume.
Go to Failover, split-brain & fencing →Split brain
Split brain is the state in which two nodes each believe they are the leader and both accept writes, so the data diverges into two histories, each containing writes that clients were told had succeeded.
Go to Failover, split-brain & fencing →wall-clock time
A small quartz crystal vibrates at a fixed nominal frequency, and the hardware counts vibrations; the operating system turns the count into "seconds since 1 January 1970" (the Unix epoch, chosen when Unix was written at Bell Labs around then), the wall-clock time your program reads.
Go to Physical clocks, NTP & why wall time lies →drift
This slow wandering is called drift, and every machine in a datacentre drifts differently.
Go to Physical clocks, NTP & why wall time lies →NTP
The Network Time Protocol (NTP) is the internet standard for doing that over the network.
Go to Physical clocks, NTP & why wall time lies →Clock step
A step sets the clock to the new value at once, so if the clock was ahead, time visibly jumps backwards.
Go to Physical clocks, NTP & why wall time lies →Clock slew
A slew instead runs the clock slightly slow (or fast) until it has caught up, so time never goes backwards, but for a while a "second" on that machine is not quite a second.
Go to Physical clocks, NTP & why wall time lies →leap second
A leap second, the Cloudflare case above, is a third source of jumps.
Go to Physical clocks, NTP & why wall time lies →commit wait
Spanner turns that into a guarantee with commit wait.
Go to Physical clocks, NTP & why wall time lies →Concurrent events
Two events with no such path in either direction are concurrent: neither could have known about the other. "Concurrent" here does not mean "at the same instant" — two events a minute apart are concurrent if no message connected them.
Go to Logical clocks: happens-before & Lamport timestamps →Lamport clock
A Lamport clock is one integer counter per node, starting at 0 and updated by three rules: add one on every local event, add one and attach the value to every message sent, and on receiving a message carrying set .
Go to Logical clocks: happens-before & Lamport timestamps →version vector
A version vector tracks replica versions of one data item — one entry per replica, not per client — which keeps the size bounded by the number of replicas.
Go to Vector clocks & version vectors: detecting concurrency →History
Each operation has an invocation (the client sends it) and a response (the client receives the result); the record of every invocation and response across all clients, in real-time order, is a history.
Go to What "consistency" means: the model hierarchy →consistency model
A consistency model is a rule that says which histories a system is allowed to produce.
Go to What "consistency" means: the model hierarchy →linearization point
Linearizability says there exists a moment inside that interval, the linearization point, where the whole operation atomically happened.
Go to Linearizability →network partition
The failure in question is a network partition: a network fault that splits the nodes into groups that cannot exchange messages, while the nodes in each group keep running and keep receiving client requests.
Go to CAP: the theorem and its proof →session
A session is the sequence of reads and writes one client issues.
Go to Eventual consistency & session guarantees →Monotonic writes
Monotonic writes: the session's writes are applied at every replica in the order the session issued them.
Go to Eventual consistency & session guarantees →Writes-follow-reads
Writes-follow-reads: a write is ordered, at every replica, after the writes the session had already read.
Go to Eventual consistency & session guarantees →Sharding
Sharding, also called partitioning, splits a dataset into disjoint pieces — shards or partitions — and assigns each piece to a different node, so that every record lives in exactly one shard.
Go to Sharding & the partition key →partition key
That is the partition key — the column, or combination of columns, whose value alone decides a row's shard — and it is the single most consequential schema decision, because it fixes three things at once:
Go to Sharding & the partition key →compound key
The compromise many systems adopt is a compound key: hash a prefix to distribute, keep a suffix ordered within the partition.
Go to Range vs hash partitioning →Virtual node
Virtual nodes fix this — Dynamo's name for giving one physical node many ring positions, which it calls tokens.
Go to Consistent hashing →Key salting
Salting splits one logical key into physical ones by appending a random suffix, so the load spreads across partitions:
Go to Hot partitions & skew →Local (document-partitioned) index
In a local index, each partition keeps an index over only its own rows.
Go to Secondary indexes across partitions →Global (term-partitioned) index
A global index is one index across all the data, partitioned in its own right by the indexed value.
Go to Secondary indexes across partitions →Index projection
DynamoDB names this a projection — the set of columns copied into each index entry — and makes it a required choice at index creation, with three settings: KEYS_ONLY stores only the keys, INCLUDE adds named attributes, and ALL copies the entire row.
Go to Secondary indexes across partitions →quorum
A quorum is the number of replicas an operation must hear from before it may return: acknowledgements for a write and responses for a read, out of the that hold the key.
Go to Leaderless replication & the quorum condition →Coordinator (2PC)
Two-phase commit (2PC) is an atomic commit protocol: a coordinator first asks every participant to prepare — make its part durable and promise it can commit — and only if every participant votes yes does it record "commit" and tell them all to commit; otherwise it tells them all to abort.
Go to Distributed transactions: 2PC, sagas & outbox →Participant (2PC)
Two-phase commit (2PC) is an atomic commit protocol: a coordinator first asks every participant to prepare — make its part durable and promise it can commit — and only if every participant votes yes does it record "commit" and tell them all to commit; otherwise it tells them all to abort.
Go to Distributed transactions: 2PC, sagas & outbox →compensating transaction
A saga is a sequence of local transactions, each committing independently, with a compensating transaction for each step that undoes it semantically.
Go to Distributed transactions: 2PC, sagas & outbox →dual write
Doing both directly is a dual write — two separate commits to two systems with nothing tying them together — and it fails in both directions — commit then crash before publishing, or publish then fail to commit.
Go to Distributed transactions: 2PC, sagas & outbox →Consensus
Consensus is the problem of getting several nodes, each of which may propose a value, to decide a single one of those values, such that no two nodes decide differently, and every node that does not crash eventually decides — even though some nodes may fail.
Go to Consensus: the problem, FLP, Paxos & quorum intersection →partial synchrony
That "behaves well enough" has a name worth learning: partial synchrony, a model introduced by Dwork, Lynch and Stockmeyer in 1988 precisely to describe where consensus becomes solvable.
Go to Consensus: the problem, FLP, Paxos & quorum intersection →Proposer
A proposer is a node that wants a value decided and runs the protocol to get it chosen.
Go to Consensus: the problem, FLP, Paxos & quorum intersection →Acceptor
An acceptor is a voter.
Go to Consensus: the problem, FLP, Paxos & quorum intersection →Chosen value
A value is chosen once a majority of acceptors have accepted it.
Go to Consensus: the problem, FLP, Paxos & quorum intersection →Learner
A learner is anyone who needs the outcome: the other replicas, or a client waiting for a reply.
Go to Consensus: the problem, FLP, Paxos & quorum intersection →ballot number
Each attempt carries a ballot number, an integer unique to that attempt and larger than any the proposer has used before (a node id breaks ties), so that newer attempts outrank older ones — the same trick as a fencing token.
Go to Consensus: the problem, FLP, Paxos & quorum intersection →replicated state machine
A replicated state machine is a set of servers that each start in the same state and apply the same deterministic commands in the same order, so they all end in the same state.
Go to Raft →producer
A producer (service A) sends a message: a small record describing work to do, such as "make thumbnails for upload 81723".
Go to Message queues: decoupling in time →consumer
A consumer (service B) asks the broker for a message, does the work, and then sends an acknowledgement ("done with this one").
Go to Message queues: decoupling in time →acknowledgement
A consumer (service B) asks the broker for a message, does the work, and then sends an acknowledgement ("done with this one").
Go to Message queues: decoupling in time →Message broker
A message queue is a durable buffer of messages between producers and consumers, run as its own service, the message broker.
Go to Message queues: decoupling in time →work queue
In a work queue (also called point-to-point), each message is handed to exactly one of the consumers reading the queue.
Go to Message queues: decoupling in time →Publish-subscribe
In publish-subscribe (pub-sub), a producer publishes to a named topic and every subscriber to that topic receives its own copy.
Go to Message queues: decoupling in time →delivery guarantee
A delivery guarantee states how many times a message may be processed when failures occur.
Go to Delivery guarantees & queue operations →At-most-once delivery
At-most-once delivery means a message is processed once or not at all: it can be lost, never duplicated.
Go to Delivery guarantees & queue operations →Exactly-once semantics
What is achievable is the exactly-once effect: at-least-once delivery combined with idempotent processing, which is what the term exactly-once semantics means in practice.
Go to Delivery guarantees & queue operations →poison message
A poison message is one that makes the handler fail every time, because its payload is malformed or it hits a bug, so retrying it never helps.
Go to Delivery guarantees & queue operations →dead-letter queue
So after failed attempts (SQS calls this maxReceiveCount) the broker moves it to a dead-letter queue (DLQ): a separate queue that holds failed messages for a person to inspect.
Go to Delivery guarantees & queue operations →batch job
A batch job reads a fixed input, transforms it, and writes a new output.
Go to Batch processing & distributed dataflow →Bounded input
Its input is bounded: it has an end, known when the job starts, so the job terminates and its result is complete for that input.
Go to Batch processing & distributed dataflow →Input split
It cuts the input into splits (pieces of, say, 64 MB to a few GB), runs one task per split independently on many machines, and then combines the results by key, the field the records are grouped by, such as the customer id.
Go to Batch processing & distributed dataflow →Task (batch)
It cuts the input into splits (pieces of, say, 64 MB to a few GB), runs one task per split independently on many machines, and then combines the results by key, the field the records are grouped by, such as the customer id.
Go to Batch processing & distributed dataflow →backup task
The mechanism was a backup task: near the end of a job, start a second copy of each still-running task on another machine and take whichever finishes first.
Go to MapReduce: map, shuffle, reduce →MapReduce
MapReduce is a model for batch jobs in which the programmer supplies two functions.
Go to MapReduce: map, shuffle, reduce →map-side join
In a map-side join, one side of a join is small enough to fit in memory, so it is broadcast to every mapper and joined there — eliminating the shuffle entirely.
Go to MapReduce: map, shuffle, reduce →bisection bandwidth
In real systems: is a count of emitted intermediate pairs and their average serialised size in bytes, so is bytes crossing the network — the number to compare against the input size itself and against the cluster's bisection bandwidth: the total bandwidth across the narrowest cut that splits the cluster into two halves.
Go to MapReduce: map, shuffle, reduce →DAG (dataflow)
Spark, begun by Matei Zaharia and colleagues at UC Berkeley (first described at HotCloud 2010, with its core abstraction, resilient distributed datasets, published at NSDI 2012), and the engines that followed it keep intermediate data in memory and express a whole pipeline as a DAG (directed acyclic graph): a graph of stages in which data flows one way and never loops back.
Go to MapReduce: map, shuffle, reduce →Stream
A stream, in this module, is such a sequence treated as unbounded: new events keep arriving for as long as the system runs.
Go to Streams, partitioned logs & offsets →Topic (log)
A topic is a named log for one kind of message, such as orders or page-views.
Go to Streams, partitioned logs & offsets →Partition (log)
One log on one machine has one machine's throughput, so a topic is split into partitions, each an independent append-only sequence with its own offsets, spread across the brokers.
Go to Streams, partitioned logs & offsets →Offset commit
Saving it is called committing the offset, and there are two usual places:
Go to Streams, partitioned logs & offsets →Consumer lag
Consumer lag — the distance between the log's end and a consumer's offset — is the single most important metric here.
Go to Streams, partitioned logs & offsets →stream processor
A stream processor is a long-running program that reads a stream continuously and keeps results up to date as events arrive.
Go to Event time, watermarks & windowing →Window (stream)
Since a stream has no end, aggregation happens over windows: finite slices of event time, each producing its own result, such as "active users from 10:00 to 10:01".
Go to Event time, watermarks & windowing →tumbling window
Tumbling — a tumbling window has a fixed size and does not overlap its neighbours.
Go to Event time, watermarks & windowing →sliding window
Sliding — a sliding window has a fixed size and overlaps its neighbours.
Go to Event time, watermarks & windowing →session window
Session — a session window covers one burst of activity, per user, closing after a gap of inactivity.
Go to Event time, watermarks & windowing →allowed lateness
To update a window the processor must still hold its state, so Flink and Beam keep a closed window's state for an extra period called allowed lateness, measured in event time past the watermark.
Go to Event time, watermarks & windowing →Upsert
Systems that emit to a store supporting upserts — insert-or-overwrite by key, so writing a corrected value for a window replaces the old one — handle this naturally; those that append do not, and discover the problem after the first correction.
Go to Event time, watermarks & windowing →Lambda architecture
It became known as the Lambda architecture.
Go to Event time, watermarks & windowing →Kappa architecture
He called this the Kappa architecture.
Go to Event time, watermarks & windowing →Checkpoint (stream processing)
It takes checkpoints: every few seconds or minutes it writes a consistent copy of all its operator state — the open windows and their counts — together with the input offsets that state reflects, to durable storage.
Go to Event time, watermarks & windowing →Fold
A fold starts from an empty state and applies each event in order to the running state: OrderPlaced creates the order, PaymentReceived marks it paid, and so on.
Go to CDC & event sourcing →read model
A read model, also called a projection, is a separate table built by consuming the events and shaped for one query — "open orders per customer", say.
Go to CDC & event sourcing →Projection (event sourcing)
A read model, also called a projection, is a separate table built by consuming the events and shaped for one query — "open orders per customer", say.
Go to CDC & event sourcing →CQRS
Splitting the model that accepts writes (commands that append events) from the models that answer reads (projections) has its own name: command query responsibility segregation, or CQRS, a pattern Martin Fowler, writing it up in 2011, credits to Greg Young.
Go to CDC & event sourcing →Snapshot (event sourcing)
The answer is snapshots — periodically store the folded state and replay only events after it — which is compaction again, and must be designed in rather than added when it starts hurting.
Go to CDC & event sourcing →Aggregate (event sourcing)
Snapshots cannot help there; the state itself is too large for one entity, and the fix is to split the aggregate — the entity whose events are replayed together, such as one order or one account — into smaller ones rather than to snapshot more often.
Go to CDC & event sourcing →REST
This style, in which each thing the system holds is named by a URL and acted on with HTTP's standard methods, is called REST (Representational State Transfer).
Go to API design →base62
Counter + base62.
Go to Deep dives →service level indicator (SLI)
A service level indicator (SLI) is a measured quantity describing the service a user receives, such as the fraction of requests served successfully within a latency threshold.
Go to Cross-cutting production decisions →service level objective (SLO)
A service level objective (SLO) is a target value for an SLI over a stated window, such as 99.9 % over 30 days.
Go to Cross-cutting production decisions →service level agreement (SLA)
A service level agreement (SLA) is a contract that attaches a consequence — a refund, a credit — to missing an SLO.
Go to Cross-cutting production decisions →critical path
A request's critical path is the set of services it cannot succeed without.
Go to Cross-cutting production decisions →recovery point objective (RPO)
The recovery point objective (RPO) is how much recent data you may lose, measured in time.
Go to Cross-cutting production decisions →recovery time objective (RTO)
The recovery time objective (RTO) is how long the service may be down before the standby is serving: detection, promotion, and redirecting traffic.
Go to Cross-cutting production decisions →