Menu
Docs/CDN Setup

CDN Setup

SnapSharp emits CDN-friendly cache headers on screenshot endpoints. When a response is served from the Redis cache, you can let Cloudflare, BunnyCDN, Fastly, or any standards-compliant CDN cache it at the edge — eliminating origin egress and dropping p99 latency for popular URLs to the time it takes to hit your nearest PoP.

How it works

On every /v1/screenshot response we set:

HeaderWhenValue
Cache-ControlCache HIT (Redis)public, s-maxage=<ttl>, stale-while-revalidate=86400
Cache-ControlCache MISSprivate, no-cache
Cache-Control4xx / 5xx errorsno-store (set by errorHandler)
VaryCache HITAccept
X-CacheAlwaysHIT or MISS
X-EdgeAlwaysorigin (or cf-<colo> / bunny-<region> if SnapSharp serves through a CDN)

s-maxage matches the cache_ttl query parameter you sent (default 3600, max 86400). stale-while-revalidate=86400 lets edges keep serving the cached byte stream for up to 24h after expiry while asynchronously refreshing in the background.

We deliberately mark MISS responses private, no-cache. A cache miss is the byte stream of the screenshot we just rendered for your request — it may include cookies, JS injection, custom CSS, dark mode, etc. We let the next identical request find it in Redis on the next request and tag that response as cacheable.

Errors (auth failures, plan gates, SSRF, timeouts) are never cached.

EndpointRecommended s-maxageNotes
/v1/screenshot3600 (1h)Matches default Redis TTL. Bump higher for static marketing sites.
/v1/og-image3600 (1h)OG cards rarely change. 86400 is fine for production.
/v1/extract300 (5m)Page metadata can change frequently after deploys.
/v1/diff0 (do not cache)Diff results are pair-specific and short-lived.
/v1/site-audit0 (do not cache)Audit results are user-specific and reported once.

Cloudflare

Put cdn.snapsharp.dev (or your own domain) in front of api.snapsharp.dev and add a single Cache Rule:

  1. Match: Hostname equals cdn.example.com AND URI Path starts with /v1/screenshot
  2. Action: Cache eligibility: Eligible for cache
  3. Cache key: Include all query string parameters (do not strip cache_ttl etc — they affect the rendered output)
  4. Edge TTL: Respect origin Cache-Control (recommended) or set a hard cap
  5. Browser TTL: Respect origin so users see the same Cache-Control

Optional: enable Tiered Cache so the request hops through your regional cache before reaching SnapSharp's origin. With tiered cache + SWR, popular URLs see one origin hit per hour globally.

The repo includes a starter declarative config in infra-cf-cache-rules.json that you can adapt for the Cloudflare Rules API or Terraform.

BunnyCDN

Create a Pull Zone backed by https://api.snapsharp.dev:

  1. Origin URL: https://api.snapsharp.dev
  2. Cache settings → Use Cache-Control headers: On (this is the important toggle — it makes Bunny honor our s-maxage)
  3. Cache settings → Vary cache by query string: On
  4. Cache settings → Cache error responses: Off
  5. Edge rules: optional — strip Authorization from the cache key (the Redis cache is per-URL+params, not per-API-key, so two API keys asking for the same screenshot get the same bytes).

Test with curl -I https://your-zone.b-cdn.net/v1/screenshot?url=...&token=... and watch X-Cache: HIT flip after the first request.

Verifying it works

After fronting SnapSharp with a CDN, verify the headers from a client:

curl -sI 'https://cdn.example.com/v1/screenshot?url=https://example.com&token=YOUR_KEY' \
  | grep -iE 'cache-control|x-cache|x-edge|vary'

You should see:

Cache-Control: public, s-maxage=3600, stale-while-revalidate=86400
Vary: Accept
X-Cache: HIT
X-Edge: origin

Hit the URL twice in a row — the second response should land at your CDN edge before reaching SnapSharp at all. Most CDNs add their own cf-cache-status or cdn-cache header so you can tell.

Putting your own CDN in front of your SnapSharp account

You don't need an enterprise plan to use a CDN — any plan can. Just point your CDN at https://api.snapsharp.dev and add your API key as a query param (?token=...) or a static origin header. The cache headers we emit work transparently for any HTTP cache that respects Cache-Control: public.

Caveats:

  • If you want a per-user custom cdn.yourdomain.com mapped to SnapSharp with a SAN cert, that's an enterprise feature — contact us.
  • Real-time invalidation across edges (push API) is on the roadmap; today you wait out the TTL or call your CDN's purge API.

Custom domains for enterprise

Enterprise customers can run on their own domain (e.g. screenshots.yourbrand.com) with a SnapSharp-managed cert and a private edge IP pool. See enterprise docs (coming soon) or contact sales.

CDN Setup