Public: anyone can read this; the crew can change it.

A test proves a 400 MB snapshot through a throttled fake store restores within the drill's size-scaled budget #2819

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

A real 400 MB snapshot restores green through a 150 Mbit/s store in about 21.5 s, against a 16 min 40 s budget. No phase needed fixing, so `src/snapshot/` is untouched. I didn't get a type check: `bun x tsc --noEmit` fails here with "bun is unable to write files to tempdir" (read-only filesystem), so the forge's check is the first to run it. The new test passes locally under `bun test`.

shipped production is serving it deploy 119f4d2

opened this

A real 400 MB snapshot restores green through a 150 Mbit/s store in about 21.5 s, against a 16 min 40 s budget. No phase needed fixing, so src/snapshot/ is untouched. I didn't get a type check: bun x tsc --noEmit fails here with "bun is unable to write files to tempdir" (read-only filesystem), so the forge's check is the first to run it. The new test passes locally under bun test.

What changed

  • New test/drill-400mb.test.ts runs the real runDrill and the real restoreSnapshot against a fake object store.
  • The store serves a 400 MB packed forge.db (24 parts) plus the rest of a real small snapshot taken in the test, through one shared 150 Mbit/s link that makes each get wait behind the bytes before it.
  • The 400 MB is generated at run time: the snapshot's own database copy followed by incompressible padding, in a single zstd frame. Nothing large is kept in the repo.
  • I used the snapshot's database copy because the live forge.db file sits behind its WAL and lacks the schema.
  • Only boot is stubbed, since the side-booted forge isn't the point.
  • The test asserts a green verdict, budgetMs == drillBudgetMs(manifest.bytes) (at least 1,000,000 ms), the drill finishing inside that budget, and every phase recorded in order. It also asserts that files takes at least the time the wire needs.

Phase times measured

PhaseTime
manifest4 ms
files (download)21,391 ms
unpack7 ms
bundles0 ms
key3 ms
open2 ms
boot101 ms

Download is the slowest phase because the wire is the limit. Unpack takes 7 ms after the last part lands, which shows decompression is streamed during the download rather than done afterwards.

Test time

  • The drill takes 21.5 s and the whole test about 25 s, under the 30 s limit.
  • I did not scale size or speed down. Scaling both together leaves the wire time unchanged, and the full-size test already fits.
  • Setup is about 3.5 s and the test needs roughly 1 GB of memory briefly. On a slow machine the margin to 30 s is thin.

Not done

  • Clone time isn't covered: the snapshot has no large repositories, so bundles is 0 ms. The clone phase is untested at this size.
  • The node zstd stream stops after the first frame of a multi-frame input without an error, so the generator writes one frame. The real packer already writes one.

🤖 Generated with Claude Code

Closes #2813

commented

A real 400 MB snapshot restores green through a 150 Mbit/s store in about 21.5 s, against a 16 min 40 s budget. No phase needed fixing, so src/snapshot/ is untouched. I didn't get a type check: bun x tsc --noEmit fails here with "bun is unable to write files to tempdir" (read-only filesystem), so the forge's check is the first to run it. The new test passes locally under bun test.

What changed

  • New test/drill-400mb.test.ts runs the real runDrill and the real restoreSnapshot against a fake object store.
  • The store serves a 400 MB packed forge.db (24 parts) plus the rest of a real small snapshot taken in the test, through one shared 150 Mbit/s link that makes each get wait behind the bytes before it.
  • The 400 MB is generated at run time: the snapshot's own database copy followed by incompressible padding, in a single zstd frame. Nothing large is kept in the repo.
  • I used the snapshot's database copy because the live forge.db file sits behind its WAL and lacks the schema.
  • Only boot is stubbed, since the side-booted forge isn't the point.
  • The test asserts a green verdict, budgetMs == drillBudgetMs(manifest.bytes) (at least 1,000,000 ms), the drill finishing inside that budget, and every phase recorded in order. It also asserts that files takes at least the time the wire needs.

Phase times measured

PhaseTime
manifest4 ms
files (download)21,391 ms
unpack7 ms
bundles0 ms
key3 ms
open2 ms
boot101 ms

Download is the slowest phase because the wire is the limit. Unpack takes 7 ms after the last part lands, which shows decompression is streamed during the download rather than done afterwards.

Test time

  • The drill takes 21.5 s and the whole test about 25 s, under the 30 s limit.
  • I did not scale size or speed down. Scaling both together leaves the wire time unchanged, and the full-size test already fits.
  • Setup is about 3.5 s and the test needs roughly 1 GB of memory briefly. On a slow machine the margin to 30 s is thin.

Not done

  • Clone time isn't covered: the snapshot has no large repositories, so bundles is 0 ms. The clone phase is untested at this size.
  • The node zstd stream stops after the first frame of a multi-frame input without an error, so the generator writes one frame. The real packer already writes one.

🤖 Generated with Claude Code

commented

A real snapshot restores green through a throttled fake store inside the drill's budget, but the test now runs at 1/4 scale (100 MB at 37.5 Mbit/s), not 400 MB at 150 Mbit/s. It passes locally in 22.7 s. I haven't re-run the forge's check, so that verdict on the new push is still to come.

Why the scale changed: the first push failed the check with ENOSPC. The check's scratch disk filled at about 320 MB while the restore wrote the 400 MB database. I scaled size and speed down together, by 4. The wire time is unchanged, about 21 s, which keeps the test under 30 s, and the restored file on disk is 100 MB.

What the test does (test/drill-400mb.test.ts):

  • It takes a small real snapshot, then swaps its forge.db for a packed one: the snapshot's own database followed by incompressible padding, in one zstd frame. The padding is generated at run time and never kept in the repo.
  • The fake store serves it through one shared link at 37.5 Mbit/s.
  • runDrill and restoreSnapshot run for real; only the side boot is stubbed.
  • It asserts a green verdict and budgetMs == drillBudgetMs(size), which is 700,000 ms (11 min 40 s) at this size. The drill must finish inside that, every phase must be recorded in order, and the download phase must take at least the wire time.

Phase times measured:

PhaseTime
manifest4 ms
files (download)21,437 ms
unpack8 ms
bundles1 ms
key8 ms
open6 ms
boot38 ms

Download is the slowest phase because the wire is the limit; unpack finishes within 8 ms of the last part landing. Nothing in src/snapshot/ needed fixing.

Not covered:

  • Disk write time for a full 400 MB restore. The scratch disk couldn't hold it.
  • Clone time for large repositories, since the test snapshot has none.
  • Type check. bun x tsc --noEmit can't run in my sandbox (read-only tempdir), so the forge's check is the first to run it.

🤖 Generated with Claude Code

Changes requested — before the latest push

The pull is test-only, so there is no page, phone or keyboard surface to judge, and I found no security problem. The miss is that it does not do what the issue and title say. The test restores 100 MB at 37.5 Mbit/s, not a 400 MB snapshot at the forge downlink speed.

The unscaled disk-write phase of a 400 MB restore is never exercised. That phase was the open risk, and the scale-down was made because it hit ENOSPC. The describe name and the header comment still say 400 MB. The budget assertion is 700 s here, not the 1000 s the 400 MB rule gives.

Fix first: make the claim and the proof match.

  • Run the real 400 MB at 150 Mbit/s when the scratch disk has room. Check free space with statfs on tmpdir for about 1 GB and skip the test, by name, when it does not.
  • Alternatively, retitle the test and the header honestly as a 1/4-scale proof, and open an issue for the 400 MB disk-write case.

Smaller points:

  • delete (link as { bounded?: unknown }).bounded has no comment saying why. Explain it or drop it.
  • The wall-clock guard took < 30_000 against a 21 s wire leaves little margin on a loaded runner. Either widen it or drop it, since the drill budget assertion already covers the requirement.
  • The bundles phase is 0 ms, so it is untested at this size. Say so in the header.
commented

test/drill-400mb.test.ts now runs the real 400 MB at 150 Mbit/s wherever the scratch disk has room, and a 1/4-scale run (100 MB at 37.5 Mbit/s) everywhere. Both pass locally, but I haven't re-run the forge's check on this push.

What changed

  • Full run: a real snapshot with a 400 MB packed database goes through the fake store at 150 Mbit/s, and runDrill must finish green inside 16 min 40 s. It runs only if statfsSync(tmpdir()) shows at least 1.5 GB free; otherwise it is skipped and named as skipped. On this machine it ran and passed: files took 21,380 ms, unpack 4 ms, open 3 ms, boot 144 ms.
  • Scaled run: always runs. It checks green, an 11 min 40 s budget (the 400 MB rule at this size), and each phase recorded in order. Its phase times were about the same.
  • Header and titles: both now say which run proves what. They also say that clone time is not proven, because bundles is ~0 ms with no large repository, and that the full-size disk write is only proven where the full run isn't skipped.
  • delete link.bounded: dropped. dirStore has no bounded, so it did nothing.
  • Wall-clock took < 30 s: dropped. The budget assertion covers the requirement, and the wire time is asserted as a lower bound.

Where I deviated

  • Skip on a small disk: I skip the full run there, as asked, and the scaled run still covers the streaming, phases and budget rule. The earlier ENOSPC check disk will skip the full run, so the forge's check won't prove the 400 MB disk write.
  • Test time: each test takes about 22 s, so the file takes about 47 s when both run. The issue's 30 s limit holds per test, not for the file.
  • Type check: still not run. bun x tsc --noEmit can't run in my sandbox, so the forge's check is the first to run it.
  • Follow-up issue: I did not open one for the 400 MB disk-write case, since the full run now covers it where the disk allows.

No phase needed fixing, so src/snapshot/ is untouched. Download is the slowest phase because the wire is the limit.

🤖 Generated with Claude Code

Approved

Test-only change; no page, API, MCP, terminal or dependency surface is touched, so the security, both-doors and README items do not apply. The test is real: it runs runDrill and restoreSnapshot against a throttled store, asserts a green verdict, the size-scaled budget, phase order, and the wire time as a floor on the download. Nothing is left commented out and the scratch dir is removed in afterAll.

Two things I would do next:

  1. The full 400 MB run skips itself when the scratch disk has under 1.5 GB free, and the check disk hit ENOSPC at about 320 MB earlier. So the forge check may only ever run the 1/4-scale proxy. Give the check a bigger scratch disk, or open an issue to prove the 400 MB disk write there, so the title is true in CI and not just locally.
  2. Each test takes about 22 s, so the file takes about 47 s, and the full run holds roughly 1 GB in memory. Build the padded zstd frame once and reuse it, or stream it, to cut setup and the memory peak. The clone-time (bundles) phase is still unproven at size, as the header says; a follow-up issue should cover it.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs