Web Development

Base64 33% Size Increase: RFC 4648 Source & Formula

The citation for Base64's 33% size increase: RFC 4648 §4 defines the 3-bytes-to-4-characters rule, and RFC 2045 §6.8 states the 33 percent figure verbatim.

By Inventive HQ Team

The Citation for Base64's 33% Size Increase

If you are here to cite the 33% figure in a spec, a design doc, or a code review, here are the two normative references — and they are not the same document.

RFC 4648, “The Base16, Base32, and Base64 Data Encodings” (S. Josefsson, October 2006, Standards Track) is the current definition of Base64. Section 4, “Base 64 Encoding”, specifies the transformation that causes the expansion:

The encoding process represents 24-bit groups of input bits as output strings of 4 encoded characters. Proceeding from left to right, a 24-bit input group is formed by concatenating 3 8-bit input groups. These 24 bits are then treated as 4 concatenated 6-bit groups, each of which is translated into a single character in the base 64 alphabet.

— RFC 4648, Section 4

RFC 4648 states the 3-to-4 rule but never writes down a percentage. The “33 percent” number itself appears in RFC 2045, Section 6.8, “Base64 Content-Transfer-Encoding” (Freed & Borenstein, November 1996, Standards Track):

The encoding and decoding algorithms are simple, but the encoded data are consistently only about 33 percent larger than the unencoded data.

— RFC 2045, Section 6.8

So if you have been searching for “base64 increases size by 33 percent RFC 4648” and could not find the number in RFC 4648, that is why: RFC 4648 §4 gives you the mechanism, RFC 2045 §6.8 gives you the figure. Cite whichever matches your claim, or cite both.

Quotable summary

Paste-ready for a design doc or an RFC of your own:

Base64 encoding expands data by 33.3%. RFC 4648 §4 defines the encoding as representing each 24-bit group of input (3 octets) as 4 encoded characters, giving a fixed output-to-input ratio of 4/3 ≈ 1.3333. RFC 2045 §6.8 describes the result as “consistently only about 33 percent larger than the unencoded data”. For an input of n bytes, the padded, unwrapped output is exactly 4 × ceil(n / 3) bytes. Line-wrapped output adds more: MIME's 76-character lines (RFC 2045 §6.8) with CRLF terminators bring the total to 36.8%.

Sources: RFC 4648 §4 (Josefsson, 2006); RFC 2045 §6.8 (Freed & Borenstein, 1996).

The formula

For an input of n bytes:

encoded_bytes = 4 × ceil(n / 3)

The ratio converges on 4/3 = 1.3333…, an increase of 33.3333…%. Equivalently, each output character carries 6 bits of payload (2^6 = 64, hence the name) but occupies an 8-bit byte, so the overhead is 8/6 = 4/3 — the same number reached from the other direction.

If your encoder omits padding — permitted only when the referring specification says so, per RFC 4648 §3.2 — the output is ceil(4n / 3) bytes instead, which is at most 2 bytes smaller across the entire file.

The rest of this page shows the bit-level derivation, an exact size table, and the wrapping and padding nuances that make the figure precise.

How 3 Bytes Become 4 Characters

The diagram below shows the core transformation. Three input bytes contain 24 bits. Base64 slices those 24 bits into four 6-bit groups, then maps each group to one character from its 64-symbol alphabet (A-Z, a-z, 0-9, +, /). Four characters out for every three bytes in — no more, no less.

Three bytes of binary become four Base64 characters Twenty-four bits of input are regrouped from three 8-bit bytes into four 6-bit chunks, each mapped to one Base64 character, producing the 4-over-3 (about 33 percent) size increase. 3 bytes in (24 bits) → 4 characters out

Input: 3 bytes × 8 bits = 24 bits byte 1 (8 bits) byte 2 (8 bits) byte 3 (8 bits)

regroup by 6 bits

Output: 4 chars × 6 data bits (stored in 8-bit bytes) 6 bits 6 bits 6 bits 6 bits char char char char

24 payload bits stored in 32 bits → +33% overhead (4/3)

The Math, Step by Step

Base64 encoding increases file size by approximately 33% due to fundamental mathematical constraints. The expansion is not an inefficiency to be optimized away — it is the fixed cost of representing arbitrary binary data using a limited, text-safe character set.

Binary vs Base64 Representation

In raw binary, each byte represents 256 different values (2^8 states). Base64 restricts each character to only 64 values (2^6 states). This limitation is intentional: Base64 uses only alphanumeric characters plus two symbols (+ and /), ensuring compatibility with systems that may not handle raw binary correctly.

The 3-to-4 Conversion

The size increase becomes inevitable in three steps:

  1. Take three bytes of binary data (24 bits total).
  2. Split those 24 bits into four chunks of 6 bits each.
  3. Represent each 6-bit chunk as a Base64 character (which occupies 8 bits of storage).

Three bytes in, four bytes out. The math is exact: 4 ÷ 3 = 1.333, a 33.33% increase.

Worked Example: Encoding "Cat"

Let's trace the word Cat (3 ASCII bytes) all the way through the pipeline:

StepValue
ASCII charactersC a t
Decimal byte values67, 97, 116
8-bit binary (24 bits)01000011 01100001 01110100
Regrouped into 6-bit chunks010000 110110 000101 110100
6-bit decimal values16, 54, 5, 52
Base64 alphabet indexQ 2 F 0
Base64 outputQ2F0

Three bytes (Cat) became four characters (Q2F0) — a clean 33% expansion with no padding, because 3 divides evenly. The pattern holds for every 3-byte group in a file of any size.

Advertisement

Size Table: Input vs Base64 Output

Because Base64 always emits output in 4-character blocks, the overhead is largest for tiny inputs and settles to a steady ~33% as files grow. The encoded length is always 4 × ceil(n ÷ 3) bytes.

Input sizeBase64 size (no line breaks)Padding chars (=)Size increase
1 byte4 bytes2+300%
2 bytes4 bytes1+100%
3 bytes4 bytes0+33.33%
4 bytes8 bytes2+100%
6 bytes8 bytes0+33.33%
100 bytes136 bytes2+36.00%
1,000 bytes1,336 bytes2+33.60%
1 KiB (1,024 B)1,368 bytes2+33.59%
1 MiB (1,048,576 B)1,398,104 bytes2+33.3333%

Every row is 4 × ceil(n / 3). The padding count follows directly from n mod 3: a remainder of 0 gives no =, a remainder of 1 gives two =, and a remainder of 2 gives one = — the three cases enumerated in RFC 4648 §4.

Two takeaways: padding never adds more than 2 bytes to the whole file (it is a one-time rounding cost, not a per-byte tax), and the smaller the payload, the worse the relative overhead — encoding a single byte quadruples it.

Why 33% and not 25%?

A common mis-derivation: “Base64 uses 6 of 8 bits, so it wastes 2 bits out of 8, which is 25%.” That 25% is the fraction of the output that is wasted, not the growth relative to the input — and growth is measured against the input.

Work it in bytes. Three input bytes become four output bytes. The increase is (4 − 3) / 3 = 1/3 = 33.3%. The competing figure comes from (4 − 3) / 4 = 1/4 = 25%, which answers a different question: “what share of the encoded file is overhead?” Both numbers are arithmetically true about the same encoding; only 33% answers “how much bigger did my file get?” If you are writing a capacity estimate, 33% is the one you want.

Want to see the numbers on your own data? Encode a string or file below and watch the input-versus-output size change in real time.

Base64 Encoder DecoderRuns in your browser — nothing is uploaded.

Additional Overhead from Formatting

The 3-to-4 math is the floor. Real-world implementations often add a little more.

Line Breaks (MIME / PEM)

RFC 4648 itself forbids wrapping by default — §3.1, “Line Feeds in Encoded Data”, states that “Implementations MUST NOT add line feeds to base-encoded data unless the specification referring to this document explicitly directs base encoders to add line feeds after a specific number of characters.” Two widely-used specifications do exactly that:

  • MIME (RFC 2045 §6.8): “The encoded output stream must be represented in lines of no more than 76 characters each.”
  • PEM: 64-character lines. RFC 4648 §3.1 notes that MIME “inherits the encoding from Privacy Enhanced Mail (PEM), stating that it is ‘virtually identical’; however, PEM uses a line length of 64 characters. The MIME and PEM limits are both due to limits within SMTP.”

The cost is exact, not approximate. With a wrap width of w characters and a line terminator of t bytes, the wrapped size is:

wrapped_bytes = L + t × ceil(L / w),  where L = 4 × ceil(n / 3)

Each terminator is amortised over w characters, so the multiplier on top of 4/3 is (w + t) / w:

FormatWrap widthTerminatorWrapping overheadTotal increase
Unwrapped (data URI, JSON, JWT)none0%+33.33%
MIME, LF only76LF (1 byte)+1.32%+35.09%
MIME, CRLF76CRLF (2 bytes)+2.63%+36.84%
PEM, LF only64LF (1 byte)+1.56%+35.42%
PEM, CRLF64CRLF (2 bytes)+3.13%+37.50%

Worked example: 1 MiB (1,048,576 bytes) encodes to 1,398,104 bytes unwrapped (+33.3333%). Wrapped MIME-style at 76 characters with CRLF terminators it becomes 1,434,898 bytes — +36.84%. That is the number to quote for email attachments; quote +33.33% for data URIs, JSON payloads, and JWTs, which are never wrapped.

Padding Characters

When the input is not a multiple of three bytes, Base64 appends = characters so the output is always a multiple of four. RFC 4648 §4 enumerates every case exhaustively:

  1. The final quantum is an integral multiple of 24 bits → output is a multiple of 4 characters, no = padding.
  2. The final quantum is exactly 8 bits → two characters followed by two = characters.
  3. The final quantum is exactly 16 bits → three characters followed by one = character.

RFC 4648 §10 gives the canonical test vectors, which are worth pasting into a unit test: BASE64("f") = "Zg==", BASE64("fo") = "Zm8=", BASE64("foo") = "Zm9v", BASE64("foob") = "Zm9vYg==".

Padding therefore contributes at most 2 bytes to the entire file, regardless of size — a one-time rounding cost, not a per-byte tax. RFC 4648 §3.2 makes padding mandatory (“Implementations MUST include appropriate pad characters at the end of encoded data unless the specification referring to this document explicitly states otherwise”), which is why base64url in JWTs — where the referring spec does state otherwise — legitimately drops it.

Why Accept the Size Increase?

Given the inevitable bloat, why use Base64 at all? Because the alternative — pushing raw binary through text-based systems — is unreliable.

Text Protocol Compatibility

Base64 exists to move binary data through channels designed for text. Email (SMTP), XML, JSON, and HTML attributes all handle text far more reliably than raw bytes. Base64 ensures binary survives transmission through these text-only pipes without corruption.

Character Safety

The Base64 alphabet (A-Z, a-z, 0-9, +, /) is safe across character encodings, operating systems, databases, network protocols, and programming languages. Raw binary can contain control characters or byte sequences that trigger parsing errors, truncation, or security issues in those systems.

Data Integrity

Base64 is predictable and perfectly reversible. Encode once, pass through many systems, and decode back to the exact original bytes. That guarantee is worth ~33% in a great many scenarios.

Performance Implications

The size increase touches more than storage.

  • Bandwidth: Base64 payloads need ~33% more bytes to transmit — though HTTP gzip/Brotli recovers much of that on the wire, since Base64 text still compresses reasonably.
  • CPU: Encoding and decoding cost cycles. Modern CPUs handle it easily, but it adds latency at high volume or on large files.
  • Rendering: Base64 images embedded in HTML/CSS must be decoded before paint, adding work compared to loading a binary image file directly.

When Base64 Makes Sense

Despite the penalty, Base64 is the right call when:

  • Small assets (< 5-10 KB): Inlining icons or fonts as data URIs eliminates an HTTP round trip, and the saved request often beats the 33% size cost.
  • Binary in JSON APIs: Embedding a thumbnail or signature in a JSON response keeps everything in one text payload.
  • Email attachments: MIME requires Base64 for binary attachments — non-negotiable.
  • Config and credentials: API keys and tokens are tiny, so the overhead is irrelevant and the text format simplifies handling.

Optimization Strategies

When you must use Base64, minimize the impact:

  • Compress before encoding. Gzip the raw bytes first, then Base64. The final string can be smaller than the original uncompressed file. Compressing after encoding barely helps.
  • Encode selectively. If you control both ends, prefer a binary transfer and skip Base64 entirely.
  • Cache aggressively. For repeatedly served encoded resources, CDNs and browser caching confine the size penalty to the first request.
  • Consider alternatives. Base85 (a.k.a. Ascii85) has only ~25% overhead if its more fragile alphabet is acceptable; hex is simpler but doubles the size (+100%).

The Bottom Line

Base64's 33.33% size increase is the unavoidable cost of representing 8-bit binary with 6-bit, text-safe characters. Padding adds at most 2 bytes to the whole file; MIME line-wrapping takes the total to 36.84%. That expansion buys compatibility, integrity, and safety across nearly every text-based system in existence.

For the record, in one line: RFC 4648 §4 defines 24 input bits → 4 encoded characters (ratio 4/3, +33.33%); RFC 2045 §6.8 states the figure as “about 33 percent larger”; encoded size is 4 × ceil(n/3) bytes.

The skill is knowing when the trade is worth it. For small assets, API responses, email attachments, and any text-only channel, Base64 is invaluable despite the bloat. For large files or bandwidth-sensitive paths, binary transfer or compress-then-encode usually serves you better.

Want to measure the difference on your own data? Try our Base64 Encoder/Decoder tool to encode and decode in real time and watch exactly how much the output grows.

Frequently Asked Questions

What is the official source or documentation for Base64's 33% size increase?

Two RFCs, and they say different things. RFC 4648 §4 ("Base 64 Encoding") defines the mechanism — "The encoding process represents 24-bit groups of input bits as output strings of 4 encoded characters" — which gives the 4/3 ratio, but it never states a percentage. The literal "33 percent" wording is in RFC 2045 §6.8 ("Base64 Content-Transfer-Encoding"): "the encoded data are consistently only about 33 percent larger than the unencoded data." Cite RFC 4648 §4 for the rule and RFC 2045 §6.8 for the figure.

How much bigger does Base64 make a file?

Base64 makes data about 33% larger. It packs every 3 bytes of input (24 bits) into 4 printable ASCII characters, and 4 ÷ 3 = 1.333, so the encoded output is roughly one-third bigger than the original. With line breaks added every 76 characters — common in email (MIME) and PEM files — the real-world increase is closer to 36-37%.

Why is Base64 exactly 33% larger and not more?

Because each Base64 character carries 6 bits of real data (2^6 = 64 possible values) but is stored in an 8-bit byte. You are using 6 of every 8 bits, wasting 2. That 8/6 ratio equals 1.333, the same 33% overhead. It cannot be less without giving up the text-safe alphabet that makes Base64 useful.

Does Base64 padding increase the size?

Only slightly, and only at the very end. When the input length is not a multiple of 3, Base64 appends one or two '=' characters so the output is always a multiple of 4. That adds at most 2 bytes total to the entire file, regardless of how large the file is — it is a fixed rounding cost, not a per-byte tax.

How do I calculate the Base64 size of a file?

Use the formula: encoded bytes = 4 × ceil(n ÷ 3), where n is the original size in bytes. For a quick estimate, multiply the original size by 1.333 (or 1.37 if line breaks are added). A 900 KB file becomes about 1.2 MB encoded.

Does Base64 make files bigger or smaller?

Always bigger — Base64 is an encoding, not a compression scheme. It never removes redundancy; it only re-represents existing bytes in a text-safe alphabet, which costs about 33%. If you need smaller output, compress with gzip or Brotli first, then Base64 the compressed result.

Can I compress Base64 to get rid of the overhead?

Compress before encoding, not after. Base64 output looks random-ish and compresses poorly, but the underlying binary often does not. Gzip the raw data first, then Base64 the compressed bytes — the final string can end up smaller than the original uncompressed file. Note that HTTP gzip on the wire also recovers much of the 33% during transfer.

Why does 1 byte become 4 Base64 characters?

Base64 always works in 4-character output blocks. A single byte (8 bits) fills less than two 6-bit groups, so Base64 emits 2 data characters plus 2 '=' padding characters to complete the 4-character block. That is the worst-case overhead — 300% for a lone byte — but it averages out to 33% as files get larger.

Is Base64 smaller than hexadecimal encoding?

Yes. Hex (Base16) uses 2 characters per byte, a 100% size increase. Base64 uses 4 characters per 3 bytes, only a 33% increase. Base64 is more compact because each character encodes 6 bits instead of hex's 4 bits, so Base64 is the better choice when size matters and the transport allows its alphabet.

Does the 33% overhead still apply after gzip compression?

Not on the wire. If your server sends Base64 text with gzip or Brotli enabled, HTTP compression recovers a large share of the inflation during transfer because Base64 is still fairly compressible. The 33% penalty remains in memory and in stored/uncompressed form, but the bytes actually transmitted are often much closer to the original size.

base64encodingfile optimizationweb performance