Base64 Encoding: When, Why, and How to Use It
Published April 2026 · 9 min read
Base64 is one of the most widely used encoding schemes in software development, yet many developers use it without fully understanding how it works or when it is the right choice. This guide covers the algorithm from first principles, walks through real-world use cases, and helps you avoid common mistakes that can bloat payloads or create false security.
Need to encode or decode something quickly? Try our Base64 Encoder/Decoder tool — supports text and file encoding with instant results.
What is Base64?
Base64 is a binary-to-text encoding scheme that represents binary data using a set of 64 printable ASCII characters. It was designed to safely transmit binary data over channels that only support text, such as email (SMTP) or embedding data inside JSON and XML documents.
The name "Base64" comes from the fact that the encoding uses exactly 64 distinct characters to represent data. Each character encodes 6 bits of information (since 2^6 = 64), compared to the 8 bits in a standard byte.
How the Algorithm Works
The Base64 encoding process converts every 3 bytes (24 bits) of input into 4 characters (24 bits at 6 bits each) of output. Here is the step-by-step process:
- Take 3 bytes of input — this gives you 24 bits total.
- Split into four 6-bit groups — each group has a value from 0 to 63.
- Map each 6-bit value to a character using the Base64 alphabet.
- Handle padding — if the input is not a multiple of 3 bytes, pad the output with
=characters.
Example: Encoding "Hi"
"H" = 0x48 = 01001000, "i" = 0x69 = 01101001
Combined: 01001000 01101001 + 00000000 (padded to 3 bytes)
Split into 6-bit groups: 010010 | 000110 | 100100 | 000000
Values: 18, 6, 36, 0 → Characters: S, G, k, A
With padding (only 2 input bytes): SGk=
The Base64 Alphabet
The standard Base64 alphabet (defined in RFC 4648) consists of:
A-Z (indices 0-25)
a-z (indices 26-51)
0-9 (indices 52-61)
+ (index 62)
/ (index 63)
= (padding character)
These 64 characters were chosen because they are safe in virtually all text-based protocols. Every character is a printable ASCII character that will not be mangled by mail servers, HTTP headers, or text editors.
Base64 vs Base64URL Encoding
Standard Base64 uses + and / characters, which are problematic in URLs and filenames. Base64URL (also defined in RFC 4648) makes two substitutions:
| Feature | Base64 | Base64URL |
|---|---|---|
| Index 62 | + | - |
| Index 63 | / | _ |
| Padding | Required (=) | Usually omitted |
JWT tokens use Base64URL because each segment appears in URLs and HTTP headers. If you ever see a "malformed Base64" error when decoding a JWT, you probably need to replace - with + and _ with / before decoding.
The 33% Size Overhead
Base64 encoding always increases the data size by approximately 33%. Here is why: every 3 bytes of input produce 4 bytes of output. The ratio is 4/3 = 1.333..., meaning a 33.3% increase. When you add padding and potential line breaks (some implementations add newlines every 76 characters), the overhead can be slightly higher.
A 1 MB image becomes ~1.33 MB when Base64-encoded. A 10 KB JSON payload with an embedded Base64 image of 100 KB adds 133 KB instead of 100 KB. For small values this overhead is negligible; for large files it adds up quickly.
This is why Base64-encoding large files for transmission is generally a bad idea when binary-safe transport (like HTTP multipart) is available.
Common Use Cases
Data URIs
data:image/png;base64,iVBORw0KGgo...Embed small images, fonts, or files directly in HTML and CSS. Eliminates an extra HTTP request but increases document size by 33%. Best for icons under 5-10 KB.
Email (MIME)
SMTP was designed for 7-bit ASCII text. Binary attachments (images, PDFs, documents) are Base64-encoded in MIME format so they survive transport through mail servers. This is why email attachments are always larger than the original files.
JWT Tokens
header.payload.signatureEach of the three JWT segments is a Base64URL-encoded JSON object (or binary signature). This allows JWTs to be safely passed in HTTP headers, cookies, and URL query parameters.
HTTP Basic Authentication
Authorization: Basic dXNlcjpwYXNzThe username and password are concatenated with a colon and Base64-encoded. This is encoding, not encryption — anyone can decode it. Always use HTTPS with Basic Auth.
API Payloads
When a JSON API needs to include binary data (like a file upload or a generated PDF), Base64 encoding the binary content lets it fit neatly into a JSON string field. However, multipart form data is usually the better choice for large files.
Base64 in JavaScript
JavaScript provides different Base64 APIs depending on the runtime environment. Here is what you need to know:
Browser: btoa() and atob()
btoa("Hello") // "SGVsbG8="atob("SGVsbG8=") // "Hello"btoa() encodes a string to Base64, atob() decodes it. Critical limitation: these functions only handle Latin-1 characters. For Unicode text, you must first encode to UTF-8:
btoa(unescape(encodeURIComponent(unicodeString)))Or use the modern approach with TextEncoder:
const bytes = new TextEncoder().encode(text);const base64 = btoa(String.fromCharCode(...bytes));Node.js: Buffer
Buffer.from("Hello").toString("base64") // "SGVsbG8="Buffer.from("SGVsbG8=", "base64").toString() // "Hello"Node.js Buffer handles UTF-8 natively and supports Base64URL via the "base64url" encoding parameter. This is the most reliable option for server-side code.
File to Base64 (Browser)
const reader = new FileReader();reader.onload = () => console.log(reader.result);reader.readAsDataURL(file); // "data:...;base64,..."FileReader produces a full data URI including the MIME type prefix. Split on the comma to get just the Base64 string.
Common Mistakes to Avoid
Using Base64 for "security"
Base64 is encoding, not encryption. It provides zero confidentiality. Anyone can decode a Base64 string instantly. Never use it to hide passwords, API keys, or sensitive data. If you need security, use proper encryption (AES, RSA) or hashing (bcrypt, Argon2).
Double encoding
A surprisingly common bug: encoding data to Base64 twice. The second encoding turns the first Base64 string (which is already ASCII) into an even longer Base64 string. The result is a payload that is 78% larger than the original with no benefit. Always check if your data is already encoded before encoding.
Ignoring the Unicode limitation of btoa()
Calling btoa() on a string with characters outside the Latin-1 range throws a DOMException. This commonly happens with emoji, CJK characters, or any non-ASCII text. Always encode to UTF-8 first.
When NOT to Use Base64
- Large file transfers — use multipart uploads or binary streams. The 33% overhead adds up quickly: a 100 MB video becomes 133 MB as Base64.
- Storing images in databases — store the original binary (BLOB) or use object storage (S3) with URL references. Base64 in a database wastes 33% more storage and slows queries.
- Security or obfuscation — Base64 is trivially reversible. Use proper encryption for confidentiality and hashing for integrity.
- Large inline images in HTML/CSS — anything over ~10 KB as a data URI bloats your document, cannot be cached separately, and hurts page load times.
- When binary transport is available — modern protocols like HTTP/2, WebSockets, and gRPC handle binary data natively. Base64 adds unnecessary overhead.
Comparison with Other Encoding Schemes
| Encoding | Overhead | Characters Used | Best For |
|---|---|---|---|
| Base64 | ~33% | A-Z, a-z, 0-9, +, / | Binary data in text contexts |
| Hex (Base16) | 100% | 0-9, A-F | Hashes, colors, debugging |
| URL Encoding | Up to 200% | ASCII + %XX escapes | URL query parameters |
| Base32 | ~60% | A-Z, 2-7 | Case-insensitive contexts, TOTP |
Base64 offers the best space efficiency of any common text encoding scheme. Hex encoding doubles the size (each byte becomes two hex characters), and URL encoding can triple the size for non-ASCII content. Base32 is less efficient than Base64 but is useful when you need case-insensitive output, such as in OTP secret keys.
Key Takeaways
- Base64 converts 3 bytes into 4 characters using a 64-character alphabet.
- It adds ~33% size overhead — use it only when text-safe transport is required.
- Base64URL replaces
+/with-_for URL safety. JWTs use Base64URL. - In the browser, use
btoa()/atob()for Latin-1 strings; use TextEncoder for Unicode. - In Node.js,
Bufferhandles Base64 encoding natively with full UTF-8 support. - Base64 is encoding, not encryption. Never rely on it for security.
- Prefer binary transport (multipart, streams) over Base64 for large files.
Try It in DevPop
Encode and decode Base64 strings instantly with our free tool. Supports text input, file upload, Base64URL mode, and live preview.
Open Base64 Tool