Image Load Lab

Guides WordPress Workflow Tested Sep 29, 2026 WordPress 7.1.2 on this site

What WordPress Creates When You Upload a Photo: 3 Uploads Measured

A 2.9 MB camera JPEG left eight files totalling 4,048,293 bytes on our server. The same photo uploaded as a 1600-pixel WebP used 280,622 bytes, 14 times less.

What actually happens on the server when you upload a photo to WordPress? Instead of describing the Media Library in general, we uploaded the same CC0 photograph to this site three times, as a camera original, as a pre-sized WebP and as an AVIF, and recorded every file WordPress 7.1.2 created, with its dimensions and its exact size in bytes. The results turn the usual advice (“resize before you upload”) into numbers.

The three uploads

The photo is Lake Mountain Landscape by Bonnie Moreland (CC0, via Wikimedia Commons): a 5184 × 3456 JPEG of 2,915,869 bytes straight from the original upload. We prepared three versions and uploaded each one through the WordPress REST API, which uses the same code path as the Media Library uploader:

  1. Camera original: the 2.9 MB JPEG, unchanged.
  2. Pre-sized WebP: the same photo resized to 1600 pixels wide and encoded as WebP quality 75 with sharp (88,122 bytes).
  3. Pre-sized AVIF: the same 1600-pixel image as AVIF quality 50 (66,773 bytes).

This site runs WordPress 7.1.2 with the default image sizes (thumbnail 150, medium 300, medium_large 768, large 1024, plus the core 1536 and 2048 sizes) and no image-optimisation plugin.

What WordPress generated

Every file stored for each upload on imageloadlab.com (WordPress 7.1.2)
Upload File WordPress stored Pixels Content-Type served Bytes
Camera JPEG uploaded file as served 2560 × 1707 image/jpeg 472,127
Camera JPEG original kept (big-image threshold) 5184 × 3456 image/jpeg 2,915,869
Camera JPEG medium 300 × 200 image/jpeg 10,380
Camera JPEG large 1024 × 683 image/jpeg 90,498
Camera JPEG thumbnail 150 × 150 image/jpeg 4,266
Camera JPEG medium_large 768 × 512 image/jpeg 53,852
Camera JPEG 1536×1536 1536 × 1024 image/jpeg 186,407
Camera JPEG 2048×2048 2048 × 1365 image/jpeg 314,894
WebP 1600 uploaded file as served 1600 × 1067 image/webp 88,122
WebP 1600 medium 300 × 200 image/webp 7,932
WebP 1600 large 1024 × 683 image/webp 52,866
WebP 1600 thumbnail 150 × 150 image/webp 3,156
WebP 1600 medium_large 768 × 512 image/webp 35,896
WebP 1600 1536×1536 1536 × 1024 image/webp 92,650
AVIF 1600 uploaded file as served 1600 × 1067 application/octet-stream 66,773
Bar chart: the camera JPEG upload used 3,953 KB of storage, the 1600-pixel WebP 274 KB and the AVIF 65 KB (a single file with no sizes)
Total bytes of every file WordPress stored for each upload. Chart generated from the linked CSV.

The camera original produced eight files on disk totalling 4,048,293 bytes. Because the photo is wider than 2560 pixels, WordPress’s “big image” rule created a -scaled copy at 2560 × 1707 (472,127 bytes) and used it as the main image, but it also kept the 2,915,869-byte original on the server. The pre-sized WebP produced six files totalling 280,622 bytes, 14.4 times less storage for the same photograph.

Storage is only part of the story. When we inserted each upload at full size into a post, WordPress wrote a srcset whose largest candidate was the 2560-pixel -scaled JPEG (472,127 bytes) in the first case and the 1600-pixel WebP (88,122 bytes) in the second, with sizes="auto, (max-width: 2560px) 100vw, 2560px" for the JPEG. That largest candidate is what a big high-density screen may download.

What surprised us

A generated size was bigger than the file we uploaded. From the 88,122-byte WebP, WordPress created a 1536 × 1024 version of 92,650 bytes: fewer pixels but 5 % more bytes. WordPress re-encodes every size with its own default quality setting, which is higher than the quality 75 we used. If you carefully tune compression before uploading, the smaller sizes WordPress creates will not follow your setting.

The AVIF upload produced no sizes at all, and the file was served with the content type application/octet-stream instead of image/avif. The server’s image library could not process AVIF, so WordPress stored the file as-is. We tested what that means for visitors in a separate AVIF upload test.

Snow-capped mountain reflected in a calm lake at dusk, framed by conifer forest
The 1600-pixel WebP upload as WordPress serves it here, with the srcset WordPress generated from its sizes. Photo: Bonnie Moreland, CC0, via Wikimedia Commons.

A workflow based on these numbers

  1. Keep your master file off the web server. The camera original is your archive; WordPress does not need it. In our test it added 2,915,869 bytes of storage for one photo, and it lands in your backups too.
  2. Resize to the largest size your theme actually displays, times two for high-density screens. This site’s reading column is at most 623 CSS pixels wide, so 1600 pixels covers a 2× screen with room to spare. Anything above 2560 triggers the -scaled copy and keeps the original.
  3. Strip location and camera metadata before upload, rotating the pixels first. Our EXIF test found GPS data in 5 of 20 public photos.
  4. Upload WebP if your host supports it: WordPress then creates WebP sizes too. Check one upload’s generated files before assuming the same for AVIF.
  5. Write the alt text in the Media Library when you upload, describing what the image shows in the context where you will use it. Here: “Snow-capped mountain reflected in a calm lake at dusk, framed by conifer forest”.
  6. Verify what the page serves. Open the published page, inspect the image and check currentSrc in DevTools. Our size audit shows which of these generated files Chrome actually picked.

Repeat this test on your own images

To see what your own WordPress installation does, upload one test photo to the Media Library and open its attachment details. The file name and dimensions of the full size are shown there, and the generated sizes can be listed through the REST API at /wp-json/wp/v2/media/<ID>, in the media_details.sizes field, which is how our script run_wp_upload.py collected the table above. Check three things: whether a -scaled copy was created and the original kept, how many sizes your theme and plugins add, and whether a WebP or AVIF upload gets its own sizes. If you never need the camera originals on the server, the big_image_size_threshold filter can lower or disable the 2560-pixel rule, but resizing before upload is simpler and keeps the original off the server entirely.

Limitations

One photo, one host and default WordPress settings. Themes and plugins can register more sizes (some add a dozen), multiplying the storage numbers above, and hosts with a different image library (Imagick or GD, with or without AVIF support) will behave differently. File sizes of generated images depend on WordPress’s quality defaults, which can be changed with the wp_editor_set_quality filter.

Data and files

Download wp-upload.csv (17 rows, 3.1 KB) · Method: testing methodology. Photo: image credits.

When Alt Text Breaks srcset: A WordPress sizes Quirk

WordPress checks for an existing sizes attribute by searching the whole img tag, alt text included. Five of our images lost sizes that way and downloaded full-size files on desktop.

WordPress Workflow 4 min read