The rule of thumb
Inline an image when the cost of a separate request is larger than the cost of the extra bytes. With modern HTTP/2 and HTTP/3 connections, extra requests are cheap, so that point comes early: a good working limit is 2 to 4 KB per image. Popular build tools agree; Vite inlines assets under 4 KB by default and webpack's asset modules under 8 KB.
The tool below turns a PNG (or any image) into a data URI. Drop the image or open it, then choose how to copy it: Data URI, plain Base64, a ready CSS background-image line, an HTML img tag with width and height, or Markdown. It shows the data URI size and how much larger it is than the file, and warns you when the result is large enough to slow a page down. Images are converted in your browser and never uploaded.
Try it here: PNG to Base64
Open the full tool pageWhat happens when you inline an image
A data URI such as data:image/png;base64,iVBORw0KGgo... puts the image bytes inside the HTML, CSS or JSON that references them. The browser gets the image together with that file, with no separate download. That is the whole benefit. The costs come from the same fact:
- Size: Base64 writes 3 bytes as 4 characters, so the image grows by about a third. Gzip or Brotli compression on the server wins some of that back during transfer, but not all of it, and images that are already compressed (PNG, JPG, WebP) gain little.
- Caching: a separate image file is cached once and reused on every page. An inlined image is cached only as part of the file that contains it. Change one line of CSS and every inlined icon is downloaded again.
- Render blocking: CSS blocks the first paint. Every kilobyte of images inlined in a stylesheet delays the moment anything appears on screen, even if those images are far down the page.
- No lazy loading: loading="lazy" and responsive srcset choices lose their point, because the bytes have already arrived with the page.
- Maintenance: a long Base64 string is unreadable in code review and easy to break with a bad copy.
Size guide: inline or separate file?
| Image | Typical file size | As Base64 | Recommendation |
|---|---|---|---|
| 16 to 24 px UI icon (PNG or SVG) | 200 bytes to 1 KB | about 0.3 to 1.4 KB | Inline, ideal case |
| Small logo or badge | 2 to 5 KB | about 2.7 to 6.7 KB | Inline if used on one page or in an email signature, otherwise a file |
| Blurry placeholder for a photo | 300 bytes to 1 KB | about 0.4 to 1.4 KB | Inline, then load the real photo as a file |
| Logo used on every page | 10 to 30 KB | about 13 to 40 KB | Separate file, so it is cached once |
| Product photo or hero image | 50 to 500 KB | about 67 to 670 KB | Separate file with lazy loading or preload |
Good uses for Base64 images
- Small icons in CSS, such as arrows, checkmarks, a custom checkbox or a select dropdown arrow, which must appear together with the styles and never flash in late.
- Single file deliverables: an HTML report, an exported invoice, a documentation page or a prototype that must work when opened from disk or sent as one attachment.
- APIs and databases: JSON has no binary type, so images in API requests and responses (signatures, avatars, scanned documents, marketplace product images in some integrations) are commonly sent as Base64 strings.
- Low quality image placeholders: a tiny blurred version inlined in the HTML shows instantly while the full image loads.
- SVG icons: SVG is text, so it often does not need Base64 at all. The tool's option URL encoding instead of Base64 keeps the SVG readable and usually gives a shorter result.
When to avoid them
- Photos and any image over roughly 10 KB on a web page. Use a normal file in WebP or AVIF, with width and height set and lazy loading for images below the fold.
- The largest image at the top of the page (the LCP element). A big inlined image makes the HTML itself heavy and delays everything else in it; preloading a separate file is usually faster.
- Images repeated across pages, such as the site logo or a background pattern. Caching wins over saving a request.
- HTML email for the general public. Many email clients do not display data URI images; Gmail and Outlook for Windows are the best known. Use hosted images or attachments referenced by content ID (CID) instead. Inline data URIs mostly work in Apple Mail and some mobile apps, which is not enough for a newsletter.
- Very large data URIs in general. Old Internet Explorer 8 capped them at 32 KB; modern browsers accept far larger ones, but performance suffers long before any limit is reached.
How to do it well
Shrink the image before converting it. Every byte you save is multiplied by 4/3 in the data URI, so compress PNG icons, resize oversized images to the size they are displayed at, and for photos you must inline, such as in a JSON payload, use a JPG or WebP at a sensible quality. The image compressor and resizer on this site do that in the browser, and you can bring the smaller file back here.
Include the dimensions. An img tag without width and height makes the layout jump when the image appears. The HTML output of this tool includes the image's real width and height for that reason.
Keep the source file. Store the original PNG or SVG in your project and generate the data URI from it, either with your build tool or with this tool when something changes. Never treat the Base64 string as the master copy.
Measure. Compare the page with and without the inlined images in the browser's Network panel or with Lighthouse. If the CSS or HTML file grows noticeably and nothing gets faster, go back to a separate file.