# Caching and versions

> How VectorFast Render caches renders, what goes into the cache key, how template and brand kit versions work, and how idempotency keys make retries safe.

Canonical URL: https://vectorfast.ai/render/docs/caching
Markdown URL: https://vectorfast.ai/render/docs/caching.md
Last modified: 2026-10-30

**Short answer:** a render is identified by its cache key: template id and source version, brand kit version, format, size, scale, and the validated parameters. The same cache key is rendered once and then served from the edge cache or R2. Change any input, including the brand kit, and you get a new cache key and a new image.

## The cache key [#the-cache-key]

```text
cache_key = sha256(
  "v1" \n template_id \n template_version_hash \n brand_kit_version \n
  format \n width \n height \n scale \n stable_json(validated params)
)
```

* `template_version_hash` is a hash of the template's source code, so any change to a template produces new cache keys even if its version label stays the same.
* `brand_kit_version` is `default@1` for the built-in kit or `bk_…@n` for an account kit.
* Params are validated and trimmed first, then serialized with sorted keys, so key order and surrounding whitespace do not create new entries.

`POST /v1/renders` returns `cache_key`; image responses carry it as `X-Cache-Key`.

## Two cache layers [#two-cache-layers]

| Layer                 | Keyed by                                                   | Notes                                                                                              |
| --------------------- | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| Cloudflare edge cache | The full request URL (signed URLs) or the cache key (REST) | Closest to the viewer; per data center                                                             |
| R2 object storage     | The cache key                                              | Shared by REST, MCP, and signed URLs, so pixels rendered through one path are served to the others |

A response tells you which layer answered: `X-Cache: hit-edge`, `hit-r2`, or `miss`, and `cached: true` in JSON. Hits never render; `render_ms` is `0`.

Previews from `POST /v1/previews` and the MCP `preview_render` tool carry a watermark, use a separate cache key, and are only kept in the edge cache.

## Billing and cache hits [#billing-and-cache-hits]

Billing is not connected in early access, so every response reports `credits_charged: 0`. When billing is connected, a new render will spend one credit and a cache hit will spend nothing; previews stay free. See [Limits and quotas](/render/docs/limits).

## Template versions [#template-versions]

Every template has a semantic version (`launch-post@1.0.0` in `template_version`). Requests can name a template as `launch-post` (current version) or pin the major version as `launch-post@1`. A pin that does not match the current major version returns `404 template_not_found`, so a breaking template change can never silently change images you pinned.

## Brand kit versions [#brand-kit-versions]

Editing a brand kit, including uploading a new logo, creates a new version: `bk_…@1`, `bk_…@2`, and so on. Because the version is part of the cache key:

* renders that name the kit without a version use its current version and pick up your changes;
* renders that pin a version (`"brand_kit": "bk_…@1"`) keep hitting the cache for that version;
* signed URLs always carry a pinned version, so a URL you stored keeps its pixels after the kit changes.

## Idempotent retries [#idempotent-retries]

Send an `Idempotency-Key` header (1–255 printable ASCII characters) with `POST /v1/renders` to make retries safe. For 24 hours, the same key with the same body returns the stored response with the same `id` and `Idempotent-Replayed: true`; the same key with a different body returns `409 invalid_params`. Keys are scoped to your account. Two concurrent first requests with the same key may both render, but they produce the same pixels and cache key.
