There is exactly one quality setting at which re-saving a JPEG is nearly free. It is not 100, and it is not the number in any guide's recommended range. It is the number the file was already saved at — and two points either side of it, the same operation costs you roughly forty times as much.

That trade-off is unusual. Most quality dials are monotonic: turn them up for a better, bigger result, or down for a worse, smaller one. The JPEG quality dial has a dip in it. And the dip sits at a value you cannot see by looking at the picture, which is why the ordinary advice — save it at 85 to be safe — reliably produces a file that is both larger and further from the original than saving it at 80 would have been.

The one quality that is nearly free

A 640 × 427 photograph was re-saved at a range of qualities. The error column measures the mean absolute difference per colour channel, on a scale where each channel runs from 0 to 255, against the source — every pixel compared.

Saved at qualityBytesMean error per channel
7241,7651.5237
7443,2441.2394
7643,7551.0686
7845,0220.6622
8045,6980.0169
8246,7750.6214
8448,6090.8250
8651,3160.9400
8858,1830.7285
A line chart of mean absolute error per colour channel against the quality a JPEG was re-saved at, from 72 to 88, with the bytes that came back printed under each quality. The error falls steeply from 1.5237 at quality 72 to 0.0169 at quality 80 — the quality the file was already saved at — then rises again to 0.6214 at 82, 0.8250 at 84 and 0.9400 at 86 before easing to 0.7285 at 88. Bytes climb steadily throughout, from 41,765 at quality 72 to 58,183 at quality 88, so saving above the original quality costs size and fidelity together.
The dip is at the quality the file already had. Everything either side costs more bytes, more error, or both.

The file had been saved at quality 80. Re-saving it there moved the average channel by 0.0169 — about one part in fifteen thousand of the available range, which is another way of saying nothing happened. Two points down, at 78, the error is 39 times larger. Two points up, at 82, it is 37 times larger. At 84 it is 49 times larger and the file has grown by 6.4%.

Now take the common advice literally. Saving this file at 85 — the round number that sits in the middle of every recommended range — produces 49,209 bytes against 45,698, which is 7.7% bigger, with an error somewhere between the 0.8250 measured at 84 and the 0.9400 measured at 86. Bigger file, worse picture, for choosing the safer-sounding number.

Raising the quality to 100 does not rescue it either. The same photograph at quality 100 is 126,343 bytes2.8 times the size — and still not identical to the source. Quality 100 disables aggressive quantisation, but not the colour-space conversion or the transform itself.

It is not a quirk of one photograph

To confirm this was not a quirk of one file, we encoded two fresh source images at qualities chosen in advance — 65 and 92 — and swept them the same way. The minimum error followed the chosen quality in both cases.

Source saved at−4−2at the source quality+2+4
quality 651.23900.99980.00590.73721.0607
quality 920.65040.54310.06130.32000.2104

It follows both times. The reason is mechanical. JPEG compression divides the frequency coefficients of each block by a table of numbers and rounds the result. The quality setting is that table. When you re-encode at the same quality, the coefficients are already whole multiples of the same divisors — the rounding step has nothing left to round, and the file comes back almost unchanged. Re-encode at a different quality and every coefficient is snapped onto a grid that does not line up with the one it is sitting on.

Four panels. The first is a 219-pixel crop of a laptop keyboard from the test photograph. The remaining three show the absolute difference between that crop and the same crop re-saved at qualities 80, 84 and 94, with the difference amplified 24 times so it is visible at all. The quality-80 panel is entirely black: not one of the 47,961 pixels changed. The quality-84 panel shows speckled structure across the keycaps and their edges, where 47.23 per cent of pixels moved. The quality-94 panel shows the same pattern more faintly, where 18.75 per cent moved.
The same crop, re-saved three ways, with the difference amplified 24× so there is anything to see. Left to right: the crop itself, then what changed at quality 80, at 84, and at 94. The second panel is not a printing error.

The second panel above shows this effect directly. Re-saving the crop at its original quality changed not one of its 47,961 pixels; the panel is black because the difference is zero everywhere. Four points higher, at 84, 47.23% of the same pixels moved.

One row deserves attention rather than smoothing over. In the quality-92 case, the error at +4 is 0.2104, which is lower than the 0.3200 at +2. The curve away from the minimum is not clean, and we will not pretend it is. The data shows a narrow, sharp dip at the source quality, not an orderly slope.

Generation loss is not quite what you were told

The standard warning about JPEG is that every save degrades it, so the damage piles up over repeated edits. Our own image compressor said exactly that in its explanatory copy until this guide was written: "Each re-encoding pass introduces a new round of quantisation errors that compound the previous pass."

That warning is half right, and the half people act on is wrong. To test it, we took one of our own 940 × 627 photographs, fixed it at quality 80, and re-encoded it ten consecutive times, feeding each pass's output into the next.

PassError added by this passTotal drift from the startBytes
10.02670.026759,661
20.01620.038559,650
30.01160.046159,651
50.00710.056559,644
80.00340.062859,663
100.00100.064459,671

The damage does not compound. It converges. Each pass adds less than the one before — the tenth pass moved the image 27 times less than the first did — and after ten round trips the total drift is 0.0644. Across all ten generations the file size varied by 39 bytes. The encoder is walking toward a fixed point and then standing on it.

For scale, a single re-encode of that same file at quality 94 costs 0.2140 in error — 3.3 times the total damage of ten passes done correctly. One wrong-quality save is worse than ten right ones.

Change the quality between passes, though, and the warning becomes true immediately. Alternating between 94 and 80 for ten passes, the per-pass error never decays at all — it sits between 0.18 and 0.25 from the first pass to the last — and the file size swings between 59,423 and 93,114 bytes depending on which generation you happen to stop at.

So the real rule is not avoid re-saving. It is avoid changing the quality number. Generation loss is a symptom of inconsistency, not of repetition.

"Quality 80" is not a unit

This all assumes the quality number means the same thing everywhere, which it does not.

The same photograph was handed to macOS's own sips encoder and asked for quality 80. It came back at 84,059 bytes. The same picture through libjpeg at quality 80 is 58,723 bytes — Apple's "80" is 43% larger, and inspecting the table it actually wrote shows it corresponds to libjpeg's quality 94.

Neither encoder is wrong. The quality number is not a property of the image and never was; it is an index into whatever table that particular encoder happens to use. This is why guessing is a bad strategy.

The file already tells you what it was saved at

The quantisation table is not a secret. It is written into every JPEG in a marker segment called DQT, immediately available in the first few hundred bytes, and the standard tables are generated from the quality number by a published formula that can be run backwards.

Tested across qualities 50 to 98 in steps of two — 25 files — reading the table back and searching for the quality that generates it recovered the correct value 25 times out of 25, with the reconstructed table matching the stored one exactly, not approximately.

Run against eight real photographs we serve on this site, whose encoding history nobody recorded: six came back at quality 80 and two at quality 92, all with an exact table match.

The method has one limit: encoders that use custom tables rather than the standard scaled ones, like Photoshop's export path or mozjpeg with trellis quantisation, will not produce an exact match. That is what the residual is for: it was zero on every standard-encoder file above, and 68 on the sips file, which is how we knew Apple was using a table of its own before we knew anything else about it. A non-zero residual means do not trust the number, and that is a far better outcome than a confident wrong answer.

What this audit found in our own tools

Reading the source of our own tools, as we do for every guide, turned up a problem smaller and more specific than a broken calculator.

Two of our tools strip metadata from a photograph by decoding it and writing a new file from the pixels. This is the right technique, a stronger guarantee than editing metadata in place because the new file simply never had any. But both then have to choose a quality to write at, and both choose a fixed one. Our EXIF viewer hard-codes 0.94, with no control offered to the reader at all. Our EXIF stripper defaults to 0.92, which the reader can change.

Applied to the quality-80 photograph above, that is what those two choices cost:

Written atBytesChange in sizeError
80 — the quality it already was59,661−0.1%0.0267
92 — the stripper's default82,127+37.6%0.2939
94 — the viewer's fixed value93,114+56.0%0.2140

Both tools describe the loss as slight, and on that narrow point they are right — 0.2 to 0.3 of a channel level is not something an eye will find. The claim neither of them makes, and the one that matters, is about size. Stripping the GPS coordinates out of a photograph currently returns it between a third and half again larger than it arrived, on tools whose users are usually trying to prepare an image for somewhere else. Writing at the quality the file already carried would have produced a file that was both smaller and closer to the original.

Neither tool reads the DQT marker. The EXIF viewer is the sharper case, since it is already a marker parser. It walks the file's segments to find EXIF, IPTC and XMP, but passes straight over the table that would tell it what to do.

The two strip tools are logged for their next review rather than quietly patched mid-guide. The compressor's explanatory paragraph has been corrected to state that passes compound when the quality changes between them and converge when it does not. The page now carries a dated note recording the original text, which is the right way to change a published claim.

The rest of the audit came back clean. The compressor's and resizer's quality sliders do what they claim, the format converter's feature detection for AVIF encoding is now correctly wired after an earlier fix, and the stripper's lossless PNG mode really is lossless. Nothing else here is a defect.

What to actually do

Prefer the quality the file already has. If you are re-saving a JPEG without resizing it, matching the original quality is nearly free and every other value costs you. Never round upward "to be safe" — a higher number gives you a bigger file and a worse one, which is the opposite of what it sounds like it does. Treat the quality number as encoder-specific: 80 in one tool is 94 in another, so a setting copied between tools means nothing. Resize and compress in one operation rather than two, because a resize discards the block grid anyway and there is no original quality left to match. And keep an uncompressed master where the work matters — matching the quality makes re-saving cheap, not free, and the cheapest edit is still the one made from the original.

Run your own numbers

Our image compressor exposes the quality slider per file and shows the resulting size as you drag it, which is the fastest way to see the size curve in this guide on your own photograph. The image format converter does the same across JPEG, PNG, WebP and AVIF if you want to compare formats rather than qualities, and the image resizer is the tool to reach for when the dimensions are the real problem — as they usually are. To see what metadata a file is carrying before deciding anything, our EXIF viewer lists every tag it finds, and the EXIF stripper removes them in a batch, with a quality field you should now set deliberately rather than leave alone.

Sources
  • Every figure in this guide was measured rather than quoted. The quality sweep and the two controlled sources were encoded with libjpeg through PHP's GD extension in this site's own application container, comparing every pixel of each re-encoded file against the source decode; the error statistic throughout is the mean absolute difference per colour channel on a 0–255 scale. The size curve was sampled every fourth pixel and agrees with the full per-pixel measurement where they overlap — 0.89 against 0.8825 interpolated at quality 85.
  • The repeated-pass experiment, the encoder comparison and the quantisation-table recovery were run for this guide against pexels_29502356.jpg, a 940 × 627 photograph from this site's own image library, fixed at quality 80 before the first pass so that the starting quality was known rather than inferred. The macOS comparison used the system sips encoder at its own quality 80.
  • Quantisation-table recovery inverts the scaling defined in the JPEG standard's Annex K and implemented in libjpeg's jpeg_add_quant_table: the standard luminance table is scaled by a factor derived from the quality value, so searching all 100 qualities for the table that reproduces the stored one recovers the original setting. The stored table is written in zig-zag scan order, not row-major — comparing against a row-major table returns answers that are close but wrong, which is a mistake this guide made first and caught by checking the residual.
  • The mean absolute error used here is computable and reproducible, which is why it was chosen. It is not a perceptual metric and does not claim to be: it measures how far the numbers moved, not how much an eye would notice. Every source in these measurements is an already-compressed JPEG, so what is being measured throughout is re-encoding — which is what a web workflow actually does, but it is not the same as compressing an original.
  • The two strip-tool behaviours reported above were read from the shipped source on 8 August 2026, not inferred from documentation, and both are queued for fix — so a reader checking later may find them changed. The compressor's wording was corrected the same day, in response to the measurement in this guide: public/tools/exif-viewer/app.js passes a fixed 0.94 to canvas.toBlob, and public/tools/image-exif-stripper/app.js reads a user-editable field defaulting to 0.92. Browsers encode JPEG through the same libjpeg family used for these measurements.

This guide is about lossy image encoding, not archival practice. For anything that will be printed, edited further, or kept as a record, keep the original file — no re-encoding strategy is a substitute for not re-encoding.