I had a compression rule that looked pleasantly simple: encode AVIF at the lowest quality that still passed a SSIMULACRA2 target of 60. For larger image sets, I allowed one representative sample to fall as low as 58 while requiring the rest to stay at or above 60.
For PNG and normal source images, I was comfortable with that rule. Then I started dealing with WebP files that had already been compressed from higher-quality originals before I received them.
higher-quality original: ~2 MB
↓
lossy WebP: ~100 KB
↓
AVIF
Should that second conversion still be allowed to score 60 against the WebP? At first, I thought yes. A score of 60 is still 60. The problem is that the reference image has changed.
The metric was not wrong. The reference had changed.
SSIMULACRA2 compares a reference image with a distorted image and scores the perceptual difference between those two specific inputs. Its implementation is designed to react to compression-related damage such as blur, ringing and introduced edges, and its published evaluation material includes distortions from JPEG, WebP, AVIF and other codecs. The SSIMULACRA2](https://github.com/cloudinary/ssimulacra2/blob/main/README.md%22>SSIMULACRA2) documentation explains the metric and its approximate quality anchors.
If I encode AVIF directly from a good source, the comparison is effectively source → AVIF. A score of 60 describes the damage introduced by that conversion.
With an already-lossy WebP, the real history is different:
original
↓ first lossy encode
WebP
↓ second lossy encode
AVIF
But SSIMULACRA2 only sees WebP → AVIF. It has no knowledge of the original that existed before the WebP. Any artifacts already present in the WebP have become part of the reference.
That means a score of 60 can tell me that the AVIF did not move too far away from the WebP. It cannot tell me how far the final AVIF is from the lost master.
Lossy transcoding creates a second quality budget
Suppose the original contains a clean gradient. The first encoder introduces a little banding, but the WebP still looks acceptable. I then encode that WebP to AVIF. SSIMULACRA2 can penalize additional degradation introduced by the AVIF encoder, but it cannot penalize damage that already exists in the reference.
This is why encoding from an already-lossy image is not equivalent to encoding directly from the best available source. A discussion in the libavif](https://github.com/AOMediaCodec/libavif/discussions/2640%22>libavif) project makes the same general point: existing compression artifacts can be carried into a new AVIF when the input is already compressed.
That does not mean AVIF automatically amplifies every WebP artifact, and it does not mean transcoding should never be done. It means the second encoder is operating after some of the original quality budget has already been spent.
The policy I ended up using
- Canonical or high-quality source: target 60, single-sample floor 58.
- Lossless WebP: target 60, single-sample floor 58.
- Known lossy derivative: target 65, single-sample floor 63.
The important distinction is not JPEG versus WebP. It is canonical source versus known lossy derivative.
WebP can be lossless. The WebP](https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification%22>WebP) lossless specification describes a mode that reconstructs pixel values exactly, so there is no previous lossy generation to compensate for. Conversely, a JPEG that I know has already passed through several lossy transformations deserves the same caution as a previously compressed WebP.
Why 65?
There is no SSIMULACRA2 rule saying that a second lossy generation requires exactly five extra points. I found no such rule because it does not exist. The value 65 is an engineering policy, not a property of the metric.
The published quality anchors are useful context. Roughly speaking, 50 corresponds to medium or fair quality, while 70 corresponds to high or good quality. That puts 60 in a fairly aggressive web-compression range rather than the visually lossless end of the scale.
For a direct conversion from a good source, I am comfortable spending that amount of perceptual quality in exchange for smaller files. For a second lossy generation, I wanted a smaller additional distortion budget.
I considered 70, but that would push every transcoded image into a substantially stricter quality region. On pages that load many images, especially over mobile connections, those extra bytes matter. I did not have evidence that forcing every already-compressed image to 70 would justify the cost. So I settled on 65 as a conservative middle ground.
Why 65/63 instead of 65/62?
My original policy was 60/58, which allows one representative outlier to fall two points below the main target. When I raised the main threshold to 65, preserving the same policy naturally produced 65/63.
60 - 58 = 2
65 - 63 = 2
Using 62 would create a three-point exception. That would make the normal samples stricter while making the single worst sample more permissive. I could not find a technical reason to widen the exception specifically for inputs that have already gone through lossy compression.
Neither 63 nor 65 is a magical number. The useful property is that the policy remains internally consistent.
A 2 MB file becoming 100 KB does not tell me the visual quality
I deliberately do not derive SSIMULACRA2 thresholds from compression ratio. A source shrinking from 2 MB to 100 KB sounds dramatic, but file size alone says surprisingly little about perceptual degradation.
Resolution, image entropy, noise, flat areas, line art, chroma subsampling and the previous format all affect compression efficiency. The Google](https://developers.google.com/speed/webp/docs/webp_study%22>Google) WebP compression study compares codecs at approximately matched quality rather than assuming that equal file sizes imply equal visual quality.
So I do not use rules such as 20× smaller → target 65. What matters to my policy is whether the current file is known to be a lossy derivative, not how impressive its size reduction looks.
If I still have the original, I do not transcode the WebP
If both the high-quality original and the small lossy WebP still exist, I encode AVIF directly from the original and use the normal 60/58 policy.
preferred:
original → AVIF
avoid when possible:
original → lossy WebP → AVIF
A stricter second-generation target cannot restore information that disappeared during the first encode. A score of 65 only tells the AVIF encoder to stay closer to the WebP. A score of 70 would stay even closer. Neither recreates the missing original.
The implementation bug mattered more than 62 versus 63
While reviewing the policy, I found a more dangerous problem in the encoder logic. The code already had format-specific target constants and a helper capable of returning a different target for WebP. That made changing WebP from 60 to 65 look trivial.
It was not. The adaptive quality decision still used the global target and global worst-score threshold. The format-specific target was later used to label individual results as passing or below target, but it did not necessarily control the decision that selected the final AVIF quality.
That creates a subtle failure mode. A WebP sample can be correctly described as below its intended target of 65 while the adaptive search still accepts the quality because the global pass condition is 60.
intended WebP target: 65
actual score: 61.2
format-aware label: below target
global search rule: pass if target is still 60
A threshold is meaningless unless it participates in the decision that chooses the encoded output.
The safer design is to make thresholds part of the sample policy
I now prefer treating the thresholds as properties of the source rather than decorative format constants. In simplified pseudocode:
if sample is a known lossy derivative:
target = 65
floor = 63
else:
target = 60
floor = 58
reject if any sample is below its floor
allow at most one sample below its target
The important property is that the same thresholds used to describe a result also control whether that result is accepted.
Sampling policy matters too
I do not need to test every image at every candidate AVIF quality. The pipeline selects up to ten representative JPEG, PNG or WebP samples across the bytes-per-pixel distribution.
For collections with ten images or fewer, every sample must meet the normal target. For larger collections, one sampled image may use the lower floor while the others still need to satisfy the main target.
Sampling makes the search practical, but it also means I do not want the outlier rule to become unnecessarily loose. The selected samples are representatives, not proof that every unsampled image behaves identically.
The experiment that could replace the heuristic
The strongest answer would come from keeping true originals for a representative corpus and testing complete chains:
A: original → AVIF, target 60
B: original → lossy WebP → AVIF, target 60
C: original → lossy WebP → AVIF, target 63
D: original → lossy WebP → AVIF, target 65
E: original → lossy WebP → AVIF, target 70
For each variant, I would record final byte size, SSIMULACRA2 against the true original, SSIMULACRA2 against the WebP intermediate, and the encoder quality that was selected. I would also manually inspect difficult images.
I have not run that controlled experiment across a sufficiently representative set of preserved originals, so I cannot claim that 65 is globally optimal. That limitation matters.
AVIF is not automatically worth another encode
If the only remaining source is a 100 KB WebP and the AVIF that passes 65/63 is 96 KB, I would question the conversion. Saving 4 KB may not justify another lossy generation and additional processing complexity.
If the same 100 KB WebP becomes a 65 KB AVIF while still passing the quality policy, the trade-off is much more compelling on image-heavy pages.
A codec conversion should answer two separate questions: is the additional distortion acceptable, and is the size reduction large enough to matter? Passing the first does not automatically satisfy the second.
The rule I use now
If I have the best-quality original, I encode from it directly and use 60/58 for this web-oriented workload. If the WebP is lossless, I also use 60/58. If the only remaining file is a known lossy derivative, I use a stricter second-generation budget, currently 65/63. If AVIF barely reduces the size, I consider keeping the existing WebP.
The deeper lesson is not that WebP requires a special SSIMULACRA2 number. It is that a full-reference quality metric only answers the question represented by its reference image.
If the reference has already lost information, a high score means “close to this reference,” not “close to the image that existed before it.” Once I started treating image provenance as part of the compression policy, the thresholds stopped looking like arbitrary codec settings. They became budgets for different generations of loss.