How to Cache OG Images
Caching OG images means serving a previously-generated social preview from a CDN instead of re-rendering it on every share. FastOG caches identical images at the edge for a year — the same URL returns the cached PNG without counting against your quota and at roughly zero latency, so most of a site's OG traffic never touches the renderer.
Why caching matters
A social share triggers a fetch by the platform's crawler. If every share re-rendered, you would burn quota and latency on identical content. Aggressive caching — keyed on the image's content — turns "every share counts 1 render" into "the first share counts 1 render, every other share is free."
The content-keyed model that makes it work
FastOG uses content-signed URLs: the URL is a pure function of the parameters. Identical title + template → identical URL. That means:
- FastOG's edge keeps the image under the URL.
- Same content shared 10,000 times → one render, one quota count, 9,999 cache hits.
- Change the content → different URL → one new render.
GET /api/v1/og?title=Hello&template=default&key=...&s=... → render (1 quota count), then
GET /api/v1/og?title=Hello&template=default&key=...&s=... → cached (0 counts, instant)
GET /api/v1/og?title=Changed&template=default&key=...&s=... → render (1 quota count)
FastOG's caching headers
FastOG returns Cache-Control: public, max-age=31536000, immutable (one year) for rendered images. A cover
is served from FastOG's edge in two tiers: the render cache in front of fastog.com, and a durable object
store behind it. Repeat fetches are answered without re-rendering, and X-FastOG-Worker-Cache on the
response says which tier answered (HIT, R2, MISS).
Because the durable copy does not depend on the renderer, covers that have been fetched at least once keep being served while FastOG's render service is briefly unavailable — an outage does not blank out a preview that has already been generated. A cover that has never been rendered before is the one case that needs the renderer, and there FastOG answers with an image rather than an error:
| Situation | What a crawler gets |
|---|---|
| Cover already rendered | the cover, from the edge or the durable store |
| Never rendered, render service up | the cover, rendered on demand |
| Never rendered, render service briefly down | the page's own image carried in the URL (your product photo), or a neutral card — never an error page |
If the request itself is invalid (a tampered signature, a missing title), you still get the matching 4xx.
Changing an image you have already published
| You changed | What to do |
|---|---|
| The content (title, price, photo) | nothing: the content is in the URL, so the new content is a new URL and renders fresh |
| The template or a render default | bump the cache-bust version (FASTOG_CACHE_BUST) so every URL gains a new v param |
| You need the same URL re-rendered | ask support to purge that one URL — the exact-URL purge is not exposed as a public endpoint |
Links that were already shared keep working, and keep showing the image they promised, unless you purge that exact URL.
Caching your own og:image (self-hosted)
If you store images yourself instead of using FastOG's cache, apply the same rules:
| Step | Detail |
|---|---|
| Cache key = content hash | Store by a hash of the data, not a mutable filename |
| Long TTL | max-age=31536000, immutable for stable content |
| Versioned URLs | Append a hash/version when content changes |
| CDN in front | Let the CDN absorb repeat fetches |
FAQ
Do repeat shares really cost 0 renders?
Yes. Identical URLs hit the edge cache and never reach the renderer — no quota count is consumed.
How long does FastOG cache an image?
One year (immutable). Long after first render, a shared card is served from cache.
What if I want an image to update (e.g. live price)?
Change a parameter (the price) → new URL → new render. Stable content stays cached; dynamic content updates when you want it to.
Related
Try it free — no signup required
Preview and test dynamic OG images in seconds.
Open the Free OG Image Tester