Expand description
Row ids: minting them, and reading one that arrived from outside.
Every id this server mints is a UUID version 7 (RFC 9562 §5.7): a 48-bit big-endian millisecond timestamp, then random bits. Two properties follow, and both are why the version moved from 4.
The ids of rows created close together share a prefix, so an index over
them is written at its right-hand edge rather than at a fresh random leaf
per insert. SQLite feels that only mildly — an id column is a secondary
index over the rowid, and one writer at a time dominates — but the
PostgreSQL backend TODO.md plans is where a random primary key costs a
page split and a full-page WAL write per row.
And they sort by creation. ORDER BY created_at, id is the tie-break seven
paged listings use on a whole-second created_at, so that tie-break is now
chronological where a v4 gave a fresh random permutation per pair. Only
among rows minted since the change: the ids already in a table were
converted in place and keep the v4 bits they were minted with, so a v4 and a
v7 in the same second still tie arbitrarily, for ever.
Ids are stored as the 16 bytes themselves, not as text — sqlx’s uuid
feature encodes a Uuid as a SQLite BLOB and decodes it with
Uuid::from_slice, and maps the same type to Postgres’s native uuid. So
there is no decode helper here: row.try_get::<Uuid, _>("id") is the whole
of it. What there is instead is parse, for the one direction that can
fail.
Three mints in this crate are deliberately not row ids and do not come
through mint: the x-request-id fallback
(crate::middlewares::access), the job runner’s lease-owner id
(crate::jobs::runner) and a notification’s delivery_id
(crate::notify). None is the identity of a row, and reaching into the
storage layer for a value that never reaches storage would be backwards.