Base64 solves one narrow problem: moving binary data through a channel that only reliably carries text.
Email bodies, JSON string values, URLs, XML documents and HTML attributes all expect text. Hand them raw binary, a PNG, a zip file, an encryption key, and bytes get mangled: a 0x00 truncates a C string, 0x0A becomes a line break, high bytes get reinterpreted by whatever encoding is in play. Base64 sidesteps all of it by re-expressing arbitrary bytes using 64 characters that survive any text pipeline.
How it works
Take three bytes, 24 bits. Split them into four groups of 6 bits. Each 6-bit group is a number from 0 to 63, which indexes into the alphabet A–Z, a–z, 0–9, +, /.
So three input bytes always become four output characters. When the input length is not a multiple of three, the encoder pads with = to keep the output length a multiple of four. One = means the last group had two bytes; two = means it had one.
Input: M a n
Bits: 01001101 01100001 01101110
Regroup: 010011 010110 000101 101110
Index: 19 22 5 46
Output: T W F u
The 33% tax
Four characters for every three bytes is a 33% size increase, before any transport overhead. A 3 MB image becomes about 4 MB of Base64.
This is the single most important practical fact about it, and the reason for most of the guidance below.
The URL-safe variant
+ and / are not safe in URLs or filenames, / is a path separator and + means a space in query strings. Base64url (RFC 4648 §5) replaces them with - and _, and usually drops the = padding.
This is what JWTs use, and it is why a JWT never contains +, / or =. If you are decoding one by hand and it fails, check that your decoder handles the URL-safe alphabet.
Base64 is not encryption
This needs saying plainly, because it keeps appearing in real systems:
Base64 provides no confidentiality whatsoever. It is a public, reversible transformation with no key. Anyone can decode it instantly. A password, an API key or a token stored "encoded in Base64" is stored in plaintext with an extra step.
The recurring failure mode is HTTP Basic authentication, which sends base64(username:password) in a header. That is not protection, it is why Basic auth is only acceptable over TLS, which is what actually provides the confidentiality.
Related: a JWT payload is Base64url, not encrypted. Anyone holding the token can read every claim inside it. The signature prevents modification, not reading. Do not put anything private in a JWT payload.
When to use it, and when not to
Reasonable:
- Embedding a small icon or SVG as a data URI to avoid a network round-trip.
- Attaching binary to email (MIME has done this since the beginning).
- Putting a small binary blob inside a JSON field.
- Encoding binary keys, hashes and signatures for text-based config.
Not reasonable:
- Large images in HTML or CSS. You pay the 33% overhead, the asset cannot be cached independently, and inline data blocks the parser. A separate file that the browser caches is better in almost every case. The rough threshold is a few kilobytes.
- Large file uploads. Multipart form data sends bytes directly, with no overhead.
- Anything you want to keep secret. Encrypt it.
- "Compressing" data. It makes data 33% larger, never smaller.
A note on encoding order
If you need both compression and Base64, compress first, then encode. Base64 output is high-entropy text that compresses poorly, so doing it the other way round wastes most of the compression.
Decoding safely
Decoding is a pure transformation with no server involvement required, which matters because the things people decode, tokens, config blobs, API payloads, are frequently sensitive. NextTool's Base64 tool and JWT decoder run entirely in the browser, so pasting a live session token into them does not transmit it anywhere.
Which is worth caring about, given that a leaked token is usable by whoever finds it until it expires.