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.
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:
- Take three bytes of binary data (24 bits total).
- Split those 24 bits into four chunks of 6 bits each.
- 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:
| Step | Value |
|---|---|
| ASCII characters | C a t |
| Decimal byte values | 67, 97, 116 |
| 8-bit binary (24 bits) | 01000011 01100001 01110100 |
| Regrouped into 6-bit chunks | 010000 110110 000101 110100 |
| 6-bit decimal values | 16, 54, 5, 52 |
| Base64 alphabet index | Q 2 F 0 |
| Base64 output | Q2F0 |
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.
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 size | Base64 size (no line breaks) | Padding chars (=) | Size increase |
|---|---|---|---|
| 1 byte | 4 bytes | 2 | +300% |
| 2 bytes | 4 bytes | 1 | +100% |
| 3 bytes | 4 bytes | 0 | +33.33% |
| 4 bytes | 8 bytes | 2 | +100% |
| 6 bytes | 8 bytes | 0 | +33.33% |
| 100 bytes | 136 bytes | 2 | +36.00% |
| 1,000 bytes | 1,336 bytes | 2 | +33.60% |
| 1 KiB (1,024 B) | 1,368 bytes | 2 | +33.59% |
| 1 MiB (1,048,576 B) | 1,398,104 bytes | 2 | +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.
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:
| Format | Wrap width | Terminator | Wrapping overhead | Total increase |
|---|---|---|---|---|
| Unwrapped (data URI, JSON, JWT) | none | — | 0% | +33.33% |
| MIME, LF only | 76 | LF (1 byte) | +1.32% | +35.09% |
| MIME, CRLF | 76 | CRLF (2 bytes) | +2.63% | +36.84% |
| PEM, LF only | 64 | LF (1 byte) | +1.56% | +35.42% |
| PEM, CRLF | 64 | CRLF (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:
- The final quantum is an integral multiple of 24 bits → output is a multiple of 4 characters, no
=padding. - The final quantum is exactly 8 bits → two characters followed by two
=characters. - 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.