What is Base64 encoding and when should you use it?
Base64 shows up in JWTs, data URIs, email attachments and auth headers — and is routinely mistaken for a security measure. Here is what it actually is, and a decision framework for when to reach for it.
By Sk Md Rakib · Published · Updated · 10 min read
What Base64 actually does
Base64 represents arbitrary binary data using 64 printable ASCII characters: A–Z, a–z, 0–9, plus two symbols. It takes three input bytes (24 bits) and splits them into four six-bit groups, mapping each group to one character. That is why encoded output is about 33% larger than the input, and why the length of a Base64 string is always a multiple of four once padding is applied.
It exists to solve one problem: some channels were designed for text and either corrupt or reject raw bytes. Email bodies, HTTP header values, JSON string values, XML attributes and URLs all fall into that category. Base64 makes any byte sequence survive them intact.
What Base64 does not do
It is not encryption, not compression, and not obfuscation worth the name. Anyone holding the encoded string can decode it instantly with no key. HTTP Basic Authentication encodes credentials in Base64 and derives all of its protection from TLS — remove HTTPS and the credentials are effectively in plain text.
It also makes data bigger, so using it to 'shrink' anything is backwards. And because the encoded form is not human-readable, it is a common hiding place for accidental secrets: a Base64 blob in a repository looks like noise, which is exactly why credentials survive in one for years.
Standard versus URL-safe alphabets
Standard Base64 uses + and / for its final two characters. Both are hostile in a URL: + can be interpreted as a space in query strings and / separates path segments. URL-safe Base64, defined in RFC 4648, substitutes - and _ so the encoded value passes through URLs, filenames and headers untouched.
JWTs use URL-safe Base64 with the trailing = padding stripped, which is why a token pasted into a standard decoder sometimes fails with an input-length error. If a decode fails on something you know is valid, alphabet or padding mismatch is almost always the reason.
Where it is genuinely the right tool
Use Base64 to embed a small image, icon or font directly in CSS or HTML as a data URI, eliminating an HTTP request for an asset measured in a few kilobytes. Use it to carry binary values inside JSON, which has no binary type. Use it for email MIME attachments and for encoding credentials or binary configuration in headers and environment variables.
Avoid it for large files, where multipart uploads move the same bytes without the 33% overhead; for anything requiring confidentiality, where you want real encryption applied before encoding; and for large inline images, where the data URI bloats a render-blocking stylesheet and defeats browser caching.
- Good fit: assets under roughly 4 KB inlined as data URIs.
- Good fit: binary fields inside a JSON document.
- Bad fit: anything you need kept secret.
- Bad fit: multi-megabyte file transfer.
Encoding and decoding across languages
Every mainstream runtime ships Base64 support. In the browser, btoa and atob handle Latin-1 strings and need TextEncoder or TextDecoder to work correctly with Unicode — a classic source of mojibake. In Node.js, Buffer.from(str, 'base64') decodes and buf.toString('base64') encodes. Python uses the base64 module, and Go uses encoding/base64, both offering the URL-safe alphabet as a separate encoder.
For ad-hoc work, our Base64 Encoder handles both alphabets in your browser, and the JWT Decoder does the URL-safe split-and-decode for tokens so you do not have to do it by hand.
Where Base64 costs you, and what to use instead
Base64 represents three bytes with four characters, so every payload grows by about thirty-three per cent before any protocol overhead. That is a reasonable price for making binary data safe in a text channel, and a poor one when the channel already handles binary. Inlining a large image as a data URI, for example, inflates the HTML document, blocks it from being cached separately, and delays first paint — a plain URL to the file is almost always faster.
The rule of thumb is to encode only when the transport genuinely cannot carry raw bytes: an email MIME part, a JSON string field, an environment variable, an HTTP header, a JWT segment, or a small icon where saving a request matters more than the extra bytes. For file uploads, prefer multipart form data or a direct binary body. For large assets, prefer a URL. For anything above a few kilobytes inside JSON, consider whether the payload belongs in JSON at all.
Choose the right alphabet as well. Standard Base64 uses plus and slash, which need percent-encoding in URLs and are invalid in filenames; Base64url swaps them for hyphen and underscore and usually drops the padding. Mixing the two is a routine source of decode failures, especially when a token is generated with one alphabet and parsed with the other.
And repeat the point that causes the most damage: encoding is not protection. Anyone can decode it instantly, no key required. If a value must stay secret, encrypt it, keep the key somewhere the payload never travels, and only then encode the ciphertext for transport.