Slow TTFB on Sanity CDN image transformations with new query params

4 replies
Last updated: Jan 21, 2021
Hey! We're fetching responsive images from cdn.sanity.io using
@sanity/image-url
to generate query param transformations. One observation is that when one or more query param changes value, the request takes quite some time where TTFB is pretty much all of the wait time.• Is anyone else experiencing this?
• Does it just take that long to generate a new version of an image server side maybe?
• Is there something that can be optimized in our transformations query params?
Example image url we have:
https://cdn.sanity.io/images/ <project-id>/<dataset>/<some-img>.png?rect=750,0,1406,1438&w=1112&h=1137&auto=format
After the initial long running request, requests for the same image with the same params are quick.
AI Update

You're experiencing exactly what the Sanity image CDN is designed to do! Here's what's happening and how to optimize:

Yes, this is normal behavior

When you change query parameters (like rect, w, h, or auto=format), you're requesting a new image transformation that hasn't been generated yet. The first request has high TTFB because Sanity's Image Pipeline is:

  1. Processing the image transformation on-demand
  2. Generating the new variant (cropping, resizing, format conversion, etc.)
  3. Caching it in the global CDN

After that initial request, the transformed image is cached at edge locations worldwide, so subsequent requests are lightning-fast.

The key optimization: Use predefined image sizes

According to Sanity's documentation on the Image Pipeline, the most important optimization is:

Limit the number of unique size/crop combinations you request. Instead of generating unique images for every viewport width, use a predefined srcset with a fixed set of image sizes.

Here's an example of a well-optimized approach:

<img 
  srcset="
    https://cdn.sanity.io/images/.../image.png?w=320&h=320&auto=format 320w,
    https://cdn.sanity.io/images/.../image.png?w=640&h=640&auto=format 640w,
    https://cdn.sanity.io/images/.../image.png?w=960&h=960&auto=format 960w,
    https://cdn.sanity.io/images/.../image.png?w=1280&h=1280&auto=format 1280w
  "
  sizes="(max-width: 768px) 100vw, 50vw"
/>

Additional optimization tips

  1. Pre-warm critical images: If you know certain image transformations will be heavily used, you can request them during your build process to pre-populate the CDN cache

  2. Use integer values: Non-integer values for w and h parameters can cause performance issues or timeouts

  3. Leverage auto=format: This is great for automatically serving WebP/AVIF to supporting browsers, but note that AVIF transformations are generated asynchronously, so the first request might get WebP instead

  4. Consider fit parameter carefully: Using fit=max prevents small images from being scaled up unnecessarily

Your current URL looks fine - the rect, w, h, and auto=format parameters are all standard. The "slowness" on first request is just the cost of on-demand image processing, which is actually a feature that saves you from pre-generating thousands of variants!

Show original thread
4 replies
Hi
user A

Yes indeed, if the image size you are requesting is not cached by the CDN it will take some time to generate the image and send it over to CDN. Therefore we strongly recommend using predefined srcsets with a set of predefined image sizes for various display, and not rely on creating unique images for every viewport width.
user J
Allright, thanks!
Here's an example from sanity.io site:
<img alt="Interior space with RBW palindrome light suspended from ceiling" srcset="<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?rect=0,50,1600,800&w=320&h=160&fit=clip&auto=format> 320w,<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?rect=0,50,1600,800&w=480&h=240&fit=clip&auto=format> 480w,<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?rect=0,50,1600,800&w=640&h=320&fit=clip&auto=format> 640w,<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?rect=0,50,1600,800&w=720&h=360&fit=clip&auto=format> 720w,<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?rect=0,50,1600,800&w=800&h=400&fit=clip&auto=format> 800w,<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?rect=0,50,1600,800&w=960&h=480&fit=clip&auto=format> 960w,<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?rect=0,50,1600,800&w=1280&h=640&fit=clip&auto=format> 1280w,<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?rect=0,50,1600,800&w=1440&h=720&fit=clip&auto=format> 1440w,<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?rect=0,50,1600,800&w=1600&h=800&fit=clip&auto=format> 1600w,<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?rect=0,50,1600,800&w=1920&h=960&fit=clip&auto=format> 1920w,<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?rect=0,50,1600,800&w=2160&h=1080&fit=clip&auto=format> 2160w,<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?rect=0,50,1600,800&w=2400&h=1200&fit=clip&auto=format> 2400w,<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?rect=0,50,1600,800&w=2880&h=1440&fit=clip&auto=format> 2880w,<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?rect=0,50,1600,800&w=4320&h=2160&fit=clip&auto=format> 4320w" sizes="393px" src="<https://cdn.sanity.io/images/3do82whm/next/98207d99e70275cc8188a4124875c2c0f3c4e034-1600x900.jpg?w=600&fit=clip&auto=format>" class="Image_img__Isbmk" width="600" height="300" loading="lazy" style="opacity: 1;">
I'd say you propably don't need that many 😄

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?