← Back to blog

WordPress thumbnail sizes: the six copies core makes, and what they cost you

The SandyWP team 5 min read

WordPress does not make three thumbnail sizes. On a clean WordPress 7.1.3 install with Twenty Twenty-Five, it registers six, and then writes a seventh file by shrinking your original.

We measured it on a throwaway install rather than quoting a guide. One 4000x3000 JPEG of 8,073,383 bytes went in.

Eight files totalling 11,534,950 bytes came out.

The six sizes core registers, read off a live install

wp_get_registered_image_subsizes() is the honest answer to this question, because it returns what this install will actually generate. Run over SSH on a fresh sandbox:

thumbnail:  150x150   crop=yes
medium:     300x300   crop=no
medium_large: 768x0   crop=no
large:      1024x1024 crop=no
1536x1536:  1536x1536 crop=no
2048x2048:  2048x2048 crop=no

Three of those are not in Settings > Media. medium_large was added in WordPress 4.4 and has no UI at all, though its width is a real option you can read with wp option get medium_large_size_w.

1536x1536 and 2048x2048 arrived with responsive images. They exist so srcset has something large to offer a retina screen, and they are the two that dominate your disk.

What one upload actually writes

Here is the full output directory after importing that single 4000x3000 photo, sorted by size:

     4,698  photo-150x150.jpg
    15,319  photo-300x225.jpg
   120,156  photo-768x576.jpg
   245,059  photo-1024x768.jpg
   480,828  photo-1536x1152.jpg
   948,211  photo-2048x1536.jpg
 1,647,296  photo-scaled.jpg
 8,073,383  photo.jpg

The six sub-sizes come to 1,814,271 bytes between them. That is the part people expect.

The surprise is the bottom two lines. photo-scaled.jpg is a 2560x1920 copy, and it is the file WordPress treats as "full" everywhere in the front end.

Your real original is kept beside it, untouched and unserved.

Why there is a -scaled file you did not ask for

Since WordPress 5.3, any upload with a side over 2,560 pixels gets downscaled, and the result becomes the attachment's main file. The threshold is the big_image_size_threshold filter, and it still returns 2560 on 7.1.3.

You can see the swap in the attachment metadata. The recorded dimensions are 2560x1920, not 4000x3000, and file points at photo-scaled.jpg while original_image holds photo.jpg.

That original is not dead weight. It is what makes regeneration possible later, which the next section depends on.

Changing the sizes does nothing to existing images

Edit Settings > Media and every image already in the library keeps the files it has. The settings only decide what happens on the next upload.

Every guide that ranks for this phrase says that much. None of them say what to do about it beyond "install a regeneration plugin", and the command line answer is better.

wp media regenerate deletes orphaned sizes, and --only-missing does not

This is the part worth knowing, and we found no ranking page that mentions it.

When a theme registers a custom size with add_image_size(), uploads get that file too. Switch themes and the size stops being registered, but the files stay on disk, counted in no backup budget and referenced by nothing.

We registered a 1600x900 agency-hero size, regenerated, then removed it, which left the directory at 9 files instead of 8. Then:

wp media regenerate --yes
# 8 files: photo-1600x900.jpg is gone

wp media regenerate --yes --only-missing
# 9 files: "No thumbnail regeneration needed", the orphan stays

Plain regenerate rebuilds the metadata from scratch, so files that no longer correspond to a registered size get deleted. --only-missing checks whether anything is absent, finds nothing absent, and exits without touching the orphan.

So the flag that looks like the safe, fast option is the one that leaves the mess. Use plain regenerate when you have just changed sizes, and --only-missing only when you are filling gaps after a failed import.

The original is what lets you change your mind

We deleted photo-scaled.jpg and ran wp media regenerate --yes. It came back, rebuilt from photo.jpg.

That is the practical argument for leaving big_image_size_threshold alone and keeping your originals. Strip them to save disk and every future size change is permanent, because there is nothing left to resize from.

If disk is the real constraint, the honest fix is uploading smaller originals, not deleting the ones you have.

Run it on a copy first, not on 20,000 images

wp media regenerate rewrites every file in your uploads directory. On a large library it runs for hours, holds Imagick memory the whole time, and there is no undo.

Two things go wrong in practice. The first is memory: a 6000px source with Imagick loaded will exhaust a 256 MB limit part way through, leaving a library half regenerated.

See increasing the WordPress memory limit before a big run.

The second is ownership. Run the command over SSH as root and every new file is root-owned, so PHP can no longer rewrite or delete them, and the next regeneration fails quietly.

On SandyWP sandboxes commands run as the web user, and the files we measured came out www-data:www-data, which is the behaviour you want. If you have already hit this on a real server, WordPress file permissions covers the repair.

The sensible order is to clone the live site, run the regeneration on the clone, check the output and the timings, then do it for real. Cloner exists for exactly this shape of job, and a sandbox is cheap enough that getting the size list wrong twice costs nothing.

A size audit you can run in one command

Before changing anything, find out what this install will generate and what it has already written:

wp eval 'foreach ( wp_get_registered_image_subsizes() as $n => $s ) {
  printf( "%s: %dx%d crop=%s\n", $n, $s["width"], $s["height"], $s["crop"] ? "yes" : "no" );
}'

du -sh wp-content/uploads
find wp-content/uploads -name '*-scaled.*' | wc -l

The first tells you how many files your next upload becomes. The third tells you how many originals are sitting beside a scaled copy, which is usually the biggest single number in the directory.

Both are two-second commands with WP-CLI preinstalled, and both are worth running before you decide anything about image sizes.

When thumbnail sizes are not your problem

If pages are slow because images are heavy, the registered size list is rarely the cause. The cause is usually a template requesting full where large would do, which is a theme fix, not a settings fix.

And if you are chasing disk usage on a host with a quota, the sub-sizes are the small half of the bill. The originals are the other 70 percent, and no amount of thumbnail tuning changes that.

Measure first. The commands above take longer to read about than to run.