advanced25 min studyLesson 359 in Engineering

Control-plane storage: history, watches, and write amplification

Budget logical churn and retained versions while separating Kubernetes API tokens from etcd’s documented revision model.

On this page

What you’ll understand

  • Explain etcd store revisions and multi-key transaction revisions.
  • Estimate retained logical history and watch-delivery payload.
  • Distinguish compaction, defragmentation, and reducing unnecessary writes.

A control plane stores desired state, status, and coordination records while many clients watch changes. A small write repeated needlessly can create storage history, watch traffic, controller work, and further writes. This lesson uses etcd v3.6 documentation for the storage model and Kubernetes v1.34 for the API boundary. The two layers are related operationally, but their public version contracts must not be casually equated.

An etcd revision orders store modifications

etcd maintains a store revision that advances when the key space is modified. A transaction that changes multiple keys advances the revision once, and its generated modification events share that revision. A key also has creation revision, modification revision, and a per-key version field with different meanings. These are documented etcd concepts; they are not a license for a Kubernetes API client to parse resourceVersion numerically or infer wall-clock duration from it. The store’s logical ordering and elapsed-time measurements answer different questions.

Multi-version storage retains historical states until compaction removes superseded history according to policy. A watcher can resume only while the requested history remains available; a compacted revision produces the documented failure and requires a new valid boundary. Longer retention supports longer disconnect recovery but increases retained-history work and space. Short retention can shift cost into relists and catch-up. Choose the policy with actual client lag, restart, and recovery needs rather than minimizing one storage metric in isolation.

Rafter=Rbefore+1R_{\rm after}=R_{\rm before}+1
This describes one successful etcd transaction that modifies the key space, even when it changes several distinct keys. R is a logical store revision, not seconds. Read-only or nonmodifying requests do not fit this increment assumption.↔ Scroll wide equations horizontally.

Logical bytes are only one part of the budget

A rough retained-history estimate multiplies the rate of stored versions by mean version size and retention time. Actual database size includes indexes, metadata, encoding, page reuse, and workload-dependent overhead; do not present that estimate as exact on-disk usage. A status update that writes the same logical information can still generate expensive downstream activity, so compare before writing and update only useful changed facts. Separate desired-state change, status progress, heartbeat, and lease renewal rates before attributing all churn to the workload itself.

Compaction makes old history unavailable, while defragmentation reclaims backend space that can remain allocated after history removal. They are different operations. The documented maintenance procedure and availability effects matter; defragmentation on a member can block that member’s reads and writes while it runs. Quota alarms and disk latency can affect control-plane progress, so monitor logical usage, allocated size, request latency, and maintenance behavior. More storage capacity does not by itself fix high latency or uncontrolled write amplification.

Bhistory≈λvsvT,Bfanout/Δt≈λesewB_{\rm history}\approx\lambda_v s_v T,\qquad B_{\rm fanout}/\Delta t\approx\lambda_e s_e w
λ_v is versions per second, s_v bytes per version, and T retention seconds. λ_e is watched events per second, s_e bytes per event, and w matching consumers. These payload estimates exclude protocol, caching, compression, and storage overhead; actual fanout depends on filtering and shared infrastructure.↔ Scroll wide equations horizontally.

Break feedback loops before adding capacity

An unconditional status write can wake the same controller, which writes status again, producing a self-sustaining loop. A broad watch that queues every object after any unrelated event can amplify work further. Inspect per-controller update rates, no-op reconciliations, list sizes, watch reconnects, and object payload growth. Apply bounded retries and appropriate filters without removing events needed for correctness. Capacity planning should include recovery bursts when many controllers restart simultaneously, not just the healthy steady-state average.

The queue lab isolates a producer-service mismatch. Reset, set λ=4 and μ=3, predict backlog 4+t, then Play or Step. Reset and set λ=2, μ=3 to observe drainage under the exact fluid formula. There are no etcd revisions, MVCC versions, WAL writes, watches, compaction, or defragmentation in this model. Use it only to explain why reducing unnecessary arrivals can matter as much as raising service capacity. The actual storage and fanout estimates come from measured rates and explicit units.

Estimate history and watch payload

A fictional workload creates 200 stored versions per second, each averaging 1,000 logical bytes, with one hour of retained superseded history. Assume every version also emits one 1,000-byte event to 20 matching independent consumers.

  1. Convert one hour to 3,600 seconds. The logical history estimate is 200×1,000×3,600=720,000,000 bytes, or 720 decimal MB, before all database overhead and reuse effects.

  2. Event payload production is 200×1,000=200,000 bytes per second. Multiplying by 20 matching consumers gives four million delivered payload bytes per second in this declared fanout scenario.

  3. Halving unnecessary version writes would halve both estimates if sizes, matching consumers, and retention remain unchanged: 360 MB of logical history and two MB/s of fanout. Real API caching, filtering, protocol overhead, and maintenance behavior require separate observation.

The result

Transparent payload estimates reveal the cost of avoidable churn, while on-disk size and actual delivered traffic remain measurement questions.

Explore the model

Interactive lab

Interactive lab · queue

Reduce avoidable arrivals before growing service

Reset, set λ=4 and μ=3, predict backlog 4+t, then Play or Step. Reset and set λ=2 and μ=3 to predict drainage. This fluid backlog is not etcd, a watch pipeline, or an MVCC storage simulator.

Reduce avoidable arrivals before growing serviceFluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Current readings: Fluid backlog: 4; Net rate · λ − μ: −1 /s; M/M/1 mean residence: 1 s. All parameters are adjustable with the labeled controls below.02.557.51001.534.56Elapsed time · sFluid backlogλ < μ
Fluid backlogCurrent time
Fluid backlog
4
Net rate · λ − μ
−1 /s
M/M/1 mean residence
1 s
t = 0 s

Fluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.

Look forReducing unnecessary work can restore a rate balance without changing the correctness protocol.

Check your understanding

How do etcd compaction and defragmentation differ?

Try it yourself

A declared model retains 50 versions/s at 2,000 bytes/version for 600 seconds. Estimate logical retained payload. If a transaction modifies three distinct keys, how many store-revision increments does that one modifying transaction produce?

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

Use rates and seconds for bytes, and the etcd transaction rule for revisions.

Compare with the solution

The estimate is 50×2,000×600=60,000,000 bytes, or 60 decimal MB, excluding storage overhead. The one modifying transaction advances the store revision once; all three key-change events share that transaction’s revision. This does not redefine Kubernetes API version-token semantics.

Take it with you

  • etcd revisions order modifying transactions rather than measure physical time.
  • History retention and fanout multiply the cost of logical churn.
  • Compaction, defragmentation, and no-op-write prevention address different costs.

Read further

Original sources and deeper explanations to follow at your own pace.

Optional progress, saved in this browser when available. Revisit any lesson at any time.

Lesson not marked complete.