Skip to content

Dev server: deferRegistry grows unboundedly across requests #144

Description

@uhyo

Problem

deferRegistry (packages/static/src/rsc/defer.tsx) is a module-level singleton in the RSC environment. In dev, every HTML render calls defer() with fresh crypto.randomUUID() IDs and registers new entries, but entries are never evicted:

  • pending entries retain the React element,
  • loaded entries retain the entire rendered payload string via drainPromise.

Over a long dev session (many page loads / HMR-triggered re-renders), memory grows without bound. The registry only resets when the RSC module itself is reloaded by HMR. Production builds are unaffected (the process exits after the build).

Suggested fix

Scope or expire dev registrations, e.g.:

  • attach a timestamp and evict entries older than some TTL after they reach ready/error, or
  • track registrations per HTML render and drop the previous generation's entries when a new top-level render for the same entry begins (keeping a short grace period so in-flight client fetches still resolve).

Found during a framework audit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions