Make the image smaller in pixels first, then lower the quality. Pixel dimensions do far more than any quality slider, because file size grows with the area of the image: halve the width and height, and you have a quarter of the pixels to store.
We tested this on a real file: a 5919 by 4024 pixel press photo from NASA’s image library, shot on a Nikon Z 6 at ISO 5000, and 17,101,037 bytes as downloaded. All encoding below used Pillow 13.
Quality alone will not get you there
Keeping all 5919 pixels of width and only changing JPEG quality gives this:
| Dimensions | JPEG quality | Size |
|---|---|---|
| 5919 x 4024 | 95 | 9,137,226 |
| 5919 x 4024 | 85 | 4,748,846 |
| 5919 x 4024 | 75 | 3,287,543 |
| 5919 x 4024 | 60 | 2,286,662 |
Even at quality 60, with visible damage if you look closely, the file is still 2.3 MB, too heavy for a web page. Now hold quality at 80 and change the dimensions:
| Dimensions | JPEG q80 | WebP q80 | AVIF q50 |
|---|---|---|---|
| 2400 x 1632 | 498,853 | 324,942 | 155,354 |
| 1600 x 1088 | 213,763 | 127,796 | 72,032 |
| 1200 x 816 | 123,362 | 77,474 | 44,635 |
| 800 x 544 | 59,871 | 39,950 | 22,791 |
| 400 x 272 | 18,687 | 13,012 | 7,812 |
Going to 1600 pixels wide at quality 80 gives a file 80 times smaller than the original, at 213 KB. Switching that to WebP takes it to 128 KB. On a screen where the photo fills a 1600-pixel slot, nobody can see the difference from the 17 MB version, because the screen cannot show more pixels than the slot has.
This is also why you should not obsess over quality. At 1600 pixels, dropping from JPEG quality 90 to 60 cost about 3.8 dB of PSNR, a standard measure of how far the result differs from its source (39.1 down to 35.3), and saved 215 KB. Changing dimensions from 2400 to 1600 saved 285 KB with no quality setting touched.
The right order
- Start from the best copy you have. The original, not something already downloaded from a website or sent through a messaging app.
- Crop. Removing pixels you do not need is free. An uncropped background full of leaves or gravel costs a surprising amount, because fine detail is expensive to store. Our Crop Image tool does this in your browser.
- Resize to the largest size it will be displayed. Allow for high-density screens, as explained below.
- Choose the format. WebP or AVIF for your website, JPG if it has to go everywhere, and PNG for graphics with text and flat colour. Our comparison has the details.
- Lower the quality as the final step, in one save, checking by eye.
Why the order matters
We tested the wrong order: compressing the original hard at JPEG quality 40, then resizing to 1600 and saving at quality 80, versus resizing the clean original straight to 1600 at quality 80.
| Route | Size | PSNR against a clean 1600-pixel version |
|---|---|---|
| Resize, then one save at quality 80 | 213,763 | 37.1 dB |
| Save at quality 40, resize, then save at quality 80 | 221,960 | 36.6 dB |
The wrong route gave a larger and worse file. The compression artefacts from the first save were baked into the pixels, and the second save then spent bytes faithfully preserving them.
Re-saving is more subtle than people say, though. Saving the same image at quality 80 ten times in a row hardly changed anything: PSNR moved from 37.06 to 36.94 dB. That is because JPEG rounds to the same values each time. But saving ten times with a different quality each round (the way a file gets treated as it passes through different apps and people) dropped it from 37.06 to 32.6 dB. Quality loss comes mostly from changes between saves, so the advice to save once from a clean copy stands.
Target sizes for the web
There is no official standard for image file size. These are the working targets we would use, and our table shows they are achievable with a real photo. Treat them as starting points.
| Image use | Width to export | Target size |
|---|---|---|
| Full-width hero | 1600 to 2000 px | Under 200 KB |
| Image inside an article | 800 to 1200 px | Under 100 KB |
| Card or grid thumbnail | 400 to 600 px | Under 30 KB |
| Small avatar or icon | 64 to 128 px | Under 10 KB |
For high-density phones and laptops, the width you need is often twice the width you display. A photo shown 700 CSS pixels wide on a 2x screen can use 1400 real pixels. The way to serve this without punishing everyone else is srcset, which offers several sizes and lets the browser choose. We show a working example in image dimensions and DPI explained.
Add up the page as well. Five 100 KB images plus a 200 KB hero is 700 KB of images, and that may be fine for an article but heavy on a mobile connection.
Other destinations have their own limits, so check them. If a form or email system caps the file at 2 MB, a 2400-pixel JPEG at quality 85 will generally clear that limit with room to spare, and no further effort is needed.
What else affects file size
Noise. Our test photo was shot at ISO 5000, and grain is close to random. Random data barely compresses, which is why this image is unusually large for its pixel count. A clean photo at low ISO would come out smaller at the same settings. If a shot is unusually heavy, a little noise reduction before export can save more than lowering quality.
Metadata. Camera data, editing history and colour profiles add up to tens of kilobytes. In this photo, the EXIF block was 15 KB and XMP 16 KB. That is trivial on a 17 MB file, but it can be a noticeable share of a 40 KB thumbnail, and it can contain private details as well. See what is EXIF data.
Colour count. A graphic with a few flat colours can drop to an 8-bit palette PNG, and our test screenshot went from 115 KB to 47 KB this way.
Using our tools
Run them in this order: Resize Image first, then Compress Image. Both run in your browser, so the file stays on your device. Since Compress does not change the pixel dimensions, a huge photo run through it alone stays huge. In Chromium, the canvas encoder our tools rely on turned our full-size 5919-pixel photo into a 3.3 MB WebP at quality 78, and that is a good result in percentage terms and still far too heavy for a web page.
The browser encoders are also not the most efficient available. For a single image, this rarely matters. For a site with hundreds of images, or if you want AVIF, use a tool that can be scripted: ImageMagick, sharp or cwebp. This cwebp command encodes a resized file at quality 80 using its slowest and most thorough method. On our 1600-pixel version it produced 127,796 bytes:
cwebp -q 80 -m 6 photo-1600.png -o photo-1600.webp
How to judge the result
View the image at the size it will be displayed, on the screen it will be seen on, not zoomed to 400%. Then check the three spots where damage shows first: flat gradients such as sky (look for banding), edges against a plain background (look for halos), and small text (look for smudging). Lower the quality in steps until one of these looks wrong, then go back up a notch. Do this once for each type of image, and use those settings from then on.