Skip to main content
This page covers the cache option: what Cache-Control an object is served with, where to set it, and which value to pick. Every SDK takes the same values.
Cache-Control is written once, at upload, and stored with the object. The CDN and the browser honor it on every read. There is no per-request override; changing it means writing the object again.

Which value to pick


The cache option

A duration is converted to whole seconds, so '1500ms' stores max-age=1. The grammar is on Types.

The raw header

Anything containing = or , is treated as a raw header and stored as written. Use this for s-maxage, stale-while-revalidate, no-transform and anything else the three keywords do not cover.

revalidate versus a short max-age

'revalidate' stores public, max-age=0, must-revalidate. The cached copy is checked with If-None-Match on every read, so an unchanged object costs a 304 with no body. A short max-age serves stale bytes until it expires, then re-downloads the whole object. 'revalidate' costs a round trip per read, but is never stale and never downloads the bytes twice.

Where you can set it

Four places. The most specific one wins.

On the bucket

The default for every object this client stores. Client options: TypeScript, Python, Go.

On a put

The JSON update takes it too, for the object it rewrites. So do copy and move, for the destination. Without it the source’s value carries over.

On a signed upload URL

Signed into the URL and handed back in the returned headers, so the uploader has to send it verbatim.

On a direct browser upload

Decided per upload in the before-upload callback on your server and signed into the presigned PUT. See Authorizing an upload.

Private buckets

On a private bucket, private replaces public, so no shared cache keeps a copy of an object only a signed request may read. This follows the bucket’s visibility in the console; nothing in the code declares it. A raw header string is passed through as written, visibility included: cache: 'public, max-age=60' on a private bucket stores public, max-age=60.

Immutable plus a versioned URL

The versioned URL is the URL with the etag on the query, so it changes whenever the content does. A stable path stored immutable and served through the versioned URL is cached for a year, and every overwrite produces a URL no cache has seen. The path never moves, so nothing has to be deleted. A private bucket has neither URL.

no-store and signed reads

These are two separate mechanisms. The link expires at its returned expiry, but the stored Cache-Control outlives it: with a long max-age the reader’s browser keeps the bytes after the link stops working. If a reader must not keep the bytes, store the object with no-store. no-store drops the visibility scope entirely and stores no-store on public and private buckets alike. See Signed read URLs for link lifetimes.

What the upload route itself caches

An upload route’s GET serves its constraints document with a 60 second Cache-Control of its own, unrelated to the objects the route stores. See Constraints.