DevRivet

Blog ·

Base64 Size Increase: Why Base64 Makes Data About 33% Bigger

Base64 turns every 3 bytes into 4 ASCII characters, so the output is about 33% larger. Learn the size formula, plus how padding and line breaks add overhead.

Base64 Encoder / Decoder

Encode and decode Base64 instantly in your browser.

Try it free →

Base64 makes data about 33% bigger because it represents every 3 bytes of input as 4 ASCII characters. Four characters is one-third more than three bytes, so the output is roughly 4/3 the size of the input. Padding and line breaks can add a little more on top of that.

To check a specific value, paste it into the Base64 Encoder / Decoder and compare the lengths. The size math below lets you predict the result before you run anything.

Why 3 bytes become 4 characters

Each byte is 8 bits, so 3 bytes is 24 bits. Base64 splits those 24 bits into four 6-bit groups. A 6-bit value can be 0 to 63, which maps to one of 64 characters: A-Z, a-z, 0-9, +, and /.

Take the ASCII text Man. In hex, the bytes are 4D 61 6E. In binary:

01001101 01100001 01101110
010011 010110 000101 101110
   19     22     5     46
   T      W      F     u

So Man encodes to TWFu. Three input bytes produced four output characters, with no loss of information.

The size math

The padded output length is:

encoded_length = ceil(input_bytes / 3) * 4

Without padding, the length is ceil(input_bytes * 4 / 3). Some examples:

  • 3 bytes becomes 4 characters (ratio 1.33).
  • 1,000 bytes becomes 1,336 characters (ratio 1.336).
  • 1 MB (1,048,576 bytes) becomes 1,398,104 characters, about 1.33 times larger.
  • 1 byte becomes 4 characters, a 300% increase. Small inputs look much worse in percentage terms.

For large payloads the ratio settles at about 1.33. That is where the common 33% figure comes from.

Padding adds up to 2 extra characters

Base64 works in groups of 4 characters. If the last group of input has only 1 or 2 bytes, the encoder fills the missing bits with zeros and appends = signs so the output length is a multiple of 4.

  • 1 leftover byte: two = signs are added.
  • 2 leftover bytes: one = sign is added.
  • 0 leftover bytes: no padding.

Hello is 5 bytes, so it becomes SGVsbG8= with one padding character. The first 3 bytes (Hel) give SGVs, and the last 2 bytes (6C 6F) give bG8 plus one =.

Padding is usually a few characters, so it rarely matters. It does matter for very small values and for systems that expect unpadded output. Some URL-safe variants drop the = entirely.

Line breaks add more overhead

The MIME standard (used in email attachments) wraps Base64 output into lines of 76 characters, and each line ends with a CRLF pair. That adds 2 bytes per 76 characters, about 2.6% extra. PEM certificates also use Base64, but they wrap lines at 64 characters, so the overhead there is higher. Many default encoders, including Node.js Buffer and Python base64.b64encode, do not add line breaks, so check the output when you compare sizes.

If you see unexpected newlines in a Base64 string, that is probably line wrapping. Most decoders ignore whitespace, but some strict parsers and JSON strings do not.

Base64 vs Base64URL

Standard Base64 uses + and /, which have special meaning in URLs and file paths. Base64URL replaces them with - and _, and often omits the = padding. Swapping the alphabet does not change the length, so the size math is the same.

The extra length in a JWT comes from two other sources. Each of the three segments is Base64URL-encoded JSON, so it carries the usual 4/3 expansion, and the segments are joined by dot characters, which add one byte each. The alphabet itself is not the cause. For more on how JWTs are structured, see Decode JWT vs Verify: What's the Difference?.

Code examples

These examples encode the string Hello and show the output length. Browsers' btoa only accepts Latin-1 characters and throws on anything above code point 255, so the browser example converts the text to UTF-8 bytes with TextEncoder first.

// Node.js
const encoded = Buffer.from("Hello", "utf8").toString("base64");
console.log(encoded); // SGVsbG8=

// Browser, UTF-8 safe
const bytes = new TextEncoder().encode("Hello");
let binary = "";
for (const b of bytes) binary += String.fromCharCode(b);
console.log(btoa(binary)); // SGVsbG8=
import base64

encoded = base64.b64encode(b"Hello").decode("ascii")
print(encoded)       # SGVsbG8=
print(len(encoded))  # 8

Common pitfalls

  • Assuming Base64 is encryption or compression. It is only an encoding, and anyone can decode it.
  • Storing large binary files as Base64 in JSON or databases without accounting for the 33% increase.
  • Calling btoa on raw text with non-Latin-1 characters, which throws an error in browsers. Encode to UTF-8 bytes first.
  • Forgetting that a Base64 string in a URL needs URL encoding, or using Base64URL when the receiver expects standard Base64.
  • Mixing up the two alphabets when decoding. Strict decoders may reject + or / when they expect Base64URL, and may reject - or _ when they expect standard Base64.

How to reduce the overhead

Base64 is the right choice when you must send binary data through a text-only channel, such as JSON, an HTML data URI, or an email body. When you control the transport, consider sending raw bytes instead. In HTTP, multipart form uploads and binary responses avoid the overhead entirely.

If the payload is text and you only need to shrink it, compress it first, then encode. Base64 of compressed data is still about 33% larger than the compressed bytes, but the compressed bytes are often much smaller than the original.

Be careful with secrets, tokens, and private files. Avoid pasting production secrets into any online tool when you can run the encoding yourself with the commands above.

FAQ

Is Base64 always exactly 33% bigger?

No. The ratio is 4/3 for large inputs, about 33.3% larger. Small inputs can look much worse because padding and the 4-character minimum add proportionally more. Line breaks add a further small amount when used.

Does Base64 compress data?

No. Base64 always makes the output larger. If you need smaller output, compress the data with gzip or another algorithm before encoding.

Why does my Base64 string end with = or ==?

The = characters are padding. They make the length a multiple of 4. One = means the last group had 2 bytes, and two == means it had 1 byte.

Can I calculate the decoded size from a Base64 string?

Yes. Take the string length, subtract the number of trailing = characters, then multiply by 3 and divide by 4, rounding down. For example, SGVsbG8= has length 8 and one =, so (8 - 1) * 3 / 4 = 5.25, which rounds down to 5 bytes, matching Hello.

Base64 Encoder / Decoder

Encode and decode Base64 instantly in your browser.

Try it free →