The DS, explained

Three questions, asked of the same key, at the same instant.

This is the narrative version of Doc 01, Doc 02, and Doc 04 — the story, not the full specification. Read this first; go to Docs when you need the normative version of a claim.

#01

The door of a very busy club

Imagine running the door at an enormous, always-open club. Thousands of faces a minute, and your job is to spot the regulars of the last hour — not the person who came every night in 2019 and stopped, not the one who showed up once tonight, but who's showing up a lot, recently. You can't write anything down per person — millions of possible faces, one notepad, fixed size. You must answer instantly. And memory has to fade on its own, because the club never closes for you to erase the notepad.

Notice that's really three questions about the same face, asked at the same moment: how often (frequency), how recently (decay), and have I seen this one already tonight (first-sighting). Existing structures answer these separately, each with its own bookkeeping. EpochSketch's premise is that because all three are about the same key at the same instant, one structure can answer all three — in one memory access.

#02

One word, three questions

The fusion is literal, not architectural — all three answers live in one 64-bit word, packed by bit position, read or written together in a single atomic operation.

6347230TAGEPOCHCOUNT16 bits24 bits24 bitsa fingerprint —which keythe write epoch —when it happeneda saturating count —how many timesone uint64 — one cache line, one atomic CAS
Every slot is a single 64-bit word, not three. The tag answers "which key," the epoch answers "when," and the count answers "how many" — read or written together in one atomic operation, never three structures that can drift out of sync with each other.
#03

Decay is read, not run

The count field is never decremented, and nothing ever sweeps the table to age entries out. Every read recomputes freshness on the spot: estimate = count >> age, where age is how many ticks have passed since the slot's stored epoch. Two reads of the same untouched slot can return two different answers — not because anything changed, but because time did.

STORED (unchanged)READ RIGHT NOWnot written to in betweenSLOT A · age = 1 tickcount200count >> 1estimate100SLOT B · age = 6 tickscount200count >> 6estimate3
Same stored bits, two different reads. Nothing wrote to either slot between the two observations — the estimate falls from 100 to 3 purely because age grew from 1 tick to 6 and the shift is computed fresh on every read. No sweep, no reset, no background timer anywhere in the structure.
#04

What happens when a bucket is full

Each bucket holds 8 slots. When a new key needs one and all 8 are occupied, the incoming key doesn't just wait — it challenges the weakest resident slot for its spot, a contest Doc 04 calls "the audition." Two designs were pre-registered and run head-to-head against a frozen HeavyKeeper baseline; the table below is the verdict, not the derivation.

OptionMechanismOutcome
A · shippedHash-derived "chip" schedule (M3) — the challenger's own hash decides how much it damages the incumbent on a lossPassed the pre-registered gate; ships in the production engine
C · referenceHeavyKeeper-style RNG lotteryFrozen as the baseline it was measured against — not adopted

Every eviction outcome that isn't a clean win fails toward "first sighting." A dropped increment or a lost eviction never inflates a count — the structure would rather undercount a key it's unsure about than silently overcount one it isn't tracking at all.

#05

Deliberately not

Named to prevent scope creep:

Exact countingKey enumeration / top-kDistributed consistencyPersistence across restartsLifetime totals
#06

Watch it work

No build step, no server — send traffic, step the epoch clock, and watch the raw 64-bit word for a slot flip bit by bit. The chip inspector dissects every eviction attempt: who won, who got chipped, why.

Open full-screen ↗