R1.07 · Caching — the chapter workshop
Cache the instrument catalog.
The chapter capstone: take the six patterns and put EchoCache in front of one real consumer read — the Exchange Platform’s instrument catalog, the reference data the gateway checks on every order.
Grounding: echo/apps/echo_cache (EchoCache.Table, Coherence) · echo/apps/exchange (Exchange.Gateway) · content/bcs4.1–4.2.md · bcsA.md — every figure verbatim from a committed record.
Static verdicts — 1 cache → fetch/3 (:hit | :l2 | :fill) ·
2 consistent → broadcast/enqueue + newer? · 3 harden
→ single-flight + jittered TTL · 4 measure → stats/1 counters.
The consumer, and the read path in layers
exchange/gateway.ex · echo_cache/table.exThe Exchange Platform’s gateway validates every order against a catalog of tradeable instruments.
Exchange.Gateway.parse_place/1 turns an untrusted order into a typed command or one closed
error, and the very first check is the instrument: it calls parse_instrument/1, which answers
{:error, :unknown_instrument} for an instrument the venue does not list. That instrument
lookup is reference data — read on every order, changed rarely — which is
exactly the read-heavy, write-light shape cache-aside is built for. Fronting it with
EchoCache.Table is the workshop.
The read path stacks four layers, each adding one move taught earlier in the chapter, and each leaving
the read correct on its own. The base layer is a cache-aside read:
EchoCache.Table.fetch/3 checks L1 ETS, then on a miss runs a single-flight fill —
GET ecc:{instruments}:<id>, the loader, then SET … PX — and
returns {:ok, value, source} with source :hit | :l2 | :fill. The next layer keeps
the cache consistent: an instrument change runs Coherence.broadcast/4 on the
fast lane or Coherence.enqueue/5 on the at-least-once job lane, and
Coherence.newer?/2 resolves a late message newer-wins.
The third layer hardens the instrument every order touches — EchoCache does this
by construction: the single-flight flights map coalesces a herd onto one fill, and a jittered
TTL (ttl ± ttl·jitter) keeps a cohort from expiring together. The fourth layer
measures: EchoCache.Table.stats/1 returns the counter snapshot —
hits, misses, fills, l2_hits, coalesced, swept, full_skips, sweeps, coh_applied, coh_stale plus
live size — so the hit rate is a number, not a guess. Nothing here is new: each layer is
a pattern from R1.01–R1.06, applied to one real surface. The work is the assembly.
The catalog read path is cache-aside at the base, with three layers stacked on top: keep it consistent on a change, let the single-flight and jitter absorb a herd, and read the hit rate off the counters. Each layer is one move from earlier in the chapter.
The three stages
cache → consistent → harden & measureThe workshop is three dives. Each takes one layer and builds it on the real consumer surface, ending with the read path one step closer to production. Take them in order: the cache must exist before it can be kept consistent, and it must be consistent before its hit rate means anything.
Cache the catalog
Wire EchoCache.Table.fetch/3 over the instrument catalog: an L1 ETS hit, else a
single-flight fill — GET ecc:{instruments}:<id> → loader →
SET … PX. The base read path.
Keep it consistent
On an instrument change, drop the L1 row and resolve newer-wins:
Coherence.broadcast/4 (fast) or Coherence.enqueue/5 (the job lane), with
newer?/2 the comparison. Choose the lane.
Harden and measure
The single-flight flights map and the jittered TTL absorb a herd by
construction, and EchoCache.Table.stats/1 reads the hit rate off the counters.
Walk the build
echo_cache/table.ex · coherence.exPick a stage to see which EchoCache surface it adds to the read path and what the cache can
do once it lands. The surface grows as the stages stack; the readout names the new calls and the property
the layer secures.
Cache-aside at the base, coherence on a change, the single-flight and jitter under a herd, and counters reporting the hit rate — four moves layered into one read path, each correct on its own.
EchoCache.Table in front of the Exchange Platform’s instrument catalog:
fetch fills on a miss, broadcast/enqueue keep it consistent, the
jittered TTL and single-flight absorb a herd, and stats reports the hit rate.
Three stages, four layers, one read path. The workshop turns the chapter’s patterns into a real consumer’s catalog cache — cached, consistent, hardened, and measured.
EchoCache against live Valkey
The figures the workshop reproduces are committed, from the EchoCache gate against the live engine — the L1 hit cost and the lane prices, figure by figure.
L1 ETS hit 1311621 reads/s ← 762 ns each L2 GET 31 us ← the L1 hit is 40 times cheaper coherence · broadcast lane 72 us ← fire-and-forget, at-most-once coherence · job lane 148 us ← at-least-once: 2.1 times the latency
Notes on ValkeyEvery L2 fill is SET … PX —
value and expiry in one atomic command — so the second layer expires itself even if every node forgets;
a separate EXPIRE would leave an immortal key if the process died between the two
— valkey.io/commands/set.
The fair lanes the job lane rides
The at-least-once coherence lane is an enqueue on EchoMQ’s fair lanes — the queue protocol taught in depth in the Queue pillar, rung by rung.
/bcs · Part IVThe EchoCache manuscript
L1 ETS over L2 Valkey, coherence by mint time, the lane that remembers — the cache built and gated, chapter by chapter.
start hereR1.07.1 · Cache the catalog
The base read path: fetch/3 over the instrument catalog, an L1 hit or a single-flight
fill.
References
sources · relatedSources
- Valkey — SET —
SET … PXsets a value and its expiry in one atomic command; the L2 fill of every cache layer. - Valkey — Topics — the engine the EchoCache gate is measured against, Valkey.
- Redis — Documentation — strings, expiry, and counters — the command families the read path is built from.
- Sanfilippo, S. — antirez weblog — the Redis creator on expiry, atomic operations, and treating cached values as a disposable copy.
- Answer.AI — The /llms.txt convention — the machine-readable map convention this course follows for agent readers.
Related in this course
- R1.07.1 · Cache the catalogthe base read path
- R1.07.2 · Keep it consistentcoherence and the lane choice
- R1.07.3 · Harden and measuresingle-flight, jitter, the counters
- R1.01 · Cache-asidethe base pattern
- R1.02 · Write-throughthe consistency-first alternative
- R1 · Cachingthe chapter