WordPress Images

How Big Should an Image Actually Be Before You Upload It

A 4032 pixel phone photograph in a 760 pixel column makes the browser download 12.2 million pixels to paint about 430,000 of them. What that costs in bytes and in memory, how to read the display width your theme actually uses, where the WordPress 2560 pixel safety net stops, and a browser tool that does the resizing before the upload.

How Big Should an Image Actually Be Before You Upload It

A phone photograph arrives at 4032 by 3024 pixels and something like 4 MB. The column it is going to sit in is 760 pixels wide. The browser downloads all 12.2 million pixels, decodes them into roughly 46 MB of memory, and then discards more than nine tenths of them to draw the picture at the size your theme asked for.

On a WordPress site that is otherwise healthy, that one habit is the most common reason pages feel slow. Not the theme. Not the plugin count. Photographs uploaded at the size the camera produced them, sitting in a column a fifth as wide. If you are working through the diagnostic order for a slow site, this is the first thing to rule out, because it is cheap to fix and it is usually the answer.

The fix is one step, and it belongs before the upload rather than after. Resize the file on your own machine, then upload the smaller file. Everything WordPress does next, the sub-sizes, the srcset, the scaled copy it quietly makes for you, then works from a sensible original instead of a huge one.

Resize first, upload second

The tool below does that job. Drop one image or forty onto the target, set a target width, press Resize, and download the results. It runs entirely in your browser: every file is decoded, redrawn on a canvas and re-encoded on your own machine. Nothing is uploaded, nothing is queued, and no account is involved.

The defaults are the ones most content images want: 1600 pixels wide, quality 82, never enlarge, keep the original format. If you stop reading here, that alone fixes the problem for the majority of uploads. The rest of the article is about which number you should actually be using, what WordPress does to your file after you hand it over, and the handful of cases where the tool needs help.

Image resizer and compressor

Drop in photos, set a width and a quality, get smaller files back. Nothing is uploaded: every image is decoded, resized and re-encoded inside this browser tab.

Drop images here or press Enter to pick files. JPEG, PNG, WebP or GIF, several at once.

No images added yet
WunderPaint
The Dynamic Design and Automation Studio
WunderPaint is a layered image editor for your WordPress media library. WunderPaint Studio is the same thing in any browser, free and without an account.

What 4000 pixels actually cost

Pixel count drives everything else, and it rises with the square of the width. Halving the width does not halve the picture, it quarters it. Going from 4032 pixels wide to 1600 leaves you with 15.7 percent of the pixels, and going to 1200 leaves under 9 percent.

File size follows, though not in a straight line, because a JPEG stores detail and a busy photograph compresses worse than a plain one. As a working figure, a 12 megapixel phone photograph that leaves the camera at 3 to 5 MB lands between 200 and 400 KB at 1600 pixels wide and quality 82, and between 100 and 200 KB at 1200. Ten of those on a page is the difference between two megabytes and twenty.

Memory is the part nobody measures. A decoded bitmap costs four bytes per pixel no matter how well the file compressed, so the 4032 pixel photograph occupies about 46 MB while the browser is painting it, and the 1600 pixel version about 7 MB. That cost is paid on the visitor’s device, and on a mid range phone with several such images in one article it is the difference between scrolling and stuttering.

Table comparing one 4032 by 3024 photograph resized to 2560, 1600, 1200 and 800 pixels wide, showing pixel count, share of the original and decoded memory falling from 46 MB to 1.8 MB.

The number that matters is the display width

There is no universal correct size. There is only the width your theme draws the image at, and you can read that number in about fifteen seconds. Open the page in a desktop browser with the window at full width, right click the image, choose Inspect. Chrome shows a tooltip when you hover the img element in the Elements panel: the layout size it is rendered at, and the intrinsic size of the file that was downloaded. If the second number is several times the first, you have found your problem.

The console version is faster once you know it. Select the image in the Elements panel so it becomes $0, then ask it directly:

$0.clientWidth    // 760  the width your theme renders it at
$0.naturalWidth   // 4032 the width of the file the visitor downloaded
$0.currentSrc     // which srcset candidate the browser actually chose

Take the layout width, double it so the picture still looks sharp on a high density screen, and that is your ceiling. A 760 pixel column wants a file about 1520 pixels wide, which is why 1600 is such a comfortable round number to standardise on. Measure on the widest layout you support, because the responsive sizes only shrink from there. WordPress still builds a srcset from the sub-sizes it generates, so the width you upload sets the ceiling, not the delivery.

The safety net WordPress already has

Core has scaled big uploads by itself since 5.3, and it is worth knowing exactly how far that protection goes. In wp-admin/includes/image.php, wp_create_image_subsizes() reads a threshold through the big_image_size_threshold filter, default 2560. If either side of your upload is larger than that, WordPress writes a second file with -scaled appended to the name, with the long edge fitted to 2560, and that copy becomes the full size everywhere on the front end.

Two details decide how much this actually helps. The sub-sizes are generated from the untouched original rather than from the scaled copy, which is the right call for quality. And the untouched original is kept, permanently: its file name is stored in the attachment metadata as original_image, and it only leaves the disk when you delete the attachment. Your uploads folder therefore holds both files, and the 4 MB you never needed is still there, still in every backup, still being copied to staging.

So the net limits the damage on the page and not in the folder. It also sits far above any real display width, which makes 2560 a fire break rather than a resize strategy. You can move it in your theme or a small plugin:

add_filter( 'big_image_size_threshold', function () {
	return 1800; // scaled copies get a 1800 px long edge instead of 2560
} );

That only changes the size of the copy. The original still stays, and it still gets written to disk first. Resizing before the upload is the only version of this that keeps the folder small as well as the page fast. For the full map of which files one upload turns into, and which of them your theme actually uses, see every file WordPress creates from a single upload.

Ceilings worth standardising on

Measuring is better than guessing, but you will not measure every time. These ceilings assume a fairly standard content column and a doubling for high density screens, and they are ceilings for the file you upload, not sizes you register in WordPress.

Where the image appearsUpload ceilingWhy that number
Full width hero or banner1800 to 2000 pxCovers a wide layout at 2x and still stays under the 2560 threshold
Image inside a content column1200 to 1600 pxA 600 to 800 px column, doubled
Half width or two column block800 pxA 400 px slot, doubled
Card, list row, related post400 to 600 pxNothing on the page ever draws it larger
Logo, avatar, inline icon200 to 400 pxOr an SVG, which has no fixed pixel size at all

Portraits are the exception that trips people up. A target width of 1200 applied to a 3000 by 4000 pixel portrait still gives you a 1600 pixel tall image that pushes the next paragraph off the screen. That is what the Max height field is for: it is applied as a second constraint on the same scale factor, so it can win. A 200 by 150 image with a target width of 800 and a max height of 300 comes out at 400 by 300, because the height constraint bites first.

Why one big jump looks soft

Resizing down is not cropping. Every destination pixel has to be invented from a neighbourhood of source pixels, and the quality of the result depends entirely on how many of them the sampler bothers to read. When the reduction is large and the sampler reads a small fixed neighbourhood, most of the source pixels are never looked at. Fine detail, hair, foliage, brickwork, the text in a screenshot, either turns to noise or vanishes, and hard edges pick up a jagged shimmer.

Halving is the friendly case: each destination pixel is the average of exactly four source pixels, so nothing is ignored. That is why the tool halves rather than jumping. It plans the steps first, halving the width while the next halving would still land above your target, then does one final draw to the exact size. From 4032 to 800 that is 2016, then 1008, then 800: three draws instead of one. Every intermediate canvas is released as soon as the next one has been drawn, so the batch does not accumulate.

Diagram of a stepped downscale from a 4032 pixel source through 2016 and 1008 pixels to a final 800 pixel draw, with a table of four example runs and the number of draws each one needs.

A reduction of less than half is drawn in one go, because there is nothing to gain from a step, and enlarging is never stepped at all. If you have images that already look soft on the site and you want to work out which of the several possible causes is yours, the blurry images walkthrough separates a bad downscale from a theme upscaling a thumbnail, which look similar and need opposite fixes.

Quality 82, and why 95 is a waste

The slider defaults to 82 for a reason. WordPress uses the same number: protected $default_quality = 82 in wp-includes/class-wp-image-editor.php, applied to every sub-size core writes unless a filter changes it. So a JPEG you upload at quality 95 is already being re-encoded at 82 for the sizes your theme actually serves. Paying for 95 on the upload buys you nothing on the page.

Above roughly 85 the curve turns cruel. The extra bytes go into detail that survives no display and no downscale, and moving from 82 to 95 commonly doubles a photographic JPEG. Below about 70 you start to see it: blocking in smooth gradients, skies and skin worst of all. If a file is still too big at 82, the honest move is to resize further rather than to compress harder. Fewer pixels at 82 beats the same pixels at 55, every time.

Format matters as much as quality. PNG is lossless, so choosing it disables the slider and shows n/a, and a photograph saved as PNG is several times larger than the JPEG of the same picture. WebP at matching visual quality is usually 25 to 35 percent smaller than JPEG. The format comparison covers which to pick for photographs, flat graphics and transparency.

The cases that catch people out

  • Files can come back bigger. Re-encoding a PNG as a PNG often grows it, and a small JPEG written as a PNG almost always does. The row says “N% larger” in amber instead of a green saving, “about the same” when it rounds to zero, and the total line owns up to it too. A tool that only ever reports savings is lying about at least one of your files.
  • Never enlarge is on by default. An 800 pixel photograph in a batch with a 1600 target comes back at 800 pixels, unchanged in size, so a mixed batch cannot be silently upscaled into mush. Untick it and the same file is drawn up to the target, which produces a bigger file and no extra detail.
  • Metadata is gone whatever the checkbox says. A canvas re-encode drops EXIF, GPS coordinates and the colour profile, so unticking Strip metadata changes the note to say metadata still cannot be kept rather than pretending to preserve it. Two consequences: the location of your house does not travel with the photo, which is a gift, and the EXIF orientation flag goes too, so a shot that relied on it appears in its stored rotation. Check portrait photographs after your first batch.
  • Keep original follows the source type. Anything that is not JPEG, PNG or WebP, a GIF or a BMP or an AVIF, is written as JPEG. If your browser cannot encode WebP, that option is disabled and relabelled rather than silently handing you a PNG wearing a WebP name.
  • JPEG has no transparency. A transparent PNG written as JPEG is flattened onto white before the final draw. If your logo needs to sit on a coloured background, keep it as PNG or WebP.
  • Things that are not images are skipped, not swallowed. A file whose type is not an image gets a row saying so and no result, a file that claims to be an image and will not decode gets its own message, and a batch of nothing but those leaves the Resize button disabled.
  • Stale numbers are called out. Touching any control while results are on screen appends “Settings changed, press Resize again” to the total line, so the figures you are reading always match the settings that produced them. A target width that is empty, zero or above 12000 refuses the run and leaves the existing results alone.

Under the surface the tool works one image at a time and decodes each source fresh on every run, so a batch of forty large photographs never holds forty decoded bitmaps in memory at once. Object URLs are tracked and revoked: re-running a file releases the previous result first, and Clear releases the lot. Download all fires one link at a time, 350 milliseconds apart, with no zip library involved.

What it deliberately does not do

No cropping, no rotation, no correction of the EXIF orientation flag it has just discarded, no AVIF output, no zip download, and no memory of your settings between visits. It resizes and re-encodes, and that is the whole job. If you need to change what is in the frame rather than how many pixels are in it, that is an editor’s work, not a resizer’s.

It also does nothing for the images already sitting in your media library, which is the awkward half of this problem for anyone who has been running a site for a few years. Those files are on the server, referenced by post content and by attachment metadata, and shrinking them means rewriting the files in place and regenerating the sub-sizes without breaking the links. Bulk resizing an existing library is a different operation with different risks, and it deserves a backup first.

The rule that comes out of all this is short. Find the width your theme draws the image at, double it, treat that as a ceiling, and resize before the upload rather than trusting a threshold that was set to 2560 for safety and not for speed. One number, decided once, applied to every photograph you publish afterwards.

What makes it worth the small effort is that this is one of the few web performance decisions with no trade-off hiding behind it. A caching layer changes when things break. A new plugin adds code you now maintain. Uploading a 1600 pixel photograph instead of a 4032 pixel one costs you nothing at all: the picture looks identical on the page, the visitor downloads roughly a tenth of the bytes, their phone spends a sixth of the memory, and your uploads folder stops growing by four megabytes every time somebody adds a photo to a post.

How Big Should an Image Actually Be Before You Upload It

Table of Contents

Learn it by building something

Every week one thing you can make the same afternoon, from dynamic templates to 3D type. Written down step by step.

One mail a week, and then it ends.
Unsubscribe in one click.

Developer Tools

Cron Expression Generator: The Five Fields and the OR Rule

The five cron fields, the four special characters, and the rule that catches everyone: day of month and day of week are combined with OR, not AND. Plus why WP-Cron misses schedules, and the two lines that put WordPress on a real timer.

Troubleshooting

Serialized Data Repair and Search Replace: The Bytes That Break a Migration

One UPDATE with REPLACE() over wp_options is all it takes to kill a WordPress site after a migration, without printing a single error. The reason is a number baked into PHP's serialization format, and the fix is counting bytes.

Security & Privacy

What Your Photos Tell Your Visitors: EXIF, GPS and WordPress

WordPress keeps the file you uploaded exactly as it arrived, sitting next to the resized copies it actually serves. If that file came off a phone, it very likely still carries the coordinates of the room it was taken in.

WordPress Development

One Design, Two Hundred Names: Designing From a Spreadsheet

Somebody needs two hundred name badges by Thursday. The spreadsheet with all those names already exists, and typing them a second time is pure waste.

WordPress Images

The WordPress Uploads Folder, and How to Move It Safely

The year and month structure under wp-content/uploads comes from one boolean option, and the full path is recomputed on every request rather than stored. That is why repointing the folder is trivial and why moving the files is not.

Photo Editing

Make a tidy application photo out of an ordinary phone snapshot

A face detector of 190 KB returns a grid of anchors, a box and five landmark points, and everything after that is arithmetic: head height, eye line, the angle to level by, millimetres to pixels. An application photo, explicitly not an official passport photo, made without uploading your face anywhere.

Download the free WunderPaint Plugin for WordPress

The WunderPaint workspace with the layers panel, adjustment sliders, text style presets and the asset library along the bottom

The Image Editor & Design Studio

Everything described here can be done in the browser, on your own site. The live demo runs the full editor with nothing to install.

Free

Chaos Art

Autonomous painters make one-of-a-kind abstract art in 3D space - gestures, art movements, painterly media, and embeds that paint a new original for every visitor.

Pro

Particle Strokes

Paint with swarms of light: twenty-two movements, a stamp you draw yourself, and curves that give a stroke a shape - the swarm keeps painting for a few seconds after you let go.

Pro

City Diorama

Any place on earth as a miniature you could hold: real streets, water and building footprints raised into a 3D diorama - or wrapped around a sphere as your own tiny planet.

Free

Papercut Art

Layered paper pictures with real depth - a photo sliced along its actual depth into up to twenty layers, parametric landscapes, animals and clouds you can shape, letters with real counters, and a look that runs on three dials.

Pro

3D Earth Studio

A hyperrealistic globe - day and night with city lights, live clouds, atmosphere halo, country borders and highlights, click-to-place markers with flight-route arcs, satellite orbits, seamless rotation video and a live website embed.

Free

Mystic Studio

Turn a birth date into wall art - a real natal chart with houses and aspects, the moon of that night, zodiac and Chinese zodiac posters, numerology cards and a synastry wheel for two, in eight artful themes.

Free

Marble Bath

Marble paper on a virtual water bath - drop, rake and comb real Ebru patterns with gestures, flowers and classic recipes, razor-sharp at any size and re-editable as a layer.