Data URI Generator

Turn a file or text into a data URI you can embed directly in HTML or CSS — and know when that is the wrong choice.

🔗
Drop a file here, or click to choose
Images, fonts, SVG, anything small

0
Original size
0
Data URI size
0%
Overhead

The crossover between the two encodings is exactly one sixth

Base64 costs a flat four characters for every three bytes, whatever the content. Percent-encoding costs one character for a byte it leaves alone and three for a byte it escapes, so if a fraction f of the bytes get escaped the cost is 1 + 2f. Setting the two equal needs no measurement at all:

1 + 2f = 4/3  →  f = 1/6 = 16.667%

Escape fewer than a sixth of the bytes and percent-encoding wins; escape more and base64 does. Built to order and measured, the switch lands exactly where the algebra says:

Bytes escapedBase64PercentSmaller
0% 1336 1000 percent
5% 1336 1100 percent
10% 1336 1200 percent
16% 1336 1320 percent
17% 1336 1340 base64
20% 1336 1400 base64
30% 1336 1600 base64
50% 1336 2000 base64

At 16% percent-encoding is smaller; at 17% it is not. Which is why this page chooses by MIME type: images, fonts, audio and video are effectively random bytes, so nearly everything escapes and base64 is right. Text is mostly letters, so little escapes. SVG is explicitly carved out of the image branch and sent down the text path for exactly that reason.

MIME typeEncoding chosen
image/pngbase64
image/jpegbase64
image/svg+xmlpercent
text/plainpercent
text/csspercent
application/jsonpercent
application/xmlpercent
application/pdfbase64
font/woff2base64
audio/mpegbase64

Except that for SVG it does not actually win

Measured rather than assumed, and the result was not what the reasoning above predicts:

ContentRawBase64As encoded hereMinimal escaping
a small SVG 95 128 167 95
CSS 46 64 60 46
JSON 40 56 84 40
plain prose 43 60 59 43

For the one format the rule names, the percent-encoded version is 167 characters against base64's 128. The reason is that JavaScript's encodeURIComponent is built for query strings rather than data URIs, and it is far more cautious than a data URI needs.

CountCharacters
escaped by encodeURIComponent24 " # $ % & + , / : ; < = > ? @ [ \ ] ^ ` { | }
strictly required by a data URI2% #
escaped as insurance21 $ & + , / : ; < = > ? @ [ \ ] ^ ` { | }

A data URI genuinely requires two: %, which starts an escape, and #, which would otherwise start a fragment. A double quote matters too, but only because the URI usually ends up inside a double-quoted attribute. The other 21 are legal unescaped, and each one costs two extra characters — and an SVG is made almost entirely of them.

So is the conservative version wrong?

Not exactly, and it is worth being precise about the trade. Escaping conservatively produces a URI that is safe everywhere — in a quoted attribute, an unquoted one, a CSS url(), a bare link, pasted into a shell. Escaping minimally produces a smaller URI that is safe in most of those and not all. That is a defensible choice, not a bug, and the output decodes back to exactly what went in either way.

What is fair to say is that the size win goes the other way for the one format most people reach for. On all 4 samples above, minimal escaping is smallest — and for the SVG it is 95 characters, the same as the raw bytes, because a well-formed SVG contains nothing a data URI has to escape at all.

The same holds for ordinary text: 43 bytes of prose stay 43 characters, against 60 as base64. That is the practical rule for hand-writing an SVG data URI into a stylesheet — escape only %, #, and the quote character you are not using, and the URI stays readable and stays small. A base64 one does neither.

How to use

  1. Choose a file, or enter text directly.
  2. Copy the generated data URI or the ready-made tag.
  3. Use it only for genuinely small assets.
  4. Check the resulting size before committing to it.
  5. Prefer an ordinary file reference for anything substantial.

Frequently asked questions

When is embedding actually worthwhile?

For very small assets — an icon, a tiny repeating pattern, a custom cursor — where saving one network request outweighs the size penalty. It is also genuinely useful for self-contained documents and for email that must carry its own images with it.

What does it cost?

About 33 per cent in size from the Base64 encoding, plus the complete loss of caching. An embedded asset cannot be cached independently, so an image embedded across five pages is downloaded five separate times rather than once — which outweighs the saved request very quickly.

Why does it slow a page down?

Because the data becomes part of the HTML or CSS itself, which must be downloaded and parsed before rendering can proceed. A large data URI inside a stylesheet delays the entire stylesheet, which delays the page — precisely the opposite of the intended effect.

What size is too large?

Above a few kilobytes the trade-off has usually reversed. Very large data URIs bloat the source file, slow parsing noticeably, and make the code unreadable to anyone maintaining it. Some older tooling also has length limits that produce silent truncation rather than an error.

What about SVG?

For SVG there are better options available. Inlining the markup directly keeps it styleable with CSS and often occupies less space than the Base64 version. If you do need a data URI, URL-encoding an SVG is generally smaller than Base64 because the content is already text.

Does my file get uploaded?

No. The file is read and encoded entirely in your browser, so nothing is transmitted at any point — which matters if the file is not something you would hand to an unfamiliar website.

Can I use a data URI for a downloadable file?

Yes, paired with a download attribute on a link, and it works well for small generated files such as a CSV or a configuration snippet. For anything large, generating a blob URL is considerably more efficient than embedding the whole file in the page.

🔒 This tool runs entirely in your browser. Nothing you enter is uploaded, logged, or stored.