Hasty Briefsbeta

Bilingual

Aggressive caching for a Mastodon reverse proxy: what to cache, what to never cache, and why content negotiation will eventually betray you

a day ago
  • Mastodon serves different content (HTML, ActivityPub JSON, API JSON) for the same URL based on the Accept header, requiring careful cache key normalization.
  • The cache key must include a normalized variant of the Accept header to prevent serving the wrong content type to clients.
  • Key assumptions: AUTHORIZED_FETCH disabled, no signed URLs, federation uses HTTP Signatures (not Authorization header).
  • Bypass cache logic is decomposed into small orthogonal maps for method, authorization, cookie, and URI patterns.
  • Short TTLs (10–30 seconds) are used for dynamic public endpoints, while immutable assets have TTLs of days.
  • proxy_cache_lock prevents thundering herds, and proxy_cache_use_stale enables stale-while-revalidate for static assets.
  • The Vary header from upstream is ignored, and the proxy takes full responsibility for correct content negotiation.
  • Logging includes cache status and variant bucket to verify behavior in production.
  • Caveats include: short TTLs cost CPU, stale-while-revalidate can hide problems, AUTHORIZED_FETCH changes caching rules, and Set-Cookie responses must never be cached.
  • The main goal is to reduce requests reaching Puma/Rails by absorbing repetitive public traffic at the proxy layer.