WordPress Image Sizes: a Ticking Time BOMB?

This is an issue that affects WordPress websites that have lots of uploaded images, such as news websites, photographers, food blogs, etc. So if you find yourself uploading lots of images into your WordPress media library every month – keep reading.


1. The Default WordPress Image Sizes from Media Settings

Let’s start with a bit of history.

When WordPress was first introduced, it came with a very cool and appreciated feature: it would automatically create images of three different sizes for each image that you upload. WordPress made it easy to upload large photos without worrying about their size, because you could easily insert smaller, cropped versions into your content.

You simply go to Dashboard > Settings > Media and choose the values for these 3 core sizes: Thumbnail, Medium, Large. Simple enough.

The average user didn’t have to worry too much about uploading that DSC_3795.jpg file straight from their camera, probably a 4000x2666px ~8MB file. No matter what size the uploaded original had, you simply choose the Thumbnail or Medium size and import it into your content.

When the time came to switch to a different WordPress theme, sometimes users had to change some of their image sizes, so as to better fit the new layout and design. Maybe the content is now 100px wider, so those Medium 600×400 images should now be 700×450.

A new problem popped up: changing the size in Settings > Media doesn’t do anything about images that already exist in the Media Library. These old images were created using old sizes, so older posts don’t look as good.

To help in that transition developers started recommending plugins like Regenerate Thumbnails, a free WordPress plugin (active on over 1 million websites) that creates image files using current Media settings for all existing images.

Now with a bit of adjustments and edits users could continue working on their websites without worrying about badly-sized images. Problem solved.


2. And then add_image_size() was introduced in WP 2.9

WordPress version 2.9 was released on December 18, 2009.

One of the new functions that proved to be crucial to the huge success and adoption of WordPress was the add_image_size() function.

This function allowed theme developers to define even more custom image sizes, but this time users did not have easy access to altering these custom sizes.

So if a theme developer wanted to create a custom block in their theme that would display the latest post with a 100×100 thumbnail next to it – they would simply add a line of code into their theme like this one:

<?php
add_image_size( 'thumb-loop-small', 100, 100, true );
?>

Developers could specify this size in their custom section and they were pretty sure that everything would work as expected. Users couldn’t just easily change the size to 300×50, as they had to get into the theme’s template files, as in edit actual code.

This signaled the start of a race for the most original placement of content on a single page. Theme developers went crazy creating blocks and widgets with custom content everywhere.

Allow me to illustrate with one of my earliest magazine WordPress themes (Telegraph) released in January of 2011, back when 960px was the norm. I drew up some stuff in Photoshop, looked for ways to organize content and images, and I came up with a homepage that looked like this:

<?php 
add_image_size( 'widget-photo-category', 300, 200, true ); 
add_image_size( 'homepage-slider', 280, 160, true ); 
add_image_size( 'quick-posts', 145, 100, true ); 
add_image_size( 'loop-main', 100, 80, true );
?>

In this theme I had defined 4 custom image sizes. Call me a bad designer or planner, but hey, we all make mistakes.


3. The Problem with Image Sizes in WordPress

Now let’s look at the issues that can be caused by all these image sizes in WordPress. We will continue with the simple example of Telegraph theme from the above, which uses 4 custom image sizes.

When a user of that theme would upload a 1600×1200 image into WordPress, here are the images that WordPress will create and keep on the server forever:

  1. /uploads/2018/08/beautiful-photo.jpg — the original photo is kept
  2. /uploads/2018/08/beautiful-photo-1024×1024.jpg — the default large size
  3. /uploads/2018/08/beautiful-photo-300×300.jpg — the default medium size
  4. /uploads/2018/08/beautiful-photo-150×150.jpg — the default thumbnail size
  5. /uploads/2018/08/beautiful-photo-300×200.jpg — the custom ‘widget-photo’category’ size
  6. /uploads/2018/08/beautiful-photo-280×160.jpg — the custom ‘homepage-slider’ size
  7. /uploads/2018/08/beautiful-photo-145×100.jpg — the custom ‘quick-posts’ size
  8. /uploads/2018/08/beautiful-photo-100×80.jpg — the custom ‘loop-main’ size

A total of 8 files will be created and kept on your web hosting server just because of a single uploaded image. Now imagine if you have 5 photos in each post, that’s 40 files per post.

If you are a food blogger or a photographer, it is not uncommon to have 20-30 photos in a single post. Multiply that by 8 (in this particular case) and you get hundreds of file on the server just because of a single post or page.

Here’s an example of a very simple photographer blog and the amount of files generated on the server:

There are 50 photos in this standard post. Each uploaded photo takes up 9 files on the server. That’s 450 files on the server from a single post that has zero incoming traffic.

Another customer of mine is using a VERY popular magazine WordPress theme and currently has 2,191 uploaded image files on his WordPress blog.

His theme and plugins have a combined number of 19 custom image sizes. Including the original and default media sizes, there are a total of 23 files for each of his uploaded image. 2,191 x 23 = 50,439 files.

A small 55KB image actually takes up 650KB because of all the alternatives sizes created for no real purpose.

Just look at this “beauty” and tell me if this looks sustainable:

Why do I care? I have unlimited hosting disk space!

Not so fast.

True, many web hosting providers advertise their packages as unlimited disk space. But we all understand that unlimited is not really unlimited. There are other limitations that they will impose (and for good reason).

For example HostGator’s hosting packages (incidentally I strongly recommend against using HostGator, here’s why):

Even though the actual disk space is “unmetered”, you lose some features once your number of inodes reaches a certain number.

Think of inodes as unique files that are in your hosting account. Each file that exists on the server is one inode. Each email that you receive and let it stay on the server is equal to 1 inode.

Using the photographer’s website from the example above, that single post adds 450+ inodes towards the account’s total usage.

And what happens once we reach our inode limit? Nothing horrible, but something bad nonetheless. Here’s the notice that you get if you’re hosted with HostGator:

Files 156360 / 100000
Size 15352.70 / 20000 MB
Error: If Backups ran now, your account would NOT be backed up.

In translation: if you exceed your inodes limit (in this case: 100,000) then automatic backups are not run. HostGator absolves themselves of risks and responsibilities, so you are on your own.

Here’s another example of SiteGround, a hosting that I really like (this very website is hosted with them).

Even though their hosting plans comparison doesn’t mention anything about an inodes limit, as a customer we find that limit in cPanel:

In this case the limit is 450,000 which sounds a lot. But once you think of the 450 files per post example, that becomes less impressive.

Now that we’ve determined and understood the issue and the risks that come with it, let’s work towards a solution.


4. How to Identify Custom Images Sizes in Your Theme?

There are two good ways to identify which custom sizes are currently defined on your WordPress website.

4.1. By checking your /wp-content/uploads/ folder

The surest way is to upload a large ~2000x2000px test image and then check the corresponding upload folder for all alternative files that were created.

You can either log in using a FTP client (like FileZilla) or by using the File Manager module from cPanel.

Go to /wp-content/uploads/CURRENT YEAR/CURRENT MONTH/ and find the file that you have just uploaded. Here’s what it would look like in FileZilla:

As you can see in this case, the original file is the largest (naturally), and then there are 6 extra files. So we deduct the 3 built-in media sizes (thumbnail, media and large) and we’re left with 3 extra custom sizes, which is not ideal.

4.2. By checking your theme’s files

Another way would be to look out for the add_image_size function in your theme’s files. Most WordPress themes define custom sizes somewhere in the functions.php file.

So go to Appearance > Editor > functions.php and do a search in your browser’s tab (CTRL+F) for the function add_image_size. The complete code looks similar to the one at the beginning of this post.

This method will not work if you don’t have permissions to edit theme files, so the page Appearance > Editor will not even be available to you. This method will also not work if your theme uses a more sophisticated file structure and defines custom images sizes elsewhere.


5. How do I reduce the number of generated files?

There are a few good ways to reduce the number of custom image files that are generated by WordPress.

Whichever method you choose, it is best if you know your website well. You should be aware of your content blocks, sections, custom templates, etc.

5.1. Disable the default WordPress Media sizes

As stated earlier, WordPress will usually create a minimum of 4 files for each uploaded media file: the original, large, medium and thumbnail versions.

Many websites don’t even use the large/medium/thumbnail sizes, as they are usually used for inserting the images into the page/post content. Most themes define their own custom sizes.

Disabling the default Media sizes is simple as pie.

Go to Dashboard > Settings > Media and set the width and height to 0 (zero) for the sizes that you want to disable. Clicking on “Save Changes” will not do anything to your existing files, it will only prevent WordPress from generating these sizes on future media file uploads.

Is this method for me?

It depends. Let’s look at my NewsToday Magazine WordPress theme as an example.

The theme defines one custom size:

<?php 
add_image_size( 'newstoday-thumb-featured', 740, 480, true ); 
?>

Images of this size are displayed in two places: on the homepage for the first featured post, but also on inner post pages too (inside posts). So these images are not used for a single, temporary purpose (for a short-time spot on the homepage), rather they are used throughout the website at all times.

This is a better way of using and implementing custom image sizes. Many users of my theme won’t even need to insert other images into the post, unless they have images with a different ratio (portrait-sized).

5.2. Disable custom image sizes defined in the theme

If you have determined that your current WordPress theme defines too many custom sizes, especially ones that you don’t even use, then consider disabling them.

The best way would be to use a child theme and make a couple of calls to the remove_image_size() function.

<?php 
add_action('init', 'ilovewp_remove_image_sizes'); 

function ilovewp_remove_image_sizes() {
    remove_image_size('custom-image-size-name');
}
?>

Why use a child theme?

If you edit your theme’s template files directly, then you will lose your changes on your next theme update, unless you don’t intend to update your theme.

5.3. Switch to a different theme

If you’ve been considering switching to a different theme and your current theme uses too many custom sizes, then maybe now is a good time to make the switch. You can find some interesting WordPress themes here.

6. I have disabled custom sizes and nothing happened

I mentioned this before: simply changing, adding or disabling custom image sizes in WordPress doesn’t do anything about your existing images. You now have to install a WordPress plugin to take some actions in regards to your existing images.

I recommend using the Force Regenerate Thumbnails, which works a little differently from the Regenerate Thumbnails plugin.

It doesn’t just generate new images for your new sizes, it also deletes all your image versions that are no longer in use. So it deletes all versions except the originals and then generates new thumbnails that are only currently active.

I was tasked with fixing some issues on a photography blog that was having performance issues. Upon inspection I have discovered 11 custom images sizes in a theme that wasn’t even using them.

After some optimization, the plugin had to delete 15 files and then regenerate only 4 instead for each media file.

Two hours later there were 90,000 less files and about 10 GB worth of disk space. Even if your web host doesn’t limit your number of inodes or the disk space, consider that your weekly/monthly backups will be much lighter and easier to manage.


7. An Open Call to Theme Developers

If you are a WordPress theme developer or just doing some custom work, please be careful with the add_image_size() function.

7.1. Plan better and use less custom image sizes

I know it is very easy to just slap a couple of them for each little thing that you thought of, but maybe there is a way to re-use an already defined size? Usually there is.

When you are in the planning phase consider using images with the same ratio. So if you have a block that displays square 400×400 images, then consider making your other blocks use square images too. Then you could load the larger images and then scale them down via CSS.

Scaling down a 400×400 image to 250×250 is easy and simple, while scaling down a 400×400 to 300×150 is not.

7.2. Include information about your custom sizes in the documentation

If you define and use custom image sizes in your theme then it is best to state that on the documentation page for the theme (or in readme.txt). Do this especially if you define custom sizes in a different file other than functions.php.

7.3. Add your custom image sizes to the Media Import selector

And finally, if you decided that custom image sizes are required and WordPress creates them, then you should add them to the Add Media size dropdown selector.

You can add something like this to your functions.php:

<?php
add_filter( 'image_size_names_choose', 'ilovewp_custom_sizes' ); 

function ilovewp_custom_sizes( $sizes ) { 
  return array_merge( $sizes, array( 
    'ilovewp-thumb-featured' => __( 'Custom Size: Slideshow Size', 'textdomain' )
    ) );
}
?>

Now your authors and users should be able to use your custom image sizes anywhere they please, not just where you hard-coded it into.


In Conclusion

I understand that some readers might consider this topic a little trivial and not worth the 2,200+ words written here.

But please stop for a minute and consider the potential footprint of badly implementing custom image sizes. It is estimated that there are over 70 million WordPress websites.

When you consider the potential resource gains from properly planning and using image sizes in WordPress, we might be able to shave off tens of billions of files that just sit there, idly, using up energy.

No matter what your reasoning is, be it to reduce your hosting bill or to reduce your environmental footprint, there’s no reason to keep creating unnecessary data.

Peace!

Previous Article
Next Article

8 Replies to “WordPress Image Sizes: a Ticking Time BOMB?”

  1. Yuda

    God, I’ve been waiting for this post for more than 10 years! Can’t believe this issue is not being discussed more often and not dealt with more easily.
    As a developer, the amount of work required to maintain a clean uploads folder for my clients is quite substantial, using all of the above plugins. Plus you really need to know what you are doing, especially when you switch themes.
    For a less seasoned dev guy this is probably even harder, and for a client it is close to impossible.
    I would really love seeing WP dealing better with image sizes, but let’s get over Guttendrama first 🙂
    Thanks for a great post!

  2. Knut

    Yes! And something else in the same problem – when the number of inodes in a directory folder rises above a limit (number depending on filesystem configuration) the directory access uses more time and memory. This small problem is most visible in DMS solutions where document storage is built to distribute the inodes evenly over a number of folders and never over the limit from the old Unix filesystem. For WP it is only the images that gets into the trouble zone 😀

  3. Roy Emory

    How do I discover the ‘custom-image-size-name’ so as to disable them in my child theme function.php? I searched through all of my plug-in files for ‘add_image_size’ but found nothing. (I see in the Uploads folder 6 additional image sizes in addition to the thumbnail, medium, and full sizes for every image that has been uploaded)

    • Roy Emory

      Nevermind. The theme had the add_image_size() function… Good article, I’ve been wanting to remove the extra files in the uploads folder for quite some time.

  4. MDIYer

    Thanks for this! Completely agree on the sentiment. This is a very brute-force way to deal with images. Hopefully eventually things will change towards efficiency.

  5. Vel

    It’s not developers fault to have so many image sizes, but designers, so change “An Open Call to Theme Developers”, to “An Open Call to Theme Designers” 🙂

  6. Goran

    Last week I had the same problem with the WP’s image sizes. It’s complete nonsense and a lot of redundancy and unnecessary files.
    Anyway, after going through a bunch of StackOverflow I ran into a really useful plugin, although it can be coded, without using a plugin. The plugin is Fly Dynamic Image Resizer.

    It basically fools WP system for creating images and generates only necessary image sizes, when they are needed. Once the image is created for the first visitor, it will be served from the server since it’s already in the media library. For me, it’s a life saver since I can easily create different image sizes for specific images, and skip the sizes I don’t need.
    Plus, it works automatically when you add a new image size in code. No need to regenerate thumbnails.

    • Dumitru Brinzan

      I’m not sure why this would be a good solution.
      Once a bot visits your page, it would generate the images and then have them there on the server, forever.
      You simply postpone the creation of files from the moment of upload to a few hours/days in the future.
      This doesn’t resolve the problem of having all these generated images on the server.

      Or did I misunderstand something?

Leave a Reply

Your email address will not be published. Required fields are marked *