Skip to content
  • FG-91
  • 13 min read
  • Last checked November 7, 2026

WordPress Thumbnails Missing or Blurry, Wrong Image Sizes, or a Slow Media Library

Gray squares in the Media Library, soft or pixelated images, crops that do not fit, or a grid that takes ages to load. Find which image size is wrong and regenerate safely.

Run the health check

Your images are not broken outright, they are just wrong. The Media Library shows gray placeholders or the full file where a thumbnail should be. Product or post grids look soft and pixelated, especially on high resolution screens. Featured images are cropped in odd places, or every image in a gallery is a slightly different shape. Or the Media Library grid takes many seconds to load, and the dashboard slows to a crawl whenever you add an image to a post.

All of this traces back to how WordPress turns one upload into many files. Every upload is copied into a set of registered sizes, and themes, page builders and the browser pick which copy to show. When a size was never created, was created for an old theme, or was squeezed too hard by an optimizer, you see it on the page. When there are tens of thousands of uploads with large metadata, you feel it in the admin. This guide works through each case. If images are not loading at all (broken icons, 404s), FG-48 covers that; for images that make the page slow to load for visitors, see FG-11.

What is happening

When you upload an image, WordPress saves the file, then asks the image editor (Imagick or GD) to make a smaller copy for each registered size. Each copy gets a suffix with its dimensions, such as photo-300x200.jpg. The list of sizes and their file names is stored in the attachment’s _wp_attachment_metadata field.

Size name Default dimensions Notes
thumbnail 150 x 150, cropped Settings, Media
medium Up to 300 x 300 Settings, Media
medium_large 768 wide, any height Not shown in Settings; used mainly in srcset
large Up to 1024 x 1024 Settings, Media
1536x1536, 2048x2048 Up to those dimensions Added in WordPress 5.3 for high resolution screens
Theme and plugin sizes Whatever they register Created with add_image_size(), often cropped to a fixed shape

Three rules explain most surprises:

  • Sizes are made only at upload time. Changing Settings, Media, or switching to a theme that registers new sizes, does nothing to images already uploaded. Old images simply do not have the new sizes, and WordPress falls back to the nearest larger file or the full image.
  • WordPress never enlarges. If the original is smaller than a size, that size is skipped.
  • Big uploads are scaled. Since WordPress 5.3, an image wider or taller than 2560 pixels is scaled down to fit 2560 and saved as photo-scaled.jpg, which becomes the “full” size. The untouched original is kept on disk and recorded as original_image in the metadata. The threshold can be changed with the big_image_size_threshold filter.

On the front end, WordPress adds a srcset attribute listing every stored size with the same aspect ratio as the one requested (up to 2048 pixels wide by default), plus a sizes attribute describing how wide the image is displayed. The browser then picks the smallest file that is sharp enough for the screen. Cropped sizes with a different shape are left out of srcset, which matters in Step 3.

JPEG copies are saved at quality 82 by default and WebP copies at 86 in current versions, adjustable with the wp_editor_set_quality filter. The original upload is not recompressed by WordPress itself.

Before you start

You need an administrator login. For regeneration and checks you need SSH with WP-CLI; without it, a regeneration plugin such as Regenerate Thumbnails does the same job in the browser, more slowly. Back up wp-content/uploads and the database first: regeneration rewrites metadata and, by default, deletes size files that are no longer registered.

How to run commands in this guide:

  • Server commands run in an SSH terminal in the site folder (the one with wp-config.php). Your host may name the tool wp or wp-cli.
  • Browser checks use developer tools: right-click an image and choose Inspect, and use the Console tab.
  • Large regenerations take time. Run them inside screen or tmux on the server if your SSH connection may drop.

Step 1: Identify which file the page is showing

On the problem page, right-click the image and choose Inspect. With the img element selected, run this in the Console tab:

[$0.currentSrc, $0.naturalWidth + 'x' + $0.naturalHeight, $0.clientWidth + 'x' + $0.clientHeight, window.devicePixelRatio]

This runs in the browser console. $0 means “the element selected in the Elements panel”, so there are no placeholders.

  • currentSrc is the file the browser actually chose from srcset.
  • naturalWidth and naturalHeight are the file’s real pixel dimensions.
  • clientWidth and clientHeight are the size it is displayed at in CSS pixels.
  • devicePixelRatio is 1 on a standard screen and 2 or 3 on high resolution phones and laptops.

Good output: the natural width is at least the displayed width multiplied by the pixel ratio, for example a 768 pixel file displayed 360 wide on a ratio 2 screen. Bad output: a 300 pixel file displayed 600 wide on a ratio 2 screen, which needs 1200 pixels and will look blurry. The file name suffix tells you which size was used, and that points to the step that applies.

Step 2: Thumbnails missing in the Media Library or on the site

Confirm what exists for one image

wp media image-size
wp post meta get ATTACHMENT_ID _wp_attachment_metadata --format=json

Run these over SSH in the site folder.

  • wp media image-size lists every registered size with width, height and crop, including theme and plugin sizes.
  • ATTACHMENT_ID is the image’s ID. In the Media Library, open the image; the URL ends with item=ATTACHMENT_ID (grid view) or post=ATTACHMENT_ID (edit screen).
  • --format=json prints the stored metadata, including a sizes object with each generated size and its file name.

Good output shows a sizes entry for each size smaller than the original. An empty sizes object, or missing names that should be there, confirms the sizes were never created. If the metadata lists files that are not on disk, the files were deleted or offloaded (Step 6).

Why sizes go missing

  • The upload ran out of resources. Large photos need a lot of memory to resize. WordPress then shows “The server cannot process the image. This can happen if the server is busy or does not have enough resources to complete the task. Uploading a smaller image may help. Suggested maximum size is 2560 pixels.” The file is saved but some sizes are not.
  • No working image editor. In Tools, Site Health, Info, Media Handling, check Active editor. If neither Imagick nor GD is available, no sizes can be made at all. The “ImageMagick supported file formats” and “GD supported file formats” rows show whether WebP and AVIF can be processed.
  • The theme changed. The new theme’s sizes do not exist for older uploads.
  • A plugin disabled sizes, through the intermediate_image_sizes_advanced filter, often in a performance plugin’s “disable image sizes” setting.

Regenerate the missing sizes

wp media regenerate --only-missing --yes

Run this over SSH in the site folder.

  • --only-missing creates only sizes that do not yet exist and leaves existing files alone. It is the safest option and much faster on large libraries.
  • --yes skips the “are you sure” prompt, which only appears when you do not list IDs.

Good output ends with “Success: Regenerated COUNT of COUNT images.”, where COUNT is the number processed. Lines saying an image could not be processed name the attachment; test it alone with wp media regenerate ATTACHMENT_ID and check the PHP error log for memory errors at that moment.

Step 3: Blurry images on the front end

Blurry images almost always mean a small file displayed large. Step 1 tells you which. The usual reasons:

  • The theme or builder asks for a small size. A blog grid template that calls the_post_thumbnail( 'medium' ), or a page builder image element set to “Medium”, requests a 300 pixel file. If the column is 600 pixels wide, the browser stretches it. Change the element’s image size setting to Large or Full, or, in theme code, request a larger size.
  • Cropped sizes have no srcset. A theme size cropped to, say, 400 x 400 has no larger siblings with the same shape, so srcset is empty and high resolution screens get only that file. Register a 2x version of the crop (for example 800 x 800 with the same crop) and regenerate that size.
  • The sizes attribute is wrong. If sizes says (max-width: 300px) 100vw, 300px but the image is displayed 900 wide, the browser picks a small file. Themes and builders set this; WordPress 6.7 and later add sizes="auto" to lazy-loaded images so the browser can use the real layout width.
  • CSS stretching. Rules such as width: 100% on an image inside a wide container, or object-fit: cover on a tall box, scale small files up. Inspect the element and check the computed width.
  • The original was small. If the upload itself was 800 pixels wide, nothing can make it sharp at 1600. Replace it.

Regenerate just one size

After registering a new size or changing one, regenerate only that size:

wp media regenerate --image_size=SIZE_NAME --yes

Run this over SSH in the site folder.

  • SIZE_NAME is a name from wp media image-size, such as large or a theme size like THEME_CARD_SIZE. Repeat the flag to regenerate several sizes at once.
  • With --image_size, only the named sizes are rebuilt; all other size files are left as they are.

Good output shows “Regenerated “SIZE_NAME” thumbnail” lines, and “No “SIZE_NAME” thumbnail regeneration needed” for images that already had a correct file.

Step 4: Wrong sizes or crops after changing Settings or themes

If you changed Settings, Media or switched themes and want every image rebuilt to the new sizes, run a full regeneration. Read the warning first.

Warning: a full regeneration deletes every existing size file that is not part of the current size list, for every image in the library, unless you add --skip-delete. Posts that link directly to an old size file (common in older posts and page builder layouts) will then show broken images.

wp post list --post_type=attachment --post_mime_type=image --format=count
wp media regenerate --skip-delete --yes

Run these over SSH in the site folder.

  • The first counts image attachments, so you know how many will be processed and can estimate the time.
  • --skip-delete keeps old size files on disk. Use it unless you are sure nothing links to them. It costs disk space but cannot break existing pages.
  • --delete-unknown (only in recent WP-CLI releases; check wp cli version if it is not recognized) does the opposite job: it only removes files for sizes that are no longer registered, without regenerating. Use it later, once you have checked that no content references them.

To check whether content links to specific sizes, search post content for size suffixes:

wp db query "SELECT ID, post_title FROM PREFIX_posts WHERE post_content REGEXP '-[0-9]+x[0-9]+[.](jpe?g|png|webp)' AND post_status = 'publish' LIMIT 20;"

Run this over SSH in the site folder. PREFIX_ is your table prefix from wp db prefix (often wp_). The pattern matches file names with a size suffix like -600x400.jpg. Any results mean pages that depend on size files, so keep --skip-delete. Page builders that store layouts in post meta need a search of PREFIX_postmeta as well.

Step 5: Images over-compressed by an optimization plugin

If images look blocky, banded or smeared (especially skies, gradients and skin tones), an optimizer may have compressed them too hard. Most optimization plugins have a “lossy” or “aggressive” level and some recompress the original upload as well as the sizes.

  1. Confirm it. Compare the file size of an affected image with a fresh upload of the same original with the plugin paused. A dramatic size difference plus visible artifacts confirms over-compression.
  2. Restore from the plugin’s backups. Most optimizers can keep a copy of each original and offer a per-image or bulk restore. This only works if the backup option was on when the images were optimized.
  3. Without plugin backups, restore wp-content/uploads from a host backup taken before the optimizer ran, or re-upload the originals from your own files.
  4. Regenerate with wp media regenerate --yes (with --skip-delete if Step 4 applies) once the originals are back, then re-optimize at a gentler level.

Before bulk optimizing again, test a handful of images at each compression level and look at them at 100 percent zoom on a high resolution screen.

Step 6: WebP and AVIF settings

WordPress accepts WebP uploads (since 5.8) and AVIF uploads (since 6.5) if the server’s image editor supports them; check the supported formats rows in Site Health, Media Handling. Since 6.7, HEIC uploads are converted to JPEG for the sizes by default, through the image_editor_output_format filter.

Core does not convert JPEG uploads to WebP by default. You can do it with that same filter, with the official Modern Image Formats plugin (from the WordPress Performance Team), or with an optimization plugin or CDN that serves WebP or AVIF on the fly. Problems to watch for:

  • Two systems converting at once (a plugin and a CDN, or two plugins) give double-compressed or mismatched files.
  • Rewrite-based delivery, where the URL stays .jpg but a .webp is served, needs the cache and CDN to vary on the browser’s Accept header. If not, a browser that cannot show WebP may be served one from the cache.
  • Converted copies made by a plugin are not always regenerated by wp media regenerate; rerun the plugin’s own bulk process after regenerating.

Step 7: A slow Media Library

The grid view loads attachments through an AJAX request to admin-ajax.php with the action query-attachments, and builds the month filter with a query over every attachment. On libraries with tens of thousands of items, large postmeta tables and slow storage, both can take seconds.

wp post list --post_type=attachment --post_status=inherit --format=count
wp db size --tables --size_format=mb
du -sh wp-content/uploads

Run these over SSH in the site folder.

  • The first counts attachments (they use the inherit status).
  • wp db size --tables shows each table’s size; --size_format=mb prints megabytes. A postmeta table far larger than posts often comes from attachment metadata and plugin data per image.
  • du -sh prints the total size of the uploads folder in a readable unit.

To see the slow part, open developer tools, Network tab, filter for admin-ajax, and load the Media Library. Check the time of the query-attachments request. With Query Monitor installed, open its panel on the Media screen to see the slowest queries and which component ran them. FG-34 covers general database bloat; here is what is specific to media:

  • Switch to the list view (the icon at the top of the Media Library), which pages results on the server.
  • Remove unused attachments with care: an image “unattached” to any post may still be used in a page builder layout, a widget or theme settings. Use a media cleanup plugin’s report and keep a backup.
  • Developers can skip the month query by returning a fixed list through the media_library_months_with_files filter, which WordPress added for exactly this problem on very large libraries.
  • Plugins that add many meta rows per image (optimizers, offload tools, SEO image tools) add up. Check their settings for options to stop storing per-image data you do not use.

Advanced: Offloading media to object storage or a CDN

For very large libraries, many sites move uploads to S3-compatible object storage and serve them from a CDN. An offload plugin copies each upload and its sizes to the bucket and rewrites URLs. This frees disk space and moves image traffic off the server, but it changes how every step above works:

  • Regeneration needs the originals. If the plugin deleted local copies, regeneration must download the original first. Check whether your offload tool supports this, or keep local copies.
  • Metadata is still local. The database still holds every attachment and its metadata, so offloading does not make the Media Library grid faster by itself.
  • Removing the plugin breaks URLs unless files are copied back and URLs rewritten first. FG-48 covers broken image URLs after such changes.
  • A CDN image service that resizes on request (by URL parameters) can replace many registered sizes. Then you can register fewer sizes in WordPress and generate less on upload.

Whatever you choose, keep the number of registered sizes in check. Every size is another file per upload, more work per upload, and more rows to scan. Run wp media image-size and question every theme or plugin size you do not actually use.

When to contact your host

Open a ticket if uploads repeatedly fail with the “server cannot process the image” message, if Site Health shows no active image editor or missing WebP or AVIF support you need, if regeneration stops with memory or time limit errors, or if you need wp-content/uploads restored from before an optimizer ran. Include:

  • The UTC time of a failed upload or regeneration, and the attachment ID or file name.
  • The Media Handling section from Site Health, Info (use Copy site info to clipboard).
  • Any PHP error log lines from that time, especially “Allowed memory size exhausted”.
  • The number of attachments and the uploads folder size from Step 7.

To check how your images load for visitors, try our diagnostic tools.

Still stuck?

Print a free one-page checklist to keep, or open the Emergency Room if the symptom does not match.

Get the free checklists

Keep reading

All field guides

Search the field manual

What is going wrong?

Press / to search from any page, Esc to close