Cache purge API
A cache purge API lets a paying customer force a specific thumbnail to be re-resolved when the underlying video’s poster changes. This feature is planned — it is designed here but not built.
Behavior
Section titled “Behavior”A paying customer requests a purge for one of their video IDs. Vumbnail invalidates the cached clean and watermarked variants for that ID (edge cache and R2), so the next request re-resolves the current poster from the provider and re-populates the caches. The purge is scoped to IDs the customer is entitled to.
Inputs & outputs
Section titled “Inputs & outputs”Inputs (proposed): an authenticated paid request (API key) naming one or more video IDs (or a playlist) to purge.
Outputs (proposed): a confirmation that the named variants were invalidated, and a count of objects purged.
States & edge cases
Section titled “States & edge cases”- Not a paying customer — purge is rejected; this is a paid-only capability.
- Unknown / never-cached ID — treated as a no-op success (nothing to purge).
- Negative-cached ID — the negative record is cleared so a recovered video can resolve again.
- Rate limiting / abuse — purge must be bounded so it can’t be used to force expensive re-resolution at scale; the limit is undecided.
- Partial failure — if edge invalidation succeeds but R2 deletion fails (or vice versa), the response must report partial success rather than claim a full purge.
Cost-safe purging model
Section titled “Cost-safe purging model”Every purge — customer-requested or operational (for example, a watermark flip) — runs under the same cost-safety model. On this platform there are exactly two ways a purge produces a surprise bill: purging faster than the edge snippet has propagated, or purging a URL that isn’t covered by the HOT list, so the miss lands on the worker instead of a cached redirect. The model below closes both. The full procedure lives in the cost-safe cache purging runbook.
Sequencing: purge last
Section titled “Sequencing: purge last”A purge is always the last step of a rollout, never a lever to force one:
- Snippet live — the edge snippet release is deployed.
- Propagated — confirmed at multiple colos, not just one.
- IDs HOT — every id being purged has 100% HOT coverage.
- Cohort removed — the affected host is out of the worker referrer cohort in the same release, so the worker can’t re-pin the old variant on miss.
- Smoke green — post-deploy smoke checks pass.
- Then trickle-purge.
Purging earlier in the sequence doesn’t speed anything up — it just re-warms the cache with the state you were trying to leave.
Trickle rate and per-wave caps
Section titled “Trickle rate and per-wave caps”Purges run as a slow trickle of 20–30 URLs per minute, in waves capped by the host’s volume tier: 50 / 25 / 15 / 5 URLs per wave, smallest caps for the highest-volume tiers. Planned — the batch purge wrapper that enforces these caps is designed but not built; the current purge tool is single-URL and uncapped, so no wave runs until the wrapper exists.
Fail-closed pre-wave cost gate
Section titled “Fail-closed pre-wave cost gate”Before each wave, a cost gate (Planned) estimates the wave’s exposure and refuses to run unless all three ceilings hold:
- ~$0.25 re-warm cost for the wave,
- ~$0.10/month permanent (recurring) cost added,
- ~$1.00 total program cost.
The gate is fail-closed: if cache-busting data for the wave is missing, it refuses rather than assumes zero. This matters because Cloudflare has no hard spend cap — billing alerts only, with roughly a 24-hour lag — so every real brake here is self-built.
Kill action
Section titled “Kill action”If a wave misbehaves, the kill action is: stop the purge and back the host off in the worker cohort. Disabling the snippet is not a brake — cached redirects are what keep requests off the worker, so snippet-disable increases cost. Run correctly, the program nets out as a monthly savings, because redirects served from cache skip the worker entirely (illustrative blended worker rate: ~$1 per 1M requests).
Data shape
Section titled “Data shape”// Proposedtype PurgeRequest = { videoIds: string[] variants?: ("clean" | "wm")[] // default: both}
type PurgeResult = { requested: number purged: number notFound: string[] failed: { videoId: string; reason: string }[]}Open questions
Section titled “Open questions”- Contract & auth surface. Is purge a path (
/<id>/purge), a separate endpoint, or part of a future account API? API-key only, or dashboard too? - Rate limits and cost. What per-customer purge budget prevents abuse while staying useful? Operational purges already run under the cost-safe model above; the customer-facing budget is undecided.
- Priority. Rated a medium-value “support and trust” multiplier rather than a direct revenue unlock; sequenced accordingly on the roadmap. See the global Open questions.