Web

Base64 Images on the Web: Pros, Cons and Site Speed

"I'll embed all my images right in the code — fewer requests, and the site will fly" — it sounds logical, but in practice the opposite usually happens. Let's work out where embedded Base64 images genuinely speed a page up, where they quietly drag it down, and how not to shoot yourself in the foot.

Blue and purple CSS code in motion — embedding images into styles
Embedding an image in code is easy. The question is whether it speeds the site up or slows it down. Photo: Pexels

The idea behind embedded images

Normally an image on a site is a separate file: the browser sees <img src="logo.png"> and sends a request to the server for that file. A Base64 image works differently: the image data is baked straight into the HTML or CSS as a data:image/png;base64,… string. There is no separate file — and therefore no separate request.

The difference is visible right in the code. Compare two ways of writing the same image:

<!-- Plain file: the browser fetches it from the server -->
<img src="/img/logo.png">

<!-- Base64: the data is already inside the page -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...">

If you are not yet familiar with the mechanism itself, take a look at "What is Base64" — it covers how an image becomes a string. Here we focus specifically on the impact on site speed.

The key takeaway up front

Base64 is not a default "site accelerator." It is a trade-off: you save one request but pay a ~33% size growth and a loss of caching. The win only exists for very small images.

Pros: when it helps

Embedded images have real strengths — their useful range is just narrower than it seems:

  • No extra request. The image arrives with the HTML or CSS — the browser doesn't have to go off and fetch a separate file at all; it's already in hand.
  • The image appears instantly. An icon in critical CSS renders with the first screen, with no flash of empty space while a file loads.
  • Nothing can "fall off." An embedded image can't return a 404 — it's always there, because it is part of the page.
  • It works in emails. In HTML mail, external images are often blocked, while embedded ones show immediately. More on that in "Base64 in CSS and email."
A wall of CSS code with gradients and colors — site styles
Small icons baked into CSS render instantly — without separate requests. Photo: Pexels

Cons: where the catch hides

Now the flip side. The bigger the image and the more often it appears, the more the downsides outweigh the upsides:

  • A 33% size increase. A text string is always about a third heavier than the original file. Fifty icons can easily add tens of kilobytes to a page.
  • Bloated HTML and CSS. The browser won't show anything until it has finished downloading and reading the CSS. Stuff giant data strings inside, and the page just sits there blank for longer.
  • CPU load. Before displaying, the browser has to decode Base64 back into bytes. For a couple of icons that's invisible; for many large images it becomes a noticeable delay.
  • Hard to maintain. Changing one baked-in icon means digging into the code and rewriting a giant string. With separate files it's just swapping an image.

The main problem — caching

This is the crux of why Base64 hurts more often than it helps. A normal image file is downloaded once and then served from cache across every page of the site and on repeat visits. An embedded Base64 image gets no such luxury: it lives inside the HTML or CSS and is re-downloaded every time with the page.

Picture an icon used on 12 pages. As a separate file it loads once and is reused 11 times for free. As a data URI it loads anew on each of the 12 pages. The encoding gets "paid for" over and over.

Let's run the math on a simple example. Say the icon weighs 3 KB. As Base64 it becomes a string of about 4 KB. A visitor who browses 12 pages downloads those 4 KB twelve times — nearly 48 KB of traffic for one tiny icon. The same file with caching would have cost 3 KB in total. The gap is small for a single icon, but across a set of dozens of elements and thousands of visitors it turns into real bytes and real slowdown.

A separate file caches once and gets reused. A Base64 string is re-downloaded on every page — that is its biggest cost.

How HTTP/2 changed the rules

The main historical argument for Base64 — fewer HTTP requests — was born in the days of HTTP/1.1, when each request was costly: the browser could keep only a few parallel connections open, and dozens of small files genuinely slowed loading.

Modern HTTP/2 and HTTP/3 work differently: dozens of files can travel down a single connection at once, with almost no cost per file. In that world the old argument has nearly vanished — an external file with caching usually beats an embedded string already for images just a couple of kilobytes in size.

Close-up of HTML code with input and label tags
On modern HTTP, external files with caching tend to beat embedded Base64 strings. Photo: Pexels

A simple rule of thumb

To avoid second-guessing every time, keep a size benchmark in mind:

SituationBase64Separate file
Icon under 5 KB, needed instantlyYes
Image in critical CSSYes
Logo in an HTML emailYes
Photo or banner over 10 KBNoYes
One icon across many pagesNoYes
~5 KBsensible upper limit
+33%string size growth
0caching for embedded

To decide in 30 seconds, ask yourself three questions: is the image under 5 KB? Is it needed on the first screen right now? Is it used on just one page rather than dozens? If the answer to all three is "yes" — embed it with confidence. A single "no" — leave it as a separate file.

The short version: use Base64 surgically — for tiny icons, critical CSS and emails. Leave everything else as separate files. For a detailed comparison by the numbers, see "Base64 vs plain files."

Need a Base64 string for an icon?

Encode a small PNG to Base64 online — get a ready data URI for your CSS or HTML in a couple of seconds.

Convert PNG to Base64

And if you need to pull an image back out of a string, Base64 → PNG has you covered. Every converter lives on the all formats page.

Sometimes. An embedded image needs no separate request to the server, and for a few tiny icons that gives a small win. But the string is about 33% heavier than the file, and it is not cached separately — so for large images the benefit turns into a loss.
A normal image file is downloaded once and then served from cache across every page. A Base64 image lives inside the HTML or CSS, so it is downloaded again with the page on every visit. Reusing one icon across 12 pages means downloading the same data 12 times.
Largely yes. The main argument for Base64 — fewer HTTP requests — was strong on HTTP/1.1, where each request was costly. HTTP/2 and HTTP/3 carry dozens of files over a single connection at almost no overhead, so an external file with caching is often faster than an embedded string.
A practical rule is small images up to about 5 KB: icons, list bullets, tiny background textures. Anything larger than around 10 KB is almost always better as a separate file that caches once and gets reused.
In critical CSS (so the first screen renders without waiting for files), in HTML emails (where external images are often blocked), and for a handful of small icons that must appear instantly. In those cases the saved request outweighs the size growth.