Designing Metered Paywalls for Video: Entitlement Architecture That Doesn't Leak or Lag
How metering, entitlements, and preview-window systems work under the hood — token design, edge enforcement, and the race conditions that let determined users past soft paywalls.
A video paywall is a distributed systems problem: entitlement state lives in a database, enforcement happens at a CDN edge, and the user is actively adversarial. Every design choice between those three points creates either leaks (free access you didn’t intend) or friction (paying users who can’t watch).
The Three Enforcement Points
| Layer | What It Enforces | Strength | Weakness |
|---|---|---|---|
| Client (UI) | Hides the play button | None — cosmetic only | Trivially bypassed |
| API / Application | Gates metadata & manifest URLs | Good | Adds request latency |
| Edge (CDN worker) | Validates signed playback tokens | Strongest — media itself is gated | Requires careful token design |
The only enforcement that matters for video is edge-level: if the manifest and media segments are served to anyone with the URL, the paywall doesn’t exist — only an obscured link does.
Tokenized Entitlement Flow
[User] ──login──> [Auth Service]
│
▼ (issues short-lived JWT: user_id, entitlements, exp=5min)
[Player] ──JWT──> [Edge Worker]
│ verifies signature, checks entitlement claim
▼
[Signed manifest URL w/ HMAC, exp=4h]
│
▼
[CDN serves segments while HMAC valid]
The Race Conditions That Leak Paywalls
- Meter increment vs. entitlement check: if the free-view counter increments asynchronously (to keep latency low), rapid parallel requests let users exhaust N views in the same tick — a classic check-then-act race. Fix: atomic increment at the edge (increment-and-check in one operation).
- URL forwarding: signed manifest URLs are bearer credentials. If a free-trial URL can be shared to a Discord server, your metering means nothing. Mitigate by binding tokens to a rolling session fingerprint rather than a static IP.
- Preview window overflows: “watch 30 seconds free” previews that cut at the player are cosmetic — the full stream already downloaded. Enforce preview length by issuing a manifest that physically ends at 30s.
“Every paywall leak we’ve audited came from enforcing at the wrong layer. If the media URL works in curl, it’s not a paywall — it’s a suggestion.”
Metering Storage That Scales
Per-user counters belong in the fastest storage you have at the edge — Workers KV, Redis, or durable objects — not your Postgres primary. Accept eventual consistency for meter reads (a user might get one extra free view); never accept it for entitlement checks (a paying user must never see a paywall).
The full token schemas, edge verification code, and leak-audit checklist are documented in our paywall and entitlement system design notes.