Skip to content

Production Hardening

The defaults in this repo’s wrangler.json are tuned for the bundled demo — ALLOWED_ORIGINS = "*", no caller allowlist, no quality cap. Useful for “paste any URL” exploration; wrong for anything you’ll link to publicly.

This page is a one-stop checklist. If you skip the docs and only do these five things, your Worker stays cheap and your bill stays predictable.

ALLOWED_ORIGINS controls which upstream URLs the Worker can fetch from. The demo uses "*" so the playground works for any pasted URL — that makes the Worker an open proxy. Replace with a curated comma-separated list:

"ALLOWED_ORIGINS": "https://cdn.yoursite.com,https://images.unsplash.com"

Path-relative requests (?url=/photo.jpg) are always fetched from ORIGIN and don’t depend on this list — but every absolute https:// URL must match.

2. Set ALLOWED_REFERERS (caller allowlist)

Section titled “2. Set ALLOWED_REFERERS (caller allowlist)”

ALLOWED_ORIGINS controls what we fetch. ALLOWED_REFERERS controls who can call us. Without it, anyone on the internet can hit your Worker URL and you pay the CPU.

"ALLOWED_REFERERS": "https://yoursite.com,https://www.yoursite.com"

Behavior:

  • Unset: any caller allowed (demo behavior).
  • Set: requests with a non-matching Referer (or Origin) header get 403 Forbidden referer.
  • Same-origin is always allowed — the Worker can serve its own bundled demo / static assets without you adding the Worker URL to the list.
  • Missing Referer is rejected when this is set. Browsers typically send a Referer for <img> requests; if your traffic comes through a strict Referrer-Policy: no-referrer header, leave ALLOWED_REFERERS unset and rely on rate-limiting + spend caps instead.

A caller can request ?q=100 and force expensive encodes. Cap it:

"MAX_QUALITY": "85"

Quality 85 is visually indistinguishable from 100 for typical web photos and encodes meaningfully faster (especially for AVIF). Values above the cap are silently clamped — the loader’s emitted srcSet keeps working without errors.

DISABLED_FORMATS lets you trade quality for cost without redeploying. It’s a comma-separated list (recognized: jpeg, png, webp, avif, gif, svg). The biggest CPU win is dropping AVIF:

"DISABLED_FORMATS": "avif"

The negotiator then picks WebP for AVIF-capable browsers — about 60–80% of AVIF’s compression gains at a fraction of the encode cost. Re-enable later by removing it from the list in the Cloudflare dashboard. You can also drop passthrough surfaces — DISABLED_FORMATS="svg,gif" rejects SVG and animated GIF inputs with 415.

5. Set platform-level guardrails (Cloudflare dashboard)

Section titled “5. Set platform-level guardrails (Cloudflare dashboard)”

These are not edgesharp settings — they’re Cloudflare features you should turn on for any public Worker:

  • Workers spend cap alert — emails you when monthly Worker spend crosses a threshold. Set this before you make the URL public. The first time you’ll need it is exactly the time you can’t predict.

  • Rate Limiting on /_next/image — e.g., 100 requests/min per IP. The CPU cost of a single cold transform is small; the cost of a thousand of them in a minute isn’t.

  • Bot Fight Mode — included on the Free plan. Catches the obvious abuse patterns without per-rule configuration.

  • R2 lifecycle rule — bound your L2 cache size. 30-day expiration is reasonable for a CDN cache:

    Terminal window
    npx wrangler r2 bucket lifecycle set edgesharp-cache \
    --rule '{"id":"expire-30d","enabled":true,"conditions":{"prefix":"v1/"},"expiration":{"days":30}}'
{
"name": "edgesharp",
"main": "src/worker.ts",
"compatibility_date": "2026-03-28",
"vars": {
"ORIGIN": "https://yoursite.com",
"ALLOWED_ORIGINS": "https://cdn.yoursite.com",
"ALLOWED_REFERERS": "https://yoursite.com,https://www.yoursite.com",
"MAX_QUALITY": "85"
}
// ...assets, durable_objects, r2_buckets, rules, migrations
}

That config + the platform-level items above is what stands between “demo I shared with my team” and “Worker I forgot about that ran up a bill when an AI crawler discovered it.”

  • Authenticated abuse — if a caller can make the right Referer header (server-side requests, Postman), the allowlist doesn’t stop them. Pair with rate-limiting on the platform layer.
  • Compromised allowed origins — if cdn.yoursite.com is XSS’d or hijacked, the Worker will fetch whatever’s there. Image content-type validation is enforced (no SVG, no executables) but compromised images can still cost CPU.
  • Workers Free plan ceiling — 100k requests/day is shared across all Workers on the account. A surge can exceed it; the spend cap alert is what tells you it’s happening.