Skip to content

feat(garage): /garage/dictionary, the dictionary the runtime dropped - #927

Merged
oddharsh merged 2 commits into
mainfrom
claude/garage-zstd-dictionary
Sep 25, 2026
Merged

oddharsh merged 2 commits into
mainfrom
claude/garage-zstd-dictionary

Conversation

@oddharsh

Copy link
Copy Markdown
Owner

Adds /garage/dictionary, a write-up of what cloudflare/workerd#7106 is worth to this site once it ships.

Most pages here reach a returning Chromium visitor as a dcz delta the build computed. The pages the Worker renders per request ship as plain brotli, because workerd's node:zlib zstd accepted a dictionary option and dropped it. Measured against production on 2026-09-25, 51 of 66 registered pages answered dcz and 15 answered br. Two of the 15 (/whoareyou, /garage/dyno) move to a baked shell with #924 and #926, so the page describes the 13 that remain.

What the page claims

  • At zstd level 6 the 13 pages drop from 81,228 to 63,449 bytes, 21.9% off the brotli the edge sends today.
  • Each page saves 1,178 to 1,672 bytes across a sixfold range in page size. The delta removes the shell every page shares, so utility pages lose 36 to 39% and /reading loses 9%.
  • Level 6 costs a median 0.165 ms per page under Node 26.9 on an M3 Max. Level 19 buys 3.9 more points for up to 9.9 ms, the whole Workers Free allowance.
  • The fix can't reach fetch() fragments: the family dictionary is offered for match-dest=("document") only.
  • The baked-shell route from feat(whoareyou): build the page at deploy, fetch its values as an island #924 and feat(dyno): build the page at deploy, fetch its chart as an island #926 gets the shell delta today with no workerd release, at the cost of a second request and a placeholder. The page weighs the two against each other.

The page runs a live demo that fetches itself a second time. A fetch() has destination empty, so the gap between its encodedBodySize and the navigation's is the dictionary's effect on that visitor, measured in their own browser.

What else changed

  • tools/runtime-dcz-probe.ts produces every number on the page. It reads production, writes nothing, and runs under node (node tools/runtime-dcz-probe.ts), because the timing is node:zlib's own zstdCompressSync.
  • pipelines/garage/README.md now lists bun run gen:shell. The checklist skipped it, and the build refuses a new page without it.
  • docs/COMPRESSION-STUDY.md gains a short section on Worker-rendered documents, next to its fragment measurements.
  • The usual projection churn: nav-run.js (a hashed asset, so this remints /a/nav-run.*), the desktop partial in 42 pages (the garage pin count goes 25 to 26), and the shell/desktop derivation lock.

Checked

bun run build, lint, typecheck, pages:check, and test (917 pass) all pass on the branch rebased onto 7eab1534. I viewed the page under bun run dev at desktop and 375px widths, with no console errors and no horizontal overflow. The demo takes its no-dictionary branch locally, as expected, since dev serves no deltas.

Owed after deploy

The OG card. gen-og-cards.ts captures production, so it can't be made before the page exists there.

15 of the 66 registered pages answer returning Chromium visitors with plain
brotli instead of a dcz delta, because the Worker renders them per request and
workerd's node:zlib zstd dropped its dictionary option. The page measures what
cloudflare/workerd#7106 would be worth once it ships: 97,711 to 76,557 bytes
(21.6%) at zstd level 6, a near constant 1,178 to 1,694 bytes per page because
the delta removes the shared shell, for a median 0.207 ms of CPU under Node.
It also says what the fix cannot reach (fetch() fragments), and runs a live
demo that fetches the page a second time to show the dictionary's effect.

tools/runtime-dcz-probe.ts produces every number on the page and writes
nothing. The garage README now lists gen:shell, which the checklist skipped
and the build requires.
…he baked-shell route

/whoareyou and /garage/dyno moved to a shell baked at build time while this
page was being written, so production's 15 brotli pages become 13 once that
release finishes ramping. Totals, the chart and the card now describe the 13
(81,228 to 63,449 bytes, 21.9% at level 6), and a new section sets the
baked-shell route against the runtime fix.
@github-actions github-actions Bot added area: content Authored documents and prose area: docs Runbooks and repository prose area: garage The garage pages and the cf-garage Worker area: infra Declared Cloudflare state, wrangler config, pins area: lwe The LWE pages and the lwe-ask Worker area: shell Client islands, stylesheets, the Luna system area: tools Developer tooling and the contract suite area: worker The site Worker: routing, rendering, bindings hashed-asset Remints an /a/ URL, so every page and page dictionary rebuilds type: feat New capability or surface labels Sep 25, 2026
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
aadhar-sh 5bafde2 Sep 25 2026, 06:36 PM

@github-actions

Copy link
Copy Markdown
Contributor

Wire-size diff vs merge base

7eab153413e6435e4667c604933bc0a4a26e2030 → 3676cbd42643c559f59386022f4cc58e46f61066

Brotli q11, the quality the edge serves. Every number here is deterministic:
an unchanged file produces no row. Advisory — this check fails on nothing.

Client assets

Total Brotli: 91.57 KiB → 91.60 KiB (+0.03 KiB, +0.0%) across 27 files, 2 changed.

file base head Δ
nav-run.js 5.40 KiB 5.43 KiB +0.03 KiB (+0.5%)
nav.js 5.63 KiB 5.63 KiB -0.00 KiB (-0.0%)

Pages

Total Brotli: 600.01 KiB → 608.75 KiB (+8.75 KiB, +1.5%) across 60 files, 54 changed.

file base head Δ
garage/dictionary.html — 8.41 KiB new
garage/index.html 12.16 KiB 12.45 KiB +0.29 KiB (+2.3%)

Plus 52 files under the 0.13 KiB floor, net +0.06 KiB — usually content-hash churn in /a/ references, counted in the total above.

Worker bundle

257.40 KiB → 257.53 KiB gzip (+0.13 KiB, +0.1%)

Largest module deltas (raw bytes in bundle):

file base head Δ
.build/src/worker/lib/site-manifest.ts 12.46 KiB 12.77 KiB +0.30 KiB (+2.4%)
.build/src/worker/lib/csp-hashes.ts 6.74 KiB 6.86 KiB +0.11 KiB (+1.7%)
.build/src/worker/lib/twins.ts 0.91 KiB 0.93 KiB +0.02 KiB (+2.3%)

Dictionary transport

Family dictionary acquisition: no change, 14.41 KiB q11.

pd/: 171 → 172 deltas, 498.73 KiB → 507.41 KiB (+8.67 KiB).

@oddharsh
oddharsh enabled auto-merge (squash) September 25, 2026 18:38
@oddharsh
oddharsh merged commit 3c49ec7 into main Sep 25, 2026
15 checks passed
@oddharsh
oddharsh deleted the claude/garage-zstd-dictionary branch September 25, 2026 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: content Authored documents and prose area: docs Runbooks and repository prose area: garage The garage pages and the cf-garage Worker area: infra Declared Cloudflare state, wrangler config, pins area: lwe The LWE pages and the lwe-ask Worker area: shell Client islands, stylesheets, the Luna system area: tools Developer tooling and the contract suite area: worker The site Worker: routing, rendering, bindings hashed-asset Remints an /a/ URL, so every page and page dictionary rebuilds type: feat New capability or surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant