Skip to content

How it works

Picasso works in two separate moments: when your page renders, it only writes signed URLs; when a browser asks for one of them, the variant is rendered, once, then served from a cache.

  1. Twig<twig:Picasso:Image src="photo.jpg" …>
  2. Loaderfinds the source: directory, S3, entity, URL
  3. Metadatareads width × height, if needed (cached)
  4. Transformersigns one URL per width and format
  5. Placeholdertiny image or BlurHash, if any
  6. <picture>sources, srcset, sizes, img
  1. The loader turns src (a path, an entity, a URL) into an image it knows how to read.
  2. If width or height is missing, the metadata of the source are read from its first bytes, and cached in the cache pool.
  3. The transformer writes a URL for each width of the srcset in each format. Glide signs them with sign_key; Imgix points them at its CDN.
  4. The placeholder, if any, adds a preview.
  5. Everything goes into one <picture>, with loading="lazy" unless the image is a priority.

No image is decoded or written at this point: a page with 30 responsive images renders in about 5 ms (benchmarks).

With Glide, the URLs point at the bundle’s route, /image/{transformer}/{loader}/{path}:

  1. BrowserGET /image/glide/uploads/photo.jpg?w=640…
  2. Controllerchecks the signature: 404 if forged
  3. Glide cachehit: streamed as is
  4. Glidemiss: reads the source, renders, stores
  • The first request of a variant renders it: tens to hundreds of milliseconds depending on the size, format and driver.
  • Every next request is a cache hit, about 0.1 ms on local disk, served with Cache-Control: public, max-age=31536000, immutable: browsers and CDNs keep it for a year.
  • The same image and transformation always give the same URL, so a thumbnail shown on several pages is rendered and downloaded once.

To keep PHP out of hits entirely, put the cache in a bucket behind a CDN: Serving from a CDN. With Imgix, all of this happens on Imgix’s side.