Base64 shows up everywhere a developer looks: inline images in CSS, tokens in an Authorization header, email attachments, config secrets, and the middle segment of every JWT. It is not glamorous, but understanding exactly what it does — and what it costs — saves you from real bugs, like corrupted payloads and links that break on a stray +. This guide skips the beginner definition and focuses on how Base64 behaves in production systems.
The 3-to-4 transform (and the 33% tax)
Base64 works on groups of three bytes. Three bytes are 24 bits, and 24 divides neatly into four 6-bit chunks. Each 6-bit chunk is a number from 0 to 63, which indexes into a 64-character alphabet. So every 3 input bytes become exactly 4 output characters.
That ratio is the whole story of Base64's size cost: output is 4/3 the size of input, an increase of about 33% before you count padding or line breaks. Encoding a 300 KB image gives you roughly 400 KB of text. That tax is the price of turning arbitrary binary into something safe to paste into text-only channels.
"Man" (77, 97, 110) become the bits 010011 010110 000101 101110 → values 19, 22, 5, 46 → the characters TWFu. Three bytes in, four characters out.The alphabet and padding
Standard Base64 (defined in RFC 4648) uses this mapping from 6-bit value to character:
| 6-bit value | Character |
|---|---|
| 0–25 | A–Z |
| 26–51 | a–z |
| 52–61 | 0–9 |
| 62 | + |
| 63 | / |
When the input length is not a multiple of three, the final group is padded with the = character so the output length stays a multiple of four. There are only three cases:
| Input bytes mod 3 | Trailing output | Example |
|---|---|---|
| 0 (exact) | no padding | "Man" → TWFu |
| 2 | one = | "Ma" → TWE= |
| 1 | two == | "M" → TQ== |
Data URIs: embedding assets inline
A data URI packs a whole file into a string using the shape data:[mediatype];base64,[data]. This lets you embed an image or font directly in CSS or HTML, saving an HTTP request:
background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0i...");
It is ideal for tiny, frequently used assets like icons, a logo, or a critical above-the-fold background. The trade-offs matter, though: inlined data grows ~33%, cannot be cached separately from the document, and bloats your HTML or CSS file. Reserve data URIs for small assets; large images are almost always better served as normal cached files.
JSON, APIs, and JWT segments
JSON is a text format, so binary values (a file upload, a cryptographic key, raw bytes) must be Base64-encoded before they can live inside a JSON string field. Many APIs accept or return binary blobs this way. HTTP Basic auth does the same thing: it Base64-encodes username:password into the Authorization header — which is exactly why Basic auth without HTTPS is unsafe, since Base64 is trivially reversible.
JWTs (JSON Web Tokens) are three Base64URL-encoded segments joined by dots: header.payload.signature. The header and payload are just Base64-encoded JSON, which is why almost every JWT begins with eyJ — that is what {" encodes to. Anyone can decode and read a JWT's payload; only the signature is protected. Never put secrets in a JWT payload.
MIME email attachments
Email was designed for 7-bit ASCII text, so binary attachments have to be encoded to survive the journey through mail servers. MIME uses Base64 for this, marked with a Content-Transfer-Encoding: base64 header. By convention the encoded output is wrapped into lines (commonly 76 characters) to stay within legacy line-length limits. This is the original problem Base64 was created to solve, and it is still how every image and PDF you attach gets transmitted.
URL-safe Base64
Standard Base64 uses + and /, and both have reserved meanings in URLs (+ can mean a space, / is a path separator), while = is used in query strings. Dropping raw Base64 into a URL therefore corrupts it. The URL-safe variant (RFC 4648 section 5) fixes this with two substitutions:
+becomes-(hyphen)/becomes_(underscore)- padding
=is often omitted entirely
This is the flavor JWTs and many token systems use, so tokens can travel safely in URLs, cookies, and headers without percent-encoding. Just remember that standard and URL-safe outputs are not interchangeable — decode with the matching variant.
When not to use Base64
The most important rule: Base64 is encoding, not encryption. It provides zero confidentiality — anyone can decode it instantly. Do not use it to "hide" passwords, API keys, or personal data. It is also not compression; it makes data larger, not smaller. Skip it when you can transmit raw binary safely (most modern APIs and file uploads handle binary directly), and avoid inlining large assets that would be better cached as separate files.
FAQ
Q: Why does my Base64 string end in one or two equals signs?
A: That is padding. It appears when the input length is not a multiple of three, keeping the output length a multiple of four.
Q: A token broke when I put it in a URL — why?
A: Standard Base64 contains +, /, and =, which have special meaning in URLs. Use URL-safe Base64 (- and _) instead.
Q: How much bigger will my data get?
A: About 33% larger from the 3-to-4 expansion, plus a little more if line breaks or padding are added.
Q: Can I read the payload of someone's JWT?
A: Yes — the header and payload are only Base64-encoded, not encrypted. The signature prevents tampering, not reading, so never store secrets in the payload.