Base64 Explained: Why Developers Use It Everywhere

Where Base64 came from, how it stretches 3 bytes into 4 characters, the URL-safe variant and why it is not encryption.

Published: 11 Nov 2026 Read time: 5 min Standard: RFC 4648

Where Base64 Came From

In the 1980s email was text only. SMTP mail servers routed messages as 7 bit ASCII and happily corrupted or stripped anything else. That was a problem for anyone who wanted to attach a photo or a spreadsheet to an email. The solution, specified in RFC 989 in 1987 and refined into Privacy-Enhanced Mail and later MIME, was to encode binary content as a safe subset of printable ASCII characters. The scheme picked 64 characters (A to Z, a to z, 0 to 9, plus / and +), hence Base64.

The algorithm has not changed meaningfully in forty years. It is still specified by RFC 4648 and used in email, JSON APIs, HTTP headers, URLs, JWT tokens, data URIs, Kubernetes Secrets, SSH keys and PEM certificates. Anywhere a text-only channel needs to carry binary, Base64 is the default.

How It Works

Base64 takes input three bytes at a time. Three bytes is 24 bits. Those 24 bits are split into four groups of six. Each six-bit value is a number between 0 and 63, which maps to one of 64 characters. The output is therefore always 4 characters for every 3 bytes of input, which is where the 33 percent overhead comes from.

When the input length is not divisible by three, the last group is padded with = characters so the output length stays a multiple of four. One leftover byte produces XX==, two leftover bytes produce XXX= and exactly divisible inputs produce no padding. The padding is purely for length alignment and is stripped in some URL-safe contexts.

Worked Example

Take the three characters Man, which is three bytes: 77, 97, 110. In binary: 01001101 01100001 01101110. Regrouped into four 6-bit chunks: 010011 010110 000101 101110, which are 19, 22, 5 and 46. Those map to T, W, F and u. So Man encodes to TWFu.

Now encode Hello: five bytes. The first three (Hel) become SGVs. The remaining two bytes (lo) have only 16 bits so the final 6-bit chunk is zero padded and the output ends with a single =. Full result: SGVsbG8=.

URL-safe Base64

The classic alphabet uses + and /. Both are reserved characters in URLs. A Base64 string pasted straight into a query string breaks because + becomes a space and / is a path separator. RFC 4648 Section 5 defines a URL-safe variant that swaps these two for - and _. Padding is also commonly stripped since the resulting length is always a multiple of four plus zero, one or two.

JWTs always use the URL-safe variant without padding. If you paste a JWT segment into a standard decoder it fails. If you paste a standard Base64 string into a JWT library it fails. Always know which variant your target expects.

What Base64 Is Not

Base64 is not encryption. The encoding is reversible by anyone. Running atob in a browser console undoes it in milliseconds. Yet year after year security audits find apps that Base64 encode an API key and ship it in client JavaScript, as if that hid anything. It does not. If you need secrecy, use real cryptography on top: encrypt with AES or RSA, then Base64 encode the ciphertext for transport.

Base64 hides nothing Treat Base64 strings as readable text. Do not use the encoding to protect secrets.

When to Reach for Base64

  • Data URIs: inline a small image or font directly in HTML, CSS or a JSON API response to avoid an extra network hop.
  • HTTP Basic Auth: the Authorization header encodes username:password as Base64.
  • Email attachments: every MIME attachment is Base64 by default.
  • JWT: the header and payload of every JSON Web Token are URL-safe Base64.
  • SSH and TLS keys: PEM wrapping is just Base64 between BEGIN and END lines.

When Not To

The 33 percent size penalty adds up. A large image embedded as a data URI inflates HTML and hurts caching. A large payload Base64 encoded in a JSON field means a full parse before you can even see the binary. Prefer separate binary channels like multipart/form-data, binary WebSocket frames or signed upload URLs when the payload is more than a few kilobytes.

Try It

Encode and decode anything in the Toolfrnd Base64 Encoder, which supports URL-safe mode, padding stripping and line wrapping. If you are debugging JWTs, use the JWT Decoder which handles the Base64URL work for you.

Takeaway

Base64 is a four decade old trick that turned binary into safe text. It is almost always the right answer when a system can only carry text. Just remember two things: it is not encryption, and the URL-safe variant is different from the standard one.