Skip to content

PPR fast path: emit stored snapshot fragments verbatim into the HIT payload (stop re-serializing baked segments per request) #700

Closed

Description

@ivogt

Problem (measured 2026-07-06, hec homepage)

On a shell HIT, the fast path replays the snapshot segments but still runs a full Flight serialization of the entire tree to build the inline hydration payload (__FLIGHT_DATA), and the SSR side then consumes that same stream again for the resume render. Measured on a 3.77MB storefront homepage: 1.09MB of __FLIGHT_DATA per request (245 chunks), verified to duplicate content already served from the stored prelude ("SPF pays off" hero et al. present in both). At the measured ~5MB/s workerd stream-generation throughput, this is roughly 200–300ms of per-request CPU whose output bytes are constant for the lifetime of the entry — the tax scales with page weight, not dynamism, inverting the fast-path promise. It also burns isolate CPU that competes with concurrent renders (the 2.5s PDP-prefetch starvation class).

Fix shape (the design doc's deferred "fragment splice")

The entry's snapshot already stores per-segment RSC-encoded fragments — the serialization work is already done at capture time (a waitUntil job, off the request path). The HIT payload assembly should:

  1. Emit the stored fragment strings verbatim (string copy) for replayed segments instead of deserialize → re-serialize;
  2. Serialize fresh only: loader rows, per-request metadata rows (nonce, pathname, params), handle records;
  3. Expand fragments on the consumer side through the same deserializeResult path the client cache seed already uses (per-record fragments have an in-tree precedent — segment-codec serializeResult/deserializeResult).

Segment-boundary fragments avoid the known raw Flight-row-surgery hazard (row-id collisions / shared-row dedupe) — each fragment is its own row space, deserialized independently, exactly like the seed.

Constraints / notes

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions