When (and When Not) to Store Files as Base64 in a Database
It's tempting to Base64 encode a file and drop it straight into a text column — no new column type, no separate storage system, just a string. Sometimes that's fine. Often it isn't. Here's how to decide.
When a Base64 text column makes sense
For small values — a config blob, a tiny thumbnail, a serialized key, a Kubernetes-style Secret value — storing Base64 text in a normal column is simple and avoids introducing a binary column type or a separate storage service. It also travels cleanly through JSON-based APIs, ORMs, and text-based exports without any special handling.
The costs that show up at scale
Base64 adds about a 33% size overhead versus storing raw bytes, which compounds with your database's own per-row and index overhead. Text columns storing large Base64 blobs also bloat query results, backups, and replication traffic — a SELECT * that incidentally includes a large Base64 column moves far more data than one that includes a lightweight reference.
The alternatives
A dedicated binary column (BLOB in MySQL, bytea in PostgreSQL) stores raw bytes directly, avoiding the Base64 overhead entirely while staying inside your database. For larger files — images, videos, documents — object storage (S3, GCS, Azure Blob Storage, etc.) with just a URL or object key stored in the database scales much better: it separates file storage from your transactional database, enables CDN caching, and keeps your database backups and queries fast.
A common real-world case: Kubernetes Secrets
Kubernetes Secret manifests are YAML/JSON — text formats — so binary or multi-line values are Base64 encoded to fit safely as a text field value (see YAML to Base64). This is purely for text-safety, not security: Kubernetes Secrets still require encryption at rest and RBAC to actually protect the data, since Base64 alone provides no confidentiality.
Rule of thumb
Small, infrequently-large, text-adjacent values (config, small keys, Secret fields): a Base64 text column is fine. Larger or frequently-accessed binary files (images, videos, documents, backups): use a binary column or, better, object storage with a reference in the database.