Repository navigation
Description
Summary
Offload final SSAT HTML compression from the Fastly Compute guest to Fastly dynamic delivery compression on current main.
The current implementation still compresses assembled HTML in the guest, including cached-template delivery. Streaming and template caching have changed since the original experiment, so the implementation and measurements must use today's paths rather than revive the closed parser-safe streaming stack from #872.
Agreed scope
- Automatically offload eligible Fastly SSAT HTML delivery compression. No new publisher opt-in or configuration flag.
- Preserve existing origin
Accept-Encodingnegotiation. Decode supported gzip, deflate, and Brotli origin responses, process HTML as today, then emit identity output withX-Compress-Hint: on. - Preserve final response framing: no stale
Content-EncodingorContent-Length; retain existingVaryfields and coverAccept-Encoding. - Explicitly declare delivery-compression capability at adapter boundaries. Axum, Cloudflare, and Spin retain current behavior. Fastly dynamic compression supports gzip/Brotli; retain in-guest delivery when reader negotiation selects deflate or fails, without changing origin negotiation.
- Cover current inline streaming, buffered HTML, template-cache miss, warm hit, and assembly fallback delivery without changing parser/EOF behavior, auction timing, or consent gates.
- Preserve current terminal privacy rules, including stricter
no-storepaths. Do not change template admission, stored representations, cache keys, origin readthrough, TTLs, or purge.
Shared EdgeZero mechanism
The P3 extraction work is tracked in IABTechLab/edgezero#362 and implemented in draft EdgeZero #452, created before the consumer migration. Draft Trusted Server #884 now pins its exact published commit 157f091e42b5c584898a5d0f8a0d3ddc3a4dd5ec across six workspace declarations and eight lockfile packages.
EdgeZero owns typed request capability, checked opaque identity-output intent and the pure Fastly finalizer. Trusted Server owns SSAT eligibility, consent/auction gates, origin decoding, output planning, HTML/EOF processing, template neutrality and privacy. The local marker, generic capability/options wrapper and header-finalization helper are removed.
Trusted Server keeps its custom lazy sender and calls the shared finalizer after late effects and privacy enforcement, before consuming response parts. It does not use the standard collecting converter. Neither project enables compression globally or relabels compressed bytes as identity.
Both PRs remain draft for joint review. Merge EdgeZero first, then replace the temporary consumer pin with a merged release before merge-ready. The existing Fastly staging criteria below remain unchanged.
Historical evidence
The July identity-origin plus Fastly delivery-compression experiment measured approximately 44.6 ms versus 9.0 ms guest processing and 47 ms versus 19 ms Fastly vCPU, with Brotli browser delivery. Earlier local fixture measurements also showed decode-to-identity substantially cheaper than mirror recompression.
These measurements justify fresh testing; they are not performance claims for the current output-only implementation.
The former blanket 10 MiB origin-response rationale is stale. Current Fastly adapter materialization checks apply to buffered responses, not its streamed-response branch. Publisher pipeline limits remain separate and unchanged. This scope does not request larger identity bodies from origin.
Acceptance criteria
- Eligible Fastly SSAT HTML selects guest identity output and the Fastly delivery-compression hint automatically, without a publisher flag. Actual platform delivery remains covered by the staging criteria below.
- Origin request encoding negotiation remains unchanged.
- Identity, gzip, deflate, and Brotli inputs produce equivalent decoded rewritten HTML through affected streaming and buffered finalizers.
- Template misses, hits, and assembly fallbacks retain existing template and privacy contracts while selecting offloaded final delivery encoding.
- Non-Fastly, non-SSAT, non-HTML, unsupported encoding, bodyless, redirect, and error paths retain existing behavior.
- Headers, lazy streaming, auction timing/cleanup, byte limits, and terminal privacy have regression coverage.
- Required local adapter tests/lints and repository CI checks pass. Hosted GitHub CI on the updated PR is pending.
- Fresh Fastly staging measurements cover inline, template-miss, and template-hit paths, recording vCPU, TTFB, origin bytes, browser bytes, actual delivery encoding, and decoded HTML equivalence.
- Real Fastly reader negotiation is verified for absent encoding headers, identity-only, supported compressed encodings, and identity-refusing requests. Local/Viceroy results are not presented as proof of dynamic compression.
Out of scope
Identity-origin fetching, new compression flags, new caching behavior, parser-safe streaming/EOF refactors, static asset compression, new retries, and new body-size limits.
Delivery
Draft PR #884 is now a feature-only branch at 85a9b9184a67a9c827be9b59ead95a801fb07faf, rebased onto main 51730bdaf841e4d7bb96c2258e5e98169bdff9a7. It preserves current-main trace, ingress and absolute-deadline behavior. The obsolete parser-stack and merge history are not replayed. The previous 5b663ee2d implementation is superseded and retained in a local backup branch.
Design: SSAT delivery compression. Plan and local verification: EdgeZero consumer integration. Consumer contract checks and independent implementation review found no blockers.
The original db27e738/63c7b63 integration validation passed all 32 Rust/repository gates, including 3,345 native core tests, normal/reusable Fastly aliases, all adapter tests/lints, parity/digest/clock/host checks, actual Fastly/Cloudflare/Spin deadline fixtures and actual Axum plus release-Fastly EOF/auction/prefix controls. JS passed 1,838 tests with one skipped. Documentation formatting/lint/build and script/Node-pin checks passed. Tool versions were Rust 1.98.1, Node 24.20.0 and Viceroy 0.21.0.
Review R1 now uses literal expected Vary fields in the framework test. The consumer pins the resulting exact framework head. Fresh framework native tests, consumer delivery/build-digest tests, formatting and SDK scoped Clippy passed. Review reruns also found both current local Fastly aliases and the SDK contract link-blocked on pending_req_header_insert; verified same-tree hosted runs passed, and the discrepancy remains unresolved. No runtime workaround was introduced. Fresh hosted CI runs on the updated heads.
These local results prove guest behavior, not actual CDN compression or performance. No deployment or merge ran. The two staging criteria above remain open.
Related: #858's historical measurement comments below remain useful background; #894 is a separate specification-only caching PR and is not modified by this work.
CI smoke fixture fix
Framework 157f091e42b5c584898a5d0f8a0d3ddc3a4dd5ec fixes the failed reusable HTTP smoke probe. Delivery contracts had passed 12/12 and Fastly library tests 103/103; uncontrolled origin EOF could race downstream receipt.
The post-commit origin now waits for the existing client first-body-byte signal before closing short. Plain immediate aborts still serve pre-commit fault tests. Status 200, exact partial, interrupted-response type and matching guest error remain mandatory. No sleeps, retries, SDK stubs, trap overrides or runtime changes were added. Cleanup releases waiters after failed probes.
A regression failed before the fix. Final checks pass 2 core + 27 harness tests, formatting, strict Clippy and the full pinned-Viceroy Fastly smoke. All three custom variants observed the required bytes and correlated error. Two independent source investigations/reviews found no blocking issue.
Consumer 85a9b9184a67a9c827be9b59ead95a801fb07faf refreshes all six declarations/eight lock sources. Six delivery tests, ten build-digest tests and formatting pass, with no registry/SDK drift. GitHub's test workflow now passes at 157f091e, including the previously failing Fastly job. Retained CI artifacts confirm 200/partial and matching guest errors for all three custom variants. Both PRs remain draft; consumer CI runs separately.
This does not resolve the separate local debug/WASM loader discrepancy or prove live Fastly negotiation/performance.
Activity
ChristianPavilonis commentedon Jul 9, 2026
Local measurement update from a native release-mode fixture test.
I added an ignored local fixture harness at
crates/trusted-server-core/tests/ssat_compression_fixtures.rs. It reads representative local HTML fixtures, runs them through the existingStreamingPipeline+HtmlProcessor, and verifies that:Command used:
cargo test -p trusted-server-core \ --target aarch64-apple-darwin \ --release \ --test ssat_compression_fixtures \ -- --ignored --nocaptureRepresentative local results:
Local interpretation:
Caveats:
X-Compress-Hint: on.Content-Encoding, transfer size, and Compute vCPU-ms.ChristianPavilonis commentedon Jul 9, 2026
Measurement update from the SSAT compression experiment branch:
Tested the guarded query parameter modes:
?__ts_ssat_compression=identity?__ts_ssat_compression=mirrorObserved headers for
identitymode:Observed headers for
mirrormode:Initial finding:
identitymode is materially better for Compute-side processing on this page:identityis about 5x faster)content-encoding: br) via Fastly dynamic compressionx-ts-ssat-processed-bytesis larger inidentitymode because it measures the uncompressed body handled by the guest before Fastly delivery compression. It does not represent final wire size.Also noted:
x-compress-hintwas not visible in the browser response, but the response had:So Fastly delivery compression appears to have been applied successfully despite the control hint not being exposed back to the client.
ChristianPavilonis commentedon Jul 9, 2026
Final decision: proceed with compression offload as a publisher-level Fastly opt-in, not as the global default yet.
PR: #884
The implementation adds:
When enabled on Fastly and the existing SSAT eligibility gates pass, Trusted Server requests
Accept-Encoding: identity, emits processed identity HTML withX-Compress-Hint: on, and lets Fastly dynamically compress delivery. Origins that ignore the identity request and return gzip, deflate, or Brotli are decoded safely to identity output.Axum, Cloudflare, and Spin explicitly declare the capability unavailable and keep the current mirrored compression behavior. The feature defaults to
falseeverywhere.Rationale:
The PR removes the temporary measurement query parameters and diagnostic headers; those findings remain recorded in this issue.
[-]Measure and offload SSAT HTML compression from the Compute guest[/-][+]Offload Fastly SSAT delivery compression from the Compute guest[/+]Refresh Fastly SSAT delivery compression