Mean encode time per file in seconds on the horizontal axis, log scale, against mean encoded size in KB on the vertical, with the speed setting labelled at each point. Further left and lower down is better. Chart generated from the measurement run described below.
Quality is the slider everybody turns. Speed is the one nobody touches, and it is worth more than the last ten points of quality. On this run the default cost 8 percent of every file for nothing, and the slowest setting was not the smallest one.
Every guide about AVIF argues about the quality slider. Almost none of them mention the other setting, the one the encoder calls speed or effort, and on this run it turned out to be worth more than the last twenty points of quality.
Speed is a straight trade. A lower number tells the encoder to search harder for a better encoding of the same picture at the same quality target. It costs time and it does not change how the file decodes for the person looking at it. That is a strange kind of setting: you pay once, at build time, and every visitor collects.
The question is how much they collect, and nobody publishes the number. So here it is.
Eight 1024 pixel PNGs from this gallery. AVIF at a fixed quality of 60, which is the setting the last run landed on as the sensible replacement for WebP 80. Every encoder speed from 0 to 10. That is 88 encodes. For each one: encoded bytes, wall clock encode time, wall clock decode time, and SSIM against the original PNG on the luma channel.
Quality is held fixed on purpose. The point is not what speed does to picture quality, it is what speed does to file size at a quality you have already chosen.
| Speed | Total KB, 8 files | Against speed 6 | Total encode, s | Mean SSIM |
|---|---|---|---|---|
| 0 | 413.6 | -7.98% | 91.60 | 0.97913 |
| 1 | 412.4 | -8.25% | 35.21 | 0.97892 |
| 2 | 412.9 | -8.14% | 27.33 | 0.97885 |
| 3 | 414.6 | -7.76% | 23.59 | 0.97859 |
| 4 | 427.6 | -4.88% | 14.49 | 0.97845 |
| 5 | 428.8 | -4.60% | 9.50 | 0.97780 |
| 6 | 449.5 | 0.00% | 2.79 | 0.97751 |
| 7 | 475.7 | +5.82% | 1.52 | 0.97593 |
| 8 | 486.9 | +8.32% | 0.88 | 0.97439 |
| 9 | 568.6 | +26.50% | 0.38 | 0.97376 |
| 10 | 568.6 | +26.50% | 0.38 | 0.97376 |
Three things fall out of that table and only one of them is the one you expect.
The slowest setting is not the smallest. Speed 1 produced 412.4 KB against speed 0 at 413.6, and it did it in 35.21 seconds against 91.60. Slightly smaller files in 38 percent of the time.
Speed 2 is smaller than speed 0 as well, at 412.9 KB in 27.33 seconds.
This is not a rounding artefact, it is how these encoders behave. The lowest speed setting turns on the most exhaustive search, and an exhaustive search over partition and prediction choices does not guarantee the smallest output at a fixed quality target, because the target is a quality target and not a size target. The encoder is allowed to spend its extra effort on fidelity instead. You can see it doing exactly that in the SSIM column: speed 0 scores 0.97913, the highest on the board, and pays for it in bytes.
If you were reaching for speed 0 because it must be best, it is not, and it costs you two and a half times the encode time to be very slightly worse on size.
Speed 6 is the setting most tooling uses when nobody specifies one, and it is what the last run on this site used. Against speed 1 it is 8.25 percent larger and it scores lower on SSIM, 0.97751 against 0.97892.
That is not a trade. It is a loss on both axes, bought with encode time.
Per file the picture is consistent rather than driven by one outlier. Comparing speed 6 against speed 0 file by file, the savings were 9.3, 8.0, 7.7, 8.6, 8.4, 10.1, 9.2 and 4.9 percent. Every file gained, and the smallest gain was on the largest file.
On a thousand image gallery averaging 56 KB an image at speed 6, moving to speed 1 takes roughly 4.6 MB off a full crawl and gives a slightly better picture doing it.
Every single image encoded at speed 9 and speed 10 came out byte for byte identical. Same size, same SSIM, same encode time within noise. The encoder caps out at 9 and the tenth setting does nothing at all.
That matters mostly as a warning about the top of the range. Speed 9 is 26.5 percent larger than speed 6 and 37.9 percent larger than speed 1. It is the setting to reach for when you are encoding on a request, in a thumbnail service, and the user is waiting. It is not a setting for a build step, and the jump from speed 8 to speed 9 is the single biggest step on the whole curve: 486.9 KB to 568.6 KB for 0.5 seconds saved across eight files.
Mean decode time across the eleven settings ran between 27 and 41 milliseconds with no trend in it, and the one reading near 99 ms at speed 5 is a scheduler artefact rather than a property of the file. The person loading the page pays the same whichever setting you chose.
That is the whole argument for spending build time here. A slower encode does not become a slower page. It becomes a smaller download and an identical decode.
If you are encoding a gallery once and serving it many times, speed 3 is the honest recommendation. It gives up 0.53 percent of the size against speed 1 and runs in 23.59 seconds against 35.21, and it is still 7.76 percent below the default.
If the encode is genuinely free, overnight on a machine nobody is waiting on, take speed 1 rather than speed 0. It is smaller, faster, and the SSIM difference between them is 0.0002, which is not a thing a human being can see.
If you are encoding live, on upload, with somebody watching a spinner, speed 8 is the last setting before the cliff. It costs 8.32 percent over the default and runs in about a ninth of a second a file. Speed 9 saves another 0.06 seconds a file and costs 16.8 percent more bytes, which is a bad trade in almost every situation.
It does not say anything about quality settings other than 60. The shape of the speed curve could differ at quality 90 where the encoder has more bits to spend, and this run did not test that.
It does not test other encoders. This is the AVIF encoder shipped with Pillow, and libavif builds with different tuning, or a rav1e based encoder, may put the knee somewhere else.
It does not test animation, alpha channels, or anything above 1024 pixels.
And the files are the ones in this gallery, which means the result describes AI art with soft backgrounds and sharp faces. A page of screenshots or line art has very different partition statistics and may not behave the same way.
Eight files, eleven encoder speeds each, 88 encodes scored. Pillow 12 with the built in AVIF encoder, quality fixed at 60, speed varied 0 through 10, every source a PNG so there is no prior lossy pass to muddy the reference. SSIM computed on the luma channel with an 11 tap Gaussian window at sigma 1.5 and the standard stabilisers. Encode and decode timings are wall clock around the save and load calls on one machine with nothing else running, and they are indicative rather than a benchmark. Sizes are exact byte counts.