Image delivery
How Image Processor chooses the delivered format, keeps one cache entry per transformation, and where it stops, with no storage and no uploads.
An image built on request still has to reach the browser in a format it reads, and be built once rather than for every reader. On an application, Image Processor builds a derived image from the source image on the origin. How a request becomes a derived image, with the diagram of that chain, is on How Applications works.
The sections cover how the delivered format is chosen, how the cache tells one derived image from another, and where Image Processor stops.
Format negotiation
The delivered format is not always the format of the source image. Two mechanisms change it, and they behave differently.
The first is explicit. A filters:format() filter in the ims string asks for a named output format. Converting to WEBP also requires the request to carry Accept: image/webp, and the Add Request Header behavior adds that header when the browser does not send it.
The second is automatic and needs no ims parameter at all. Image Processor detects whether the browser supports WEBP and converts the image when it does. A BMP image is converted to JPEG or WEBP depending on the same support. For example, a request whose Accept header lists image/webp, with no query string, can receive image/webp for a source image stored as PNG.
The bytes on the origin and the bytes on the wire are therefore two different measurements, and the response says so. A processed response carries x-ims: Enabled, and x-original-image-size carries the size of the source image before the transformation. A reader who never writes a filter can still receive a format other than the one on the origin. Read these headers before you compare a response with the file on the origin. For the headers, refer to Image Processor settings.
One cache entry per transformation
A derived image is worth building only once. The practice for the cache setting that serves images is to list ims in its query-string control: Cache vary by Query String, with the Behavior Allowlist and ims in Fields. Each distinct ims string then has a cache key of its own. That control belongs to the Application Accelerator section of a cache setting, cache_vary_by_querystring under modules.application_accelerator. Varying the cache on ims therefore requires Application Accelerator, while processing an image does not.
A cache setting created with that allowlist reads back with this modules object:
A derived image converted to another format also carries the format after the @@ separator, as in httpsstatic.example.com/static/images/image_1.jpg?ims=880x@@webp.
That key has a cost, and the cost is cardinality. Every distinct ims string is a distinct stored object. A page that asks for arbitrary widths stores an object per width, while a page that asks for four fixed widths stores four. Choosing a small set of sizes is therefore a caching decision as much as a layout one.
It is also a billing decision. An image served from the cache without processing is not counted against the monthly Images meter, so a well-cached derived image costs one processed image however many readers receive it. For what each plan includes, refer to Applications limits.
Where Image Processor stops
Image Processor reads a source image and returns a derived one. It does not store images, and it does not accept uploads: the source stays wherever it already lives, and no derived image becomes an asset the account owns. A workflow that needs to keep a transformed file has to save the response itself.
What the ims string can express, and the size of the image, bound the transformation. The operations the string accepts are on Image Processor URL parameters, and the maximum size and dimensions are on Applications limits.
One boundary is worth naming, because two surfaces share a name. WASM Image Processor is a WebAssembly library that processes images inside a function on Functions. It is a different surface with a different interface, and nothing on this page configures it.