Blog
DevGuideEncoding

Base64 Encoding Explained: How It Works and When Not to Use It

Base64 turns bytes into 64 safe text characters and makes data about a third bigger. How it works, measured overhead, and the jobs it is wrong for.

Mahdi MoradiMay 18, 2026Updated 5 min read
Base64 Encoding Explained: How It Works and When Not to Use ItPhoto by Taylor Vick on Unsplash

Base64 rewrites any bytes (an image, a PDF, a string with emoji) using only 64 characters that survive text-only systems: A to Z, a to z, 0 to 9, plus + and /. Every 3 bytes become 4 characters, so the output is about a third larger. Anyone can reverse it, which means it hides nothing.

The standard is RFC 4648 (2006). Every encoded example below was run through the Base64 Encoder & Decoder, so the outputs are what the tool gives you.

How Base64 encoding works

Take 3 bytes, which is 24 bits. Cut them into four groups of 6 bits. Each 6-bit group is a number from 0 to 63, and that number picks one character from the alphabet. The word "Man" is the classic example, and it comes out as "TWFu" with no leftovers.

How "Man" becomes "TWFu"

Text

Man

Bytes (8 bits each)

01001101 01100001 01101110

6-bit groups

010011 010110 000101 101110

Base64

TWFu

Every 3 bytes in, 4 characters out.

Calculated with the same logic as our Base64 Encoder & Decoder.

When the input length is not a multiple of 3, the last group is padded with = so the output stays a multiple of 4. "Hey" is 3 bytes and encodes to SGV5. "Hi" is 2 bytes and becomes SGk= with one pad. A single "a" becomes YQ==, two pads for one leftover byte.

Text, emoji and the btoa trap

Base64 encodes bytes, not letters. Text has to become bytes first, and on the web that means UTF-8. Plain English is one byte per letter, but an accented é takes two bytes and most emoji take four. The browser's built-in btoa() treats each character as one byte. It throws on anything above U+00FF, like an emoji, and it quietly encodes é as a single Latin-1 byte, so btoa("café") gives a different result from the UTF-8 version below (MDN, checked 2026-10).

Three strings, encoded and decoded back

Text

Hello

UTF-8 bytes

5 bytes

Base64

SGVsbG8=

Decoded

Hello

Text

café

UTF-8 bytes

5 bytes

Base64

Y2Fmw6k=

Decoded

café

Text

🔑 key

UTF-8 bytes

8 bytes

Base64

8J+UkSBrZXk=

Decoded

🔑 key

"café" is 4 letters but 5 bytes; "🔑 key" is 5 visible characters but 8 bytes.

Calculated with the same logic as our Base64 Encoder & Decoder.

"Hello" encodes to SGVsbG8=, and the other two decode back character for character. The ZipTools encoder converts text to UTF-8 before encoding, which is why the emoji works. In your own code, use one of these:

// Modern browsers (Baseline since September 2025)
const bytes = new TextEncoder().encode('café 🔑');
const b64 = bytes.toBase64();                    // standard alphabet
const url = bytes.toBase64({ alphabet: 'base64url', omitPadding: true });
const back = new TextDecoder().decode(Uint8Array.fromBase64(b64));

// Older browsers: go through a byte string
const legacy = btoa(String.fromCharCode(...bytes));

The toBase64() and fromBase64() methods are listed by MDN as Baseline 2025 (checked 2026-10). The spread in the legacy line can hit the engine argument limit on large inputs, so encode big files in chunks.

How much bigger Base64 makes your data

4 characters for every 3 bytes is 33.3% overhead. Real sizes get close to that quickly: 36% at 100 bytes, 33.6% at 1 KB. Small inputs pay more, because padding rounds the output up to the next multiple of 4.

Base64 overhead by input size

Value
3 B33.3%
10 B60%
100 B36%
1 KB33.6%
1 MB33.3%

Extra size as a share of the original. 10 bytes become 16 characters; 1 MB becomes about 1.33 MB.

Calculated with the same logic as our Base64 Encoder & Decoder.

Email adds a bit more. MIME wraps Base64 at no more than 76 characters per line (RFC 2045, section 6.8), and every line break adds two more bytes. So an attachment grows by a little more than a third on its way through email, which is worth remembering when a mailbox has a size limit.

Where you will actually meet Base64

  • Data URIs. A data:image/png;base64 URI puts a small file straight into HTML or CSS. The Base64 tool gives you a ready-made data URI when you encode a file.
  • JWTs. The header and payload of a JSON Web Token are base64url (- and _ in place of + and /) with the padding removed (RFC 7515, section 2). Decode the middle part and you can read every claim, which is a good reminder that a JWT is signed, not secret. The ZipTools decoder accepts missing padding but expects the standard alphabet, so if a segment contains - or _, swap them for + and / first.
  • APIs that put files in JSON. The GitHub API, for one, returns file contents with the encoding field set to base64 (GitHub REST docs, checked 2026-10).

When Base64 is the wrong choice

Hiding secrets. Base64 is an encoding, not encryption. An API key in Base64 is an API key with extra steps; paste it into any decoder and it's back. If something needs protecting, encrypt it, or keep it out of the file altogether. If one already leaked, read what to do about a leaked API key.

Large images inside pages. A data URI is part of the HTML or CSS file, so it is downloaded again whenever that file is, and it is a third larger than the image. Fine for a tiny icon. For a hero photo, serve the file.

Two smaller ones. If your database has a binary column type, use it instead of paying a third more space plus a decode on every read. And in URLs, standard Base64 breaks because + and / mean something there: use base64url (the URL encoding guide covers it next to percent-encoding) or percent-encode the value.

Encode and decode without uploading

The Base64 Encoder & Decoder runs in your browser. Tokens, keys and files you paste are never sent to a server, which matters when the thing you are decoding is a production API token.

MM

Mahdi Moradi

Full-stack software engineer and founder of Bornara AI, building free privacy-first tools at ZipTools. Based in Calgary, Canada.

Try the tool mentioned in this article.

Open base64 encoder

Related articles

Cookies for ads only

Tool data never leaves your browser. We use cookies only for Google AdSense. Privacy.