R0.2.2 · Valkey under the Exchange Platform — dive 2
The two roles.
One store, two jobs below the facade: EchoCache, the near-cache in front of the read path — derived state, a copy of the truth, safe to drop — and the EchoMQ bus, the work itself — authoritative state, built for atomic hand-off and recovery.
Grounding: content/bcs4.md + bcs4.1.md (the EchoCache role) · bcs3.2.md + bcs3.3.md (the EchoMQ bus role) — every figure verbatim from a committed record.
Static verdicts — EchoCache → derived, L1 hits at 762 ns
against 31 us per L2 GET (bcs4.1) · the EchoMQ bus → authoritative, the
three-field row and the four sorted sets (bcs3.2, bcs3.3) · Valkey → external, one engine
under both.
The cache machine is EchoCache
content/bcs4.md · bcs4.1.mdThe first role is the near-cache in front of the engine’s reads: an L1 of declared ETS tables
over the L2 Valkey the systems already share. Its one-line case is the bcs4 title made plain
— branded keys, local speed, bus-driven coherence. A warm read is a local ETS lookup; a
cold read fills through a declared loader and lands the L2 row with its TTL; an L1 drop falls back to L2
before the loader is consulted again.
The state here is derived — a copy of a truth that lives elsewhere, so a dropped cache costs a slower read, never a lost fact. And the speed difference is committed, not estimated:
1311621 hit reads per second (762 ns each) against 31 us per L2 GET on the same
wire -- the L1 hit is 40 times cheaper than the round trip it replaces, inside the derived band
This role grounds the caching and data-modeling families — in EchoCache’s committed record, or in clean standalone examples.
The EchoMQ bus holds the work
content/bcs3.2.md · bcs3.3.mdThe second role is the bus: the owned-protocol job queue at echo/apps/echo_mq, backed by
Valkey. Here the store holds the queues themselves, and the state is authoritative: the
jobs in the sets are the work, so the bus is built for atomic hand-off and recovery, not for
eviction. The shapes are exact. A job row is a hash of exactly three fields — state,
attempts, payload — and deliberately nothing more: no
enqueued_at, because mint time already lives inside the id. Per queue, four sorted sets carry
the lifecycle:
emq:{q}:pending # score-zero forever — lex order is mint order: FIFO, browse, and time range in one set
emq:{q}:active # scored by lease deadline — the in-flight roster and the expiry index at once
emq:{q}:schedule # scored by run-at — the separate set that keeps scores out of the lex law
emq:{q}:dead # score-zero again — the morgue browses newest-first like everything else
Eight verbs over six scripts move work between them. The order theorem’s dividend is committed, not asserted:
the last five minted in reverse mint order; the very first job sits at the head; 301 pending, no second index anywhere
Notes on ValkeyIn a sorted set, elements with the same score are
ordered lexicographically — the engine fact behind the score-zero pending set, and the
reason delayed work lives in a separate run-at-scored set —
valkey.io/topics/sorted-sets.
This role grounds the queues, coordination, streams, and flow-control families.
Which family, which role
the course map · bcs3 · bcs4The split is the map for the whole course: a pattern family grounds in one role or the other. Pick a family to read which role carries it and what it holds there.
Static verdicts — caching, data modeling → EchoCache (derived) · queues, coordination, streams & events, flow control → the EchoMQ bus (authoritative).
Each role writes its own prefix
The bus writes the closed emq:{q}:<type> grammar; EchoCache’s keyspace is its
own — a fresh prefix beside emq:, never inside it, hashtagged on the table name for the
clustered day. On Valkey, each L2 row carries its TTL on the server’s own clock.
ecc:{<table>}:<id> ← a fresh prefix beside emq:, never inside it
PTTL 300 ms of 300 ← the L2 row, written with SET ... PX
One store can hold two kinds of state: a derived cache, safe to drop, and an authoritative queue, the work itself. The kind of state determines how the role is built.
EchoCache holds the derived half — declared tables, single-flight fills, jittered TTL. The EchoMQ bus holds the authoritative half — the three-field row, the four sorted sets, every transition one atomic script.
Two roles, two kinds of state, two halves of the catalog. Which role grounds a pattern is the first thing each chapter names — and the next dive opens the bus’s own story: the tier that stopped being a reservation.
References
sources · relatedSources
- Valkey — Sorted sets — equal-score lexicographic ordering; the same-score family behind the score-zero decision.
- Valkey — SET — the
PXoption: the L2 row written with its expiry in one command. - Valkey — EXPIRE — expiration semantics; the L2-side counterpart of the L1 sweeper.
- Redis — Documentation — the command and data-type reference behind the catalog.
Related in this course
- R0.2 · Valkey under the Exchange Platformthe module hub
- R0.2.1 · The facade seamthe previous dive
- R0.2.3 · The reserved tierthe next dive; the bus, shipped
- R1 · Cachingthe family EchoCache grounds
- R3 · Reliable Queuesthe family the bus grounds
- /bcsthe architecture both roles are built inside