Skip to content
About
Main content

Summary and key takeaways

The six parts, one sentence each:

  1. Memory cannot be time-sliced, and the kernel's swap chooses victims by recency, so serious engines take the decision back. RAM has four claimants: , working memory times concurrency, OS , runtime overhead.
  2. Ownership: , off-heap, tuning, pooled buffers, dictionaries and placement each trade a cost for a cost somewhere else.
  3. Residency: , Clock, LRU-K, and approximate an unknowable future; declared intent () beats inference; pins and limit eviction.
  4. Rationing: grants and admission move failure to the start; the grant is an estimate with a heavy tail; pressure signalling is cooperative; byte limits do not isolate bandwidth.
  5. Degradation: replaces the algorithm, costs the rather than the fraction spilled, fails on one oversized key unless you use sort or algebra, and ends in a kill decision.
  6. Synthesis: five limits, eight escapes with prices, and two rules.

The five limits (nothing evades them): you cannot time-share capacity; know a footprint before it exists; account for memory you did not allocate; make eviction free when it has correctness preconditions; or isolate bandwidth by bounding bytes.

Key formulas and numbers:

FormulaMeaningSeen in
GC cost ≈ ÷ headroomcollector work per byte freedJVM tuning, off-heap
passes = ⌈log_{M/B−1}(N/M)⌉merge passes are a staircase in memorygrants, Memory grants and reservations per operator
one-pass capacity = M²/Bmemory enters quadraticallyhash and sort spill
time ∝ (1 − f) + 2frspill slowdown; r = 50 gives about 6x at 5%What spilling actually costs
R = S / (1 − ρ)response time near full spill device, memory controller
L = λW ()spill raises residence time, so raises in-flight queriesWhat spilling actually costs

Patterns that repeat:

  • mismatch, at every scale from an allocation to a whole node, including failure granularity (process versus query).
  • Costs are relocated, never removed: grants move failure to admission, moves loss to a chosen query.
  • The tail, not the mean, sizes grants, picks the join algorithm and decides the reserve.
  • Independence assumed, but false: predicates correlate upstream, peaks correlate downstream.
  • Declare intent, do not infer it, and measure instead of estimate: the two escapes that cost nothing (with reformulating the algebra).
  • Where is expensive, ration at admission, which forces an estimate; where it is cheap, schedule continuously.

Practical checklist:

  1. Write the four claimants of RAM and make sure two substitutes are not double-buffering.
  2. List what cannot spill; that is your kill inventory.
  3. Compare each grant with the actual peak; add feedback.
  4. Grant in steps, count bytes at admission, hold a reserve for invisible holders, use two watermarks with .
  5. Compute r for the real spill device; compress spill; gate concurrent spillers.
  6. Check the aggregate's algebra before building anything else.
  7. Fail a query before the OS fails a process, and connect the kill path to .
  8. Remember that bandwidth is the one resource nobody isolates.

Amara's closing note (Voltara): ration before the work starts, trust measured peaks over the optimizer, spill for survival and not speed, reduce before writing, and kill a query before the kernel kills a process.