B1.5 · dive — the law of two clocks
Identity time is the id’s; event time is data.
A trading platform runs on two times that look alike and are not. The id’s milliseconds answer exactly one question: when did this architecture first know this entity by name. When the fill occurred at the exchange, when the order was placed by the client, when the risk breach opened — those are claims under someone else’s clock, and they travel as properties in a system’s table, never as readings of the id.
Source: content/bcs1.5.md · What and How; the streams record under bench/valkey-id/ owns the window proof; the rung 1.1 transcript owns the byte-sort proof.
What identity time is
content/bcs1.5.md · WhatPer node it is a strict total order — the minting law’s counter never repeats
and never reverses — and fleet-wide it is a coarse global order at millisecond grain with node
concurrency inside each tick. It is also a free creation instant: the canonical pair in
vectors.json decodes USR0NgWEfAEJfs to 320636799581945856 and
reads unix_ms as 1780512970164, no column required.
The measured record has exercised both faces. The substrate’s gate paged a byte-sort desc over 2000 minted ids with no timestamp consulted:
G4 ordered ok -- page_desc(2000) == byte-sort desc over 2000 minted ids; store holds no clock
And the streams experiment addressed a ten-millisecond window purely by id arithmetic
— 40960 entries (expected 40960), the first of them 1781000000010-28672, an id readable by
eye as time, node, and sequence:
window [+10ms, +20ms) via branded-derived ids: 40960 entries (expected 40960)
first id in window: "1781000000010-28672" (low 22 bits = node 7 << 12 | seq 0 = 28672)
What identity time is not
content/bcs1.5.md · What · Lamport 1978It is not event time, and the distinction has a fifty-year-old foundation. Lamport’s 1978 result examined one event happening before another in a distributed system and showed the relation to “define a partial ordering of the events” — order in a distributed system is a causal construction, not a reading of simultaneous wall clocks, and a timestamp minted here cannot testify about what happened there.
The law of two clocks: identity time is the id’s; event time is data. Every chapter after this one cites the line instead of re-arguing it.
Identity time, as arithmetic
content/bcs1.5.md · HowA window over ORD names is two synthetic cursors, no clock consulted at
read time:
# Elixir — min_for: the smallest snowflake a millisecond can carry
min_for = fn ms -> Bitwise.bsl(ms - 1_704_067_200_000, 22) end
from = EchoData.BrandedId.encode!("ORD", min_for.(t0))
til = EchoData.BrandedId.encode!("ORD", min_for.(t1))
// Go — the same cursor, the same bytes
minFor := func(ms int64) uint64 { return uint64(ms-1704067200000) << 22 }
from := brandedid.MustEncode("ORD", minFor(t0))
til := brandedid.MustEncode("ORD", minFor(t1))
(ms − 1704067200000) << 22 — the smallest snowflake each can carry.min_for(1780512970164) is
320636799581945856 — exactly the canonical vector’s snowflake, because that vector
carries node 0 and sequence 0. The t0/t1 pair brackets the same ten-millisecond window the streams
bench addressed.Event time, as data
content/bcs1.5.md · How + DecisionsThe other side of the law is a refusal: the exchange’s stamp rides beside the name, typed as time, never encoded into one.
defmodule Fill do defstruct [:id, :order_id, :at_exchange] # at_exchange: DateTime — their clock end
type Fill struct {
ID string // FIL… — named when we first knew it
OrderID string // ORD…
AtExchange time.Time // their clock, our data
}
Same grammar both sides of the bus, and the same prohibition: nothing parses an id to
answer an event-time question. The decision of record closes the loop: no created_at
beside an id for “first named” — unix_ms is the accessor, and a duplicate
column is the second clock returning in disguise. Event timestamps are exempt, because they were never
duplicates.
References
sources · relatedSources
- Lamport — Time, Clocks, and the Ordering of Events in a Distributed Systemhappened-before “define[s] a partial ordering of the events”
- Valkey documentation — Streams introductionentry ids carry the millisecond; ranges address time through the id
Related
- B1.5 — The Time Inside the Namethe module hub; the three clocks in context
- B1.2 — The Identity Contractthe order theorem and the second clock this law generalizes
- B1.3 — The ID Systemthe storage record the window proof extends
- EchoMQ — the coursethe bus whose stream entry ids carry the millisecond