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
Public sites perf · Phase 3: optional, vendor-neutral edge cache / CDN support #73
Part of the public-site performance plan (master issue linked above). Depends on Phase 2.
Goal
Let any HTTP cache or CDN sit in front of apps/sites using standard headers only. It stays optional and vendor-neutral, so it works for self-hosters. Correct delivery never depends on it, because Layer 1 (Phase 2) does the real caching.
Emit headers per mode. Compute tags in apps/sites/proxy.ts from the URL path (t:<team>, t:<team>:docs, t:<team>:page:<path>, ...) and confirm they survive the rewrite. Browser Cache-Control stays max-age=0, must-revalidate.
Never edge-cache/help/tickets/*, chat, search, form APIs, previews, or the webhook routes.
Purge adapter interfacepurge(tags[]), with a generic http adapter: a signed POST of { tags } to EDGE_PURGE_URL with EDGE_PURGE_SECRET.
Outbox destination for edge purges, with retries and acknowledgments. Order: Layer 1 revalidateTag → edge purge → a second edge purge about 10 seconds later (catches renders that were already in progress).
Sensitive-data purge events count as complete only after the edge purge is acknowledged.
RSC / _rsc check: the cache key must include the query string so HTML and RSC payloads are never mixed up. Test client-side navigation behind a CDN that ignores Vary.
Optional ASSET_PREFIX for serving _next/static from a separate host.
Optional self-hosted recipe: Caddy (TLS, unchanged) → Varnish with xkey → apps/sites, wired through the http adapter. Documented and opt-in, not part of the default stack.
Docs: configuration reference for the EDGE_* variables.
Done when
ttl mode works behind an unmodified CDN or proxy.
purge mode with the Varnish recipe shows a publish within a few seconds.
Implemented in #144 (stacked on #143). The done-when checks:
ttl mode behind an unmodified proxy: with EDGE_CACHE_TTL=5 and no purge integration, publishes appear after 5.0–5.1 s.
purge mode with the Varnish recipe: a publish is visible at the edge in 0.20–0.54 s. Purges are scoped by tag, retried if the receiver is down, and repeated after 10 s.
Client navigation stays correct behind Varnish, both with Vary honored and with Vary stripped. Testing with Vary stripped found an RSC cache-poisoning case: a single rsc-header request could get a redirect cached at the page URL. It's fixed and retested.
Through Varnish: 4.9k–7.4k req/s at p50 1 ms, vs 140–242 req/s at the origin.
Activity
clbotdev commentedon Oct 25, 2026
Implemented in #144 (stacked on #143). The done-when checks:
ttlmode behind an unmodified proxy: withEDGE_CACHE_TTL=5and no purge integration, publishes appear after 5.0–5.1 s.purgemode with the Varnish recipe: a publish is visible at the edge in 0.20–0.54 s. Purges are scoped by tag, retried if the receiver is down, and repeated after 10 s.rsc-header request could get a redirect cached at the page URL. It's fixed and retested.Through Varnish: 4.9k–7.4k req/s at p50 1 ms, vs 140–242 req/s at the origin.
Merge pull request #144 from codelitdev/perf/sites-edge-cache