You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 0a62f5c
Browse filesBrowse the repository at this point in the historyBrowse files
docs(compression): node 26 gave brotli a dictionary, so retire that limit (#305)
Gotcha 14 said `node:zlib`'s brotli has NO dictionary parameter, listed the
nine params as the whole list, and rested part of the dcz-over-dcb case on dcb
needing the `brotli` CLI back in the build path. Node 26 takes a `dictionary`
option (nodejs/node#61763, merged 2026-02-13) and `.node-version` is already
26, so CI has it too. Measured on v26.7.0, q11 over a 21KB target: 70 bytes
with no dictionary against 18 with one.
The CONCLUSION is untouched, because dcz won on decode and neither encoder's
availability was ever the axis. What changed is one of the stated reasons.
Four copies of the claim moved together, per gotcha 18's own lesson about
grepping the tree when a note lands: CLAUDE.md twice, the build.mjs comment at
the delta emitter, the roll-shell-dictionary.mjs header, and /garage/compression,
which carried it in prose AND in an understanding-check explanation.
While in that page, its dcz-vs-dcb table still held the pre-correction figures
(79 vs 80 bytes, "about twice as fast"). The 2026-07-28 re-measure against real
dictionaries never reached it: dcb is 245 bytes ahead across all 12 pairs (6.8%,
winning 11 of 12) and dcz decodes 8.3x faster, not 2x. Both inputs to the
original argument were wrong, in opposite directions, and the call survived on
the structural point instead: decode scales with the RECONSTRUCTION, not the
delta, so a smaller dcb delta never shrinks the decode gap. The quiz's correct
answer restated the old figures verbatim and now states that.
Adds one general rule, since three runtimes disagree on this single option:
probe dictionary support, never infer it. node 26 honours it, workerd accepts
it for zstd and silently ignores it, and bun does the same through 1.3.14 with
the fix landing in oven-sh/bun#34427 (unreleased; verified on 1.4.0-canary.1).
The failure is silent every time, because a frame compressed WITHOUT the
dictionary still decodes fine WITH it, so the only signal is a byte count that
never shrank.
Co-authored-by: Aadharsh Pannirselvam <19518661+oddharsh@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
so on v26.7.0 a quality-11 compress of a 21 KB target goes from 70 bytes with no dictionary
453
+
to 18 with one. The limit I over-generalized was accurate about brotli the day I wrote it
454
+
and is now accurate about neither encoder. So a runtime limit has a shelf life, and the
455
+
version you measured on belongs in the note next to the measurement.
456
+
</p>
436
457
437
458
<h2>What shipped</h2>
438
459
<tableclass="cmp">
@@ -511,17 +532,17 @@ <h2>The part that transfers</h2>
511
532
"q": "The deltas ship as dcz even though brotli measured smaller. Why?",
512
533
"options": [
513
534
{
514
-
"t": "zstd decodes about 2x faster, and on the pair this site actually ships brotli's advantage was one byte.",
535
+
"t": "Decode scales with the reconstruction rather than the delta, so brotli's smaller delta never shrinks zstd's 8.3x decode lead.",
515
536
"ok": true,
516
-
"why": "Bytes are a proxy for latency. The 5-8% brotli edge only shows up on deltas far larger than a shell asset produces, while the decode gap grows on slow CPUs."
537
+
"why": "Re-measured against real dictionaries, dcb is 245 bytes (6.8%) ahead across all 12 pairs, and dcz still wins: rebuilding 47,615 bytes costs 0.0165 ms against 0.1368. Break-even at 9 Mbps needs ~135 bytes saved per asset and dcb saves 44."
517
538
},
518
539
{
519
540
"t": "Cloudflare only passes dcz through; dcb is not supported at the edge.",
520
541
"why": "Both are passed through identically, on all plans. That is exactly why the choice was free to make on engineering grounds."
521
542
},
522
543
{
523
544
"t": "Because brotli cannot use a custom dictionary, so dcb was never actually available.",
524
-
"why": "Brotli does custom dictionaries fine via its CLI. What it lacks is a dictionary option in Node's zlib, which is a tooling gap rather than a format limit."
545
+
"why": "Brotli does custom dictionaries fine. What it lacked was a dictionary option in Node's zlib, which was a tooling gap rather than a format limit, and node 26 closed even that."
0 commit comments