CDN and caching

How Szum's CDN serves cached charts quickly – and why cache hits are free.

Szum's public chart-delivery GET endpoints are CDN-cached. The reason that matters is latency: a cache hit avoids origin work such as rendering an image or preparing an embed response. An origin render is generally needed only on the first request to each active cache location after expiry, but the exact count depends on traffic geography and cache behavior.

Cost-wise, only renders are billed, and only on cache misses. A CDN cache hit on /c/{id} or /e/{id} is served entirely from the edge, never reaches Szum, and costs nothing – there is no separate per-view charge.

What each cache hit costs your plan

EndpointCache hitCache miss
GET /c/{id} (saved image)free+1 render
GET /e/{id} (interactive embed)free+1 render

Example. For a chart embedded in an article seen 2M times in a month, requests that reuse the same URL can be served from cache instead of rerendering at origin. Billed renders scale with cache misses rather than raw page views, so they usually grow much more slowly than the audience. The exact total depends on active cache locations, expiry, revalidation, and client cache bypasses.

How a render gets charged

Two things have to happen for one render to count:

  1. The request reaches origin (cache miss, cache expiry, or Cache-Control: no-cache from the client).
  2. Szum successfully produces the requested chart output (the request passes validation, rate limits, and plan policy).

If either fails, the render is not committed. Failed work releases its temporary capacity reservation without entering usage.

Cache headers per endpoint

EndpointCache-ControlNotes
POST /chartprivate, no-storeAuthenticated; response carries X-Usage-* headers, must not be reused across keys
GET /chartpublic, max-age=86400, s-maxage=604800, stale-while-revalidate=864001d browser, 7d CDN, 1d SWR
GET /c/{id} (saved image)public, max-age=86400, s-maxage=86400, stale-while-revalidate=864001d browser, 1d CDN, 1d SWR – update, unpublish, and delete request a CDN purge; browser caches and purge failures fall back to ≤1d
GET /e/{id} (interactive embed)public, max-age=86400, s-maxage=86400, stale-while-revalidate=86400Same as /c/{id} – HTML shell, identical kill-switch semantics
GET /r/{id}[.png|.svg] (MCP)public, max-age=3600, immutable1 hour response cache; the preview config lives for 1 hour, and bare, PNG, and SVG URLs are distinct immutable cache keys

The public chart-delivery routes (/chart, /c, /e, and /r) return handled non-redirect errors with private, no-store, so a transient failure can't poison their edge caches.

Cache keys

The CDN keys on the full URL including query string. That means:

  • https://szum.io/chart?config={...} – two clients sending the same byte-identical config share the same cache entry. Reorder a JSON key and you get a fresh render. The query string IS the input here, so unique query strings produce different renders, which is intentional.
  • https://szum.io/c/abc123 and https://szum.io/e/abc123 – stable; everyone who fetches the same id hits the same cache entry.

Use /c/{id} (saved charts) or /e/{id} (interactive embeds) when many recipients will fetch the same chart – emails, dashboards, Slack, iframes. The opaque short URL is byte-identical for every recipient, which gives repeated requests the best chance of being served from edge cache.

See also

On this page