Object storage is a service for storing files: images, videos, PDFs, anything binary. Instead of putting files on your server's hard drive, you upload them to a bucket, where each file is an object addressed by a key.
The key looks like a path (avatars/user-123.png), but the storage is flat. The
/ is just part of the key string. There are no real folders.
It's not a file system
An object store can look and feel like a file system, but it isn't one. There's no atomic move or rename. To "rename" an object you copy it to a new key and then delete the old one, which is two separate requests. In between, both keys exist, and anyone listing the bucket can see that. Treat keys as effectively immutable once written.
S3 is the industry standard
S3 started as an Amazon product, but it's now the industry-standard interface for object storage. Cloudflare R2, MinIO, and Backblaze B2 all speak the same S3 API, so the same client code works across providers. You write your upload and download logic once and stay free to switch.
Common reasons you may need one
- User-uploaded files (avatars, attachments)
- Static assets (images, compiled frontend bundles) — often served through a CDN that caches bucket objects at edge locations for fast global delivery
- Large datasets or backups
How to use it
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
const s3 = new S3Client({ region: "us-east-1" });
await s3.send(new PutObjectCommand({
Bucket: "my-app-uploads",
Key: "avatars/user-123.png",
Body: fileBuffer,
ContentType: "image/png",
})); Don't store files in your database or on your server's filesystem. Object storage is cheaper, more durable, and scales without you managing disk space.
Check your understanding
Why one shared S3 API matters
Cloudflare R2, MinIO, and Amazon S3 all speak the same S3 API. Why is that useful?