Formats, transparency and why not AVIF
Why format=auto is WebP — and why that is not a size argument
Section titled “Why format=auto is WebP — and why that is not a size argument”This one has a history worth reading, because the first answer was wrong.
May 2026. A benchmark over 100 production samples concluded AVIF was 4.5–9.8% larger than WebP at equivalent quality. Case closed: keep WebP.
June 2026. Re-run, and the earlier result turned out to be a methodology artifact, not a property of the format. The original bench had:
- encoded AVIF from an already-lossy
lg.webp, not from the original, and - compared unmatched quality — AVIF at q70/effort4 against WebP at q80/effort6, where its own SSIM column showed the AVIF was higher quality.
Both biases pointed the same way. Re-run from originals at matched SSIM, AVIF is 14–20% smaller at every delivery size, and 25–43% smaller on flat interiors.
So AVIF wins on size, clearly. WebP is still the default, for two reasons that have nothing to do with bytes:
- Decode cost on low-end mobile. The device mix in Central America is not the device mix in a benchmark. AVIF decode is what a cheap phone feels.
- 3–6× encode time, on a synchronous, timeout-bounded request path. The first request for a new derivative pays that.
And the product context that makes the trade obvious: delivered file size is not the priority driver here — these clients have bandwidth. AVIF’s real 14–20% win buys something nobody is asking for, while its costs land squarely on mobile thermals and time-to-first-byte, which people do notice.
Decision: format=auto → WebP. AVIF only if you ask for it explicitly.
Worth revisiting if egress cost or a bandwidth-constrained market becomes a
priority — at which point <picture> with AVIF on the large rungs is the path,
not flipping the default.
Transparency: what survives and what does not
Section titled “Transparency: what survives and what does not”JPEG has no alpha channel. That single fact drives all of this.
| you upload | you ask for | you get | alpha |
|---|---|---|---|
| PNG with alpha | image/png |
PNG | kept |
| PNG with alpha | image/webp |
WebP | kept (WebP has alpha) |
| PNG with alpha | image/webp on WebKit |
JPEG fallback | flattened onto white |
| PNG with alpha | image/jpeg |
JPEG | flattened onto white |
Asking for PNG is a promise the compressor keeps. A request for
image/png returns PNG and nothing else — no JPEG fallback, ever. That request
means lossless or alpha, on purpose — icon extraction, sprite work, a cut-out
— and silently handing back a flattened JPEG would be the same class of bug as
the format mislabelling.
// A cut-out that must keep its transparency:await nt.upload(file, { presets: ["original", "thumb"], compress: { mimeType: "image/png" }, // no fallback path exists});Why flattening is onto white
Section titled “Why flattening is onto white”Without an explicit composite, transparent pixels encode as black — a cut-out product photo becomes a photo on a black background. The compressor composites onto white before any JPEG encode, so the failure mode is “lost transparency” rather than “ruined image”.
Keeping a PNG intact
Section titled “Keeping a PNG intact”Two different goals, two different answers:
“I want the exact bytes back later.” → presets: ["original", …]. The
original variant is the uploaded bytes, untouched, whatever they were.
“I do not want it re-encoded on the way up.” → that is the compressor’s
convertSize threshold. The SDK’s defaults convert large PNGs to JPEG, because
the alternative is what production actually looked like:
tenant twolink 20 files · image/png · avg 6.85 MBtenant realtyone-cr 168 files · image/png · avg 13.16 MB (2 210 MB total)Those are photographs saved as PNG. For a photo, PNG is the wrong container
and converting is the right call. For a graphic with alpha, it is not — which
is why asking for image/png explicitly disables the whole conversion path.
What iPhones actually produce. Decoded natively where the engine can — about 136 ms — and only falling back to a 341 kB WASM decoder where it cannot, which takes ~1,700 ms. Most users never fetch the decoder.
What your visitors receive, regardless
Section titled “What your visitors receive, regardless”Delivery is always WebP by default, no matter what the client managed to
encode. The server re-encodes every variant. The client format only
affects upload size and the archived original — see
Compression in the browser.