Edge Caching & Rate Limiting
Strum VOD relies on a multi-layer edge caching architecture designed to minimize serverless computing costs (Cloudflare Workers CPU time, Neon Postgres query compute, and Cloudflare R2 Class B read operations) while delivering sub-50ms video and metadata responses globally.
All caching, rate limiting, and HTTP cache header classification logic is centralized in the @strum-vod/edge-cache package.
1. Multi-Layer Architecture Overview
┌─────────────────────────────────────────────────────────────┐
│ Browser / Video Player │
│ • HLS.js video buffer caching │
│ • Hashed static bundles cached permanently (/assets/*) │
└──────────────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Cloudflare CDN & Edge Tier │
│ • Smart Tiered Cache (Origin shielding) │
│ • Cloudflare Cache Rules (media.usestrum.app) │
│ • Native Rate Limiting binding ([[ratelimits]]) │
└──────────────────────────────┬──────────────────────────────┘
│
┌───────────────┴───────────────┐
▼ ▼
┌──────────────────────────────┐ ┌──────────────────────────────┐
│ Cloudflare R2 │ │ apps/api-edge (Worker) │
│ • HLS chunks (immutable) │ │ • caches.default │
│ • Variant / Master .m3u8 │ │ • Proactive cachedBust │
│ • Thumbnails / VTT / SRT │ │ • Fallback Rate Limiter │
└──────────────────────────────┘ └──────────────┬───────────────┘
│ (Cache Miss)
▼
┌──────────────────────────────┐
│ Neon Postgres │
│ • Assets, Renditions, Org │
│ • Jobs, Analytics Daily │
└──────────────────────────────┘2. Shared Package: @strum-vod/edge-cache
The package @strum-vod/edge-cache (packages/edge-cache) provides three unified modules:
1. Response Cache (src/response-cache.ts)
Interacts directly with Cloudflare's native caches.default API:
- Synthetic internal URIs: Uses
https://strum.internal/<kind>/<id>as cache keys to avoid collision with public origin routes. - Fail-open: Any cache read/write issue transparently falls back to the database without throwing a 500 error.
- Proactive invalidation:
cachedBust(kind, id)removes specific cache keys upon database updates or background job completions.
Standard TTL Constants (CACHE_TTL)
| Resource | TTL | Invalidation Trigger |
|---|---|---|
PLAYBACK | 24 hours (86400s) | Asset metadata update, thumbnail change, transcode completion |
HIGHLIGHTS | 1 hour (3600s) | Highlight rendering completion, title/description edits |
COMMENTS | 15 seconds (15s) | New comment posted (absorbs viral comment storms) |
SETTINGS | 5 minutes (300s) | Organization settings / branding updates |
ANALYTICS_HOURLY | 5 minutes (300s) | Hourly cron aggregation |
ANALYTICS_DAILY | 30 minutes (1800s) | Daily cron aggregation |
2. Rate Limiting (src/rate-limit.ts)
Eliminates external Redis KV clusters:
- Production: Uses Cloudflare's native
RATE_LIMITERbinding (c.env.RATE_LIMITER.limit({ key })). - Local Dev / Fallback: Automatically switches to an in-memory sliding window algorithm per isolate with automatic key pruning to prevent memory growth.
3. Media Headers & Cache-Control (src/headers.ts)
Enforces uniform HTTP headers across API endpoints, S3 presigned URLs, and transcode workers:
| File Type / Pattern | MIME Content-Type | Cache-Control Policy |
|---|---|---|
HLS Video Segments (.ts, .m4s) | video/mp2t, video/iso.segment | public, max-age=31536000, immutable |
Direct MP4 Download (download.mp4) | video/mp4 | public, max-age=31536000, immutable |
Variant Playlist (index.m3u8) | application/vnd.apple.mpegurl | public, max-age=86400 |
Master Playlist (master.m3u8) | application/vnd.apple.mpegurl | no-cache, must-revalidate |
Thumbnails (.jpg, .png, .webp) | image/jpeg, image/png, image/webp | public, max-age=604800 (7 days) |
Subtitles & AI metadata (.vtt, .srt, .json) | text/vtt, application/x-subrip, application/json | public, max-age=3600 (1 hour) |
Raw Source Video (sources/*) | video/* | private, no-store |
Static Frontend Bundles (/assets/*, /_astro/*) | application/javascript, text/css, etc. | public, max-age=31536000, immutable |
Root HTML Documents (/*) | text/html | public, max-age=0, must-revalidate |
3. Configuring Cloudflare Cache Rules
To ensure Cloudflare respects these headers and maximizes cache hit ratio on the media domain (media.usestrum.app):
Run the automated setup script:
export CLOUDFLARE_API_TOKEN="your_token_with_zone_rulesets_edit"
export CLOUDFLARE_ZONE_ID="your_zone_id"
./scripts/setup-cloudflare-cache-rules.shThis script:
- Enables Smart Tiered Cache for topology optimization (shielding R2 from redundant origin hits across global datacenters).
- Deploys HTTP Request Cache Rules to force 1-year immutable caching for video segments and bypass caching for
master.m3u8.