cost: measure what one write actually pays for #162

Merged
PerishFire merged 1 commit from land/write-cost-bench into main 2026-08-15 08:51:34 +00:00
Owner

cost: measure what one write actually pays for

A caller pushing 452 references into Codehull spent ten seconds, and none of it
was the objects. The cost was per row, and per row it grew with how many rows
the estate already held. This is the bench that says where it goes, run against
in-memory SQLite so durability is out of the picture and only ceremony is left.

Four readings, cargo test -p keel --test cost -- --ignored --nocapture --test-threads=1, release, three hundred writes each:

Flat    sudo 0.20ms  operator 0.77ms  ceremony 0.57ms
Deep    sudo 0.27ms  operator 0.85ms  ceremony 0.58ms
Deeper  sudo 0.28ms  operator 0.91ms  ceremony 0.63ms

sudo set (update plus pulse)     0.18ms
operator set (two checks)        0.21ms
sudo put (insert plus pulse)     0.21ms
operator put (check plus mint)   0.77ms
one authority check              0.01ms
mint alone                       0.54ms

round 1: put 0.92ms, set 0.24ms, grants 303
round 2: put 1.70ms, set 0.24ms, grants 603
round 3: put 2.67ms, set 0.24ms, grants 903
round 4: put 3.77ms, set 0.28ms, grants 1203
round 5: put 4.99ms, set 0.27ms, grants 1503
round 6: put 6.23ms, set 0.27ms, grants 1803

Read together they say one thing. The root-chain walk a check performs is
almost free — depth zero, one and two cost 0.57, 0.58 and 0.63ms of ceremony,
so each hop is hundredths of a millisecond. A check itself is 0.01ms while the
grant cache holds. What costs is the mint: 0.54ms on its own, more than the
business insert it accompanies, because it is a second write with its own
pulse.

And the mint costs a second time. Writing @grant bumps that unit's
generation, so the next check re-reads every grant row; the table it re-reads
grew by one because of the same mint. put therefore climbs from 0.92ms to
6.23ms across six rounds while set — same operator, same grants, same
predicate machinery, no mint — stays at 0.24ms. That pair is the whole
argument: authority checking is not expensive, minting is, and minting is what
makes checking expensive.

The readings stay #[ignore] so the guard lane does not pay for them; they are
run deliberately and read by a person.

Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com

cost: measure what one write actually pays for A caller pushing 452 references into Codehull spent ten seconds, and none of it was the objects. The cost was per row, and per row it grew with how many rows the estate already held. This is the bench that says where it goes, run against in-memory SQLite so durability is out of the picture and only ceremony is left. Four readings, `cargo test -p keel --test cost -- --ignored --nocapture --test-threads=1`, release, three hundred writes each: Flat sudo 0.20ms operator 0.77ms ceremony 0.57ms Deep sudo 0.27ms operator 0.85ms ceremony 0.58ms Deeper sudo 0.28ms operator 0.91ms ceremony 0.63ms sudo set (update plus pulse) 0.18ms operator set (two checks) 0.21ms sudo put (insert plus pulse) 0.21ms operator put (check plus mint) 0.77ms one authority check 0.01ms mint alone 0.54ms round 1: put 0.92ms, set 0.24ms, grants 303 round 2: put 1.70ms, set 0.24ms, grants 603 round 3: put 2.67ms, set 0.24ms, grants 903 round 4: put 3.77ms, set 0.28ms, grants 1203 round 5: put 4.99ms, set 0.27ms, grants 1503 round 6: put 6.23ms, set 0.27ms, grants 1803 Read together they say one thing. The root-chain walk a check performs is almost free — depth zero, one and two cost 0.57, 0.58 and 0.63ms of ceremony, so each hop is hundredths of a millisecond. A check itself is 0.01ms while the grant cache holds. What costs is the mint: 0.54ms on its own, more than the business insert it accompanies, because it is a second write with its own pulse. And the mint costs a second time. Writing `@grant` bumps that unit's generation, so the next check re-reads every grant row; the table it re-reads grew by one because of the same mint. `put` therefore climbs from 0.92ms to 6.23ms across six rounds while `set` — same operator, same grants, same predicate machinery, no mint — stays at 0.24ms. That pair is the whole argument: authority checking is not expensive, minting is, and minting is what makes checking expensive. The readings stay `#[ignore]` so the guard lane does not pay for them; they are run deliberately and read by a person. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
cost: measure what one write actually pays for
Some checks failed
guard / guard (pull_request) Failing after 2m4s
6dd2af9481
cost: measure what one write actually pays for

A caller pushing 452 references into Codehull spent ten seconds, and none of it
was the objects. The cost was per row, and per row it grew with how many rows
the estate already held. This is the bench that says where it goes, run against
in-memory SQLite so durability is out of the picture and only ceremony is left.

Four readings, `cargo test -p keel --test cost -- --ignored --nocapture
--test-threads=1`, release, three hundred writes each:

    Flat    sudo 0.20ms  operator 0.77ms  ceremony 0.57ms
    Deep    sudo 0.27ms  operator 0.85ms  ceremony 0.58ms
    Deeper  sudo 0.28ms  operator 0.91ms  ceremony 0.63ms

    sudo set (update plus pulse)     0.18ms
    operator set (two checks)        0.21ms
    sudo put (insert plus pulse)     0.21ms
    operator put (check plus mint)   0.77ms
    one authority check              0.01ms
    mint alone                       0.54ms

    round 1: put 0.92ms, set 0.24ms, grants 303
    round 2: put 1.70ms, set 0.24ms, grants 603
    round 3: put 2.67ms, set 0.24ms, grants 903
    round 4: put 3.77ms, set 0.28ms, grants 1203
    round 5: put 4.99ms, set 0.27ms, grants 1503
    round 6: put 6.23ms, set 0.27ms, grants 1803

Read together they say one thing. The root-chain walk a check performs is
almost free — depth zero, one and two cost 0.57, 0.58 and 0.63ms of ceremony,
so each hop is hundredths of a millisecond. A check itself is 0.01ms while the
grant cache holds. What costs is the mint: 0.54ms on its own, more than the
business insert it accompanies, because it is a second write with its own
pulse.

And the mint costs a second time. Writing `@grant` bumps that unit's
generation, so the next check re-reads every grant row; the table it re-reads
grew by one because of the same mint. `put` therefore climbs from 0.92ms to
6.23ms across six rounds while `set` — same operator, same grants, same
predicate machinery, no mint — stays at 0.24ms. That pair is the whole
argument: authority checking is not expensive, minting is, and minting is what
makes checking expensive.

The readings stay `#[ignore]` so the guard lane does not pay for them; they are
run deliberately and read by a person.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Land-Source: write-cost-bench@b5d2e04d4c550a1b90704da01b41fbefcfe60d13
PerishFire force-pushed land/write-cost-bench from 6dd2af9481
Some checks failed
guard / guard (pull_request) Failing after 2m4s
to 33a989a409
All checks were successful
guard / guard (pull_request) Successful in 1m53s
guard / guard (push) Successful in 2m3s
2026-08-15 08:49:33 +00:00
Compare
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
PerishLab/keel!162
No description provided.