Base64 Images: Why They're Exactly 33% Larger Than the Original
When you Base64-encode an image, it doesn't get "roughly" bigger — it gets exactly 4/3 as large (about 33.3% larger). This isn't an approximation; it's a mathematically fixed value that falls directly out of how the encoding works. This guide covers why it's specifically 33%, and then draws the line between situations where that overhead is worth accepting and situations where you should never use it.
1. Why exactly 33%: the gap between 6 bits and 8 bits
A raw binary file represents 8 bits per byte — 256 possible values. But Base64 has to represent its output using only 64 ASCII characters (A-Z, a-z, 0-9, +, /) that can be read as text and transmitted safely. Distinguishing 64 possible values only requires log2(64) = 6 bits. So instead of slicing the source into 8-bit chunks, Base64 slices it into 6-bit chunks, and each 6-bit chunk gets packed into a single ASCII character (which itself takes up 8 bits as stored text).
That means every 3 bytes (24 bits) of source data splits exactly into four 6-bit chunks, and those four chunks each become one text character (8 bits), for a total of 4 bytes of text. 3 bytes → 4 bytes — that ratio is exactly 4/3 = 1.3333..., and that's the origin of the 33.3% increase. In exchange for packing 8 bits of information into 6-bit slots, you lose 25% of your "storage density" (only 6 of the 8 available bits per byte are used), and that loss shows up as a 33% increase in the final output size.
2. The exact formula, and a real example
If the source isn't an exact multiple of 3 bytes, 1-2 padding characters (=) get appended at the end to round the length up to a multiple of 4. The formula is as follows:
Example: a 1,000,000-byte (~1MB) image → ceil(1,000,000/3) × 4 = 333,334 × 4 = 1,333,336 bytes (~1.27MiB)
If you're using it as a Data URL, a prefix like data:image/png;base64, (roughly 20-30 bytes) gets tacked on as well. That's negligible and barely affects the overall overhead, but the fact that it's now stored and transmitted as text data makes it a fundamentally different kind of object than the original binary.
3. When it's actually worth using Base64 despite the cost
There are situations where accepting the 33% penalty and inlining as Base64 still comes out ahead.
- Small icons and sprites: If the file itself is only 1-2KB, a 33% increase amounts to a few hundred bytes at most. A separate file, on the other hand, means one more HTTP request — and especially under HTTP/1.1, the per-request latency cost tends to be felt more than the extra size.
- Single-file HTML distribution: For email templates, offline reports, or any document meant to be shared as one self-contained file with nothing to install, an external image file simply can't exist — Base64 is the only option available.
- Inline background images in critical CSS: For a very small background image that needs to render immediately without blocking, eliminating a separate request entirely is the better trade-off.
4. When you should never use it: losing caching is the real cost
Inlining a large image, like a photograph, as Base64 comes with a loss that's far more damaging than the 33% size increase — you lose browser caching. A separate image file (.jpg, .png, etc.) can be stored by the browser according to its HTTP cache headers and skipped on a repeat visit instead of being re-downloaded. A Data URL, however, is embedded as text directly inside an HTML or CSS document, so it isn't cached on its own — instead, the entire embedded image gets re-downloaded every time the parent document (HTML/CSS) itself gets cached or updated. In other words, every visit — or every time you change even a single character in a CSS file — re-downloads every image baked into it.
Large Base64 strings also bloat the overall document size that the HTML/CSS parser has to process, causing parsing and rendering delays, and gzip/brotli compression is often less effective on them than on the original binary image's own compression (JPEG/PNG's native compression).
5. A practical rule of thumb: where's the line for "small"
Here's a rough guideline commonly used in the industry. It's not an absolute rule, but it's a reasonable baseline for making the call.
| Source size | Recommendation | Reason |
|---|---|---|
| ~2KB or less | Base64 inlining is fine | Request-savings benefit > 33% overhead + lost caching |
| 2KB-10KB | Depends on the situation | Depends on how often the image is reused/displayed |
| 10KB or more | Use a separate file | Lost-caching cost outweighs the request-savings benefit |
As HTTP/2 and HTTP/3 have become standard, the old pressure to "minimize the number of requests" has eased considerably. Multiplexing has made handling multiple parallel requests much cheaper, so absent a specific reason otherwise, keeping photos and larger images as separate files to take advantage of caching is now generally the better default.
Frequently Asked Questions
Q. Is the 33% figure always exactly 33% no matter the image?
Yes — because the encoding itself is structurally converting every 3 source bytes into 4 text bytes, this holds regardless of file format (PNG/JPEG/WebP), and is always exactly 4/3. There's a tiny additional bump (up to 2 bytes) from padding (=) when the source length doesn't divide evenly by 3.
Q. Can gzip compression offset the 33% loss?
Only partially. Base64 text does have more repeating patterns than the original binary image (which already has JPEG/PNG's own compression applied), but gzip doesn't manage to re-compress the underlying image data effectively. It won't eliminate the overhead entirely.
Q. Is there a size difference between a Data URL and a raw Base64 string?
A Data URL adds a prefix like data:image/png;base64, (indicating the MIME type), roughly 20-30 extra bytes. That's negligible relative to the total size, but for a very small icon the proportional impact might not be entirely ignorable.
Q. Does Base64-encoding an SVG also make it 33% bigger?
Yes, the same math applies. That said, since SVG is a text-based format, embedding it via URL encoding (data:image/svg+xml,...) instead of Base64 can often reduce the overhead.