Guide
Why Base64 encoding makes files about 33% bigger (math)
It's not a bug or an inefficient implementation — the 33% overhead is baked into what Base64 is doing.
By Buğra SözeriPublished
Base64 doesn’t compress anything — it does the opposite. It exists to make binary data safe to carry through text-only channels (email bodies, JSON strings, XML, URLs) that were never designed to handle raw bytes, and that safety costs space: every 3 bytes of input become 4 characters of output, a fixed 4:3 ratio that works out to roughly 33% larger than the original, regardless of what the data actually is.
The math behind the 33%
Base64’s alphabet has 64 symbols (A-Z, a-z, 0-9, plus two more characters, typically + and /), and 64 = 2⁶, so each output character encodes exactly 6 bits. Three bytes of input is 24 bits, which splits evenly into four 6-bit groups — hence 3 input bytes become 4 output characters. Since each character is then stored as one byte of text, 3 bytes of binary data become 4 bytes of Base64 text: a 4/3 ≈ 1.333 multiplier, or a 33.3% size increase. This isn’t implementation-specific — it’s defined this way in RFC 4648, the IETF standard every Base64 encoder follows.
Padding: the extra bit
| Input length (bytes) | Encoded length | Padding |
|---|---|---|
| Multiple of 3 (e.g. 3, 6, 9…) | Exact 4/3 ratio | None |
| Remainder 1 (e.g. 1, 4, 7…) | Rounds up to next group of 4 | == |
| Remainder 2 (e.g. 2, 5, 8…) | Rounds up to next group of 4 | = |
When the input length isn’t a clean multiple of 3, the last group gets padded with one or two = characters so the total output length stays a multiple of 4 — some decoders require this to parse the string correctly, even though it’s technically redundant information. On small inputs the padding can push the overhead slightly above 33%, but the effect shrinks toward the theoretical 33.3% as the input gets larger.
When the overhead is worth paying
The 33% cost buys compatibility: Base64 output is plain ASCII, so it survives being pasted into a JSON string, an XML attribute, a URL query parameter, or an email body without corruption — none of which can safely hold raw binary bytes. That’s the tradeoff behind embedding small images as data URIs or attaching files to an email. For genuinely large files, or anywhere a binary-safe transport already exists (a file upload endpoint, multipart form data, an object-storage API), skipping Base64 and sending the raw bytes avoids the overhead entirely — see the Base64 tool if you need to check exactly how large a given file will become before you commit to encoding it.
Frequently asked questions
- Why exactly 33% bigger, not some other number?
- Base64 encodes 3 bytes (24 bits) of input as 4 output characters (6 bits each, since the alphabet has 64 symbols). That's a 4:3 ratio, or exactly 33.3% more characters than input bytes — and since each output character is stored as one byte in a text file, the file itself grows by roughly a third.
- Can I avoid the 33% overhead?
- Only by not using Base64 — the overhead is inherent to representing arbitrary binary data as printable ASCII text. If size matters more than avoiding binary-unsafe transport, send the raw binary directly (e.g. multipart form uploads, or a binary API body) instead of encoding it to Base64.
- Does gzip compression cancel out the Base64 overhead?
- Partially. Base64 output is fairly compressible because its 64-character alphabet is small and repetitive compared to random binary, so gzip typically recovers some but not all of the lost ground — you'll usually still end up somewhat larger than the raw binary transferred with gzip alone.
- Why does Base64 output sometimes end with = or == signs?
- That's padding. Base64 groups input in chunks of 3 bytes; when the input length isn't a multiple of 3, the last group is padded with 1 or 2 '=' characters to keep the output length a multiple of 4, which some decoders require to parse correctly.
Sources & references
Authoritative references cited by this piece. Verified by Buğra Sözeri on the dates shown and re-checked at every deploy.
- RFC 4648 — The Base16, Base32, and Base64 Data Encodings — The IETF standard defining the Base64 alphabet, padding, and the 3-byte-to-4-character grouping(as of )
- MDN — Base64 encoding and decoding — MDN's explanation of Base64's binary-to-text purpose and size overhead(as of )
Related
More guides on this topic
- Cron Expression Tutorial: How to Read and Write Crontab SchedulesA field-by-field walkthrough of cron syntax — the five-column anatomy, the special characters, real examples you can paste, and the day-of-month / day-of-week quirk that bites everyone exactly once.
- JSON vs YAML: Choosing the Right Config FormatA side-by-side comparison of JSON and YAML for configuration files — syntax, comments, anchors, strict parsing, the Norway problem, JSON's number-precision trap, and a decision tree for picking one.
- Cryptographic Hashing Explained: MD5, SHA-1, SHA-256, SHA-512What a cryptographic hash actually does — the three properties that matter, why MD5 and SHA-1 are dead, where SHA-2 and SHA-3 fit, and why bcrypt/Argon2 exist instead of hashing passwords with SHA-256.
- Regex Cheat Sheet: Common Patterns Every Developer NeedsTwenty-five battle-tested regex patterns — email, URL, IPv4, IPv6, ISO date, UUID, semver, hex color, US and international phone, slug — plus the quantifier, lookaround, and flavour notes that make them portable.
Published September 25, 2026