Independent marketplace for cloud provider accounts across 22 providers

Storage & Data

Block Storage vs Object Storage: Which Does Your App Need?

Block volumes look like disks and object stores look like APIs, and most applications need both. This guide compares the two models property by property, places common workloads on the right one, and lists the mistakes that force a painful migration later.

A cloud server with an attached block volume alongside a bucket holding user uploads and archives

Two Kinds of Cloud Storage, One Decision

Teams rarely get this choice wrong out of ignorance. They get it wrong because the first storage they used was a disk, and a disk is what every framework tutorial assumes. So uploads land next to the code, the volume fills, and a second server cannot see any of it.

Block storage and object storage are not competing products. They solve different problems and most applications end up using both. The skill is knowing which bytes belong where before the volume is full.

This piece works from the properties of each model, then applies them to the workloads that actually turn up in a small production estate.

A Disk You Format Against an API You Call

Block storage presents raw blocks over a storage network. The operating system sees a device such as /dev/sdb, you create a filesystem on it, and from that moment the kernel handles reads, writes, seeks and locking exactly as it would for a local drive. Amazon EBS, Azure managed disks, Google Persistent Disk, DigitalOcean Volumes, Linode Block Storage, Hetzner Volumes and OCI Block Volumes all fit this shape.

A block volume attaches to one instance at a time in the normal case. Multi attach modes exist, but they require a cluster aware filesystem to be safe, which is a specialist arrangement rather than a default.

Object storage exposes an HTTP interface. There is no device, no filesystem and no partial write. A client sends a complete object and later fetches it whole or by byte range. Any number of machines can read and write concurrently because the service, not the kernel, arbitrates.

That single difference drives everything else: capacity planning, durability model, access control, pricing and the failure modes you will meet at three in the morning.

The Properties That Decide It

PropertyBlock volumeObject store
InterfaceDevice plus filesystemHTTP requests against keys
Concurrent writersOne instance in normal useUnlimited clients
Partial updatesYes, byte levelNo, replace the whole object
CapacityProvisioned in advance, resized manuallyGrows as you write
Latency profileSub-millisecond class, network attachedHTTP request overhead per operation
Typical chargeProvisioned size, plus performance units on some tiersStored bytes, requests and egress
Shared between serversRarely, with caveatsNaturally
Lives past the instanceYes, if it is not a local diskYes, always

Two rows deserve emphasis. Provisioned capacity means you pay for the volume you created, not the bytes you wrote, so a half empty volume is pure waste. And because object storage cannot update a byte in place, any workload that rewrites small regions of a large file is disqualified immediately.

Where Each Workload Belongs

Databases and anything with a write ahead log

Block, without hesitation. PostgreSQL, MySQL, MongoDB and their relatives depend on fsync semantics, file locking and small random writes. Put the data directory on a volume sized for growth and pick a performance tier that matches the write pattern, as discussed in the NVMe storage guide.

User uploads, avatars, attachments, generated reports

Object, without hesitation. These are write once, read many, and they must survive the instance that received them. Storing them on the web server is the single most common reason an application cannot be scaled horizontally later.

Application logs

Both, in sequence. Write locally to a volume with rotation configured, ship to a central system, and archive the compressed originals into a bucket where a lifecycle rule ages them out.

Container images and build artifacts

Object, usually wrapped in a registry or an artifact service. The consumers are many and short lived, which is exactly the access pattern object storage is built for.

Static site assets and media delivery

Object, fronted by a CDN. Serving images from a VM burns bandwidth and CPU for no benefit, a point covered in the CDN basics article.

A shared directory several servers write to

Neither, strictly. That is a file storage problem and it deserves a file service rather than a clever workaround.

The Layout Most Applications Converge On

A typical production server ends up with a root volume holding the operating system and the application, a separate data volume for the database if it is self hosted, and a bucket for everything users upload or the system generates.

Splitting the data volume from the root volume is worth the small extra effort. It lets you resize storage without touching the boot device, snapshot the data on its own schedule, and detach it for recovery if the instance itself becomes unbootable.

Frameworks make the object side easy. Most have a storage abstraction with an S3 driver, so switching from local disk to a bucket is configuration rather than a rewrite. Do it before launch; retrofitting file paths after users have uploaded thousands of files is a migration nobody enjoys.

Provider documentation is worth reading on the block side in particular, because tier names and resize rules differ. The EBS volume type reference and the Azure managed disk types page are the two most useful starting points.

Four Expensive Mistakes

Treating a volume snapshot as an application backup. A snapshot of a running database captures a crash consistent image, which usually replays fine but is not the same as a verified logical dump. Pair it with a real backup routine.

Oversizing volumes for headroom. Provisioned capacity bills whether or not you use it, and most providers let you grow a volume online while none of them let you shrink it easily. Start smaller and expand.

Putting a database on object storage through a filesystem shim. It appears to work in testing and falls over under concurrency, because the locking guarantees the engine expects are not there.

Ignoring where the bytes leave from. Object storage served directly to end users generates egress on every request, so a popular asset without a cache in front of it becomes a recurring bill rather than a one off upload.

Key Takeaways

  • Choose block when the operating system needs a real filesystem: databases, search indexes, message brokers, anything doing small random writes.
  • Choose object when many clients read the same immutable files: uploads, assets, archives, artifacts, backups.
  • Keep application state off the root volume so you can resize, snapshot and detach independently.
  • Never store user uploads on the instance filesystem if there is any chance of a second server.
  • Expect to pay for provisioned block capacity and for object requests plus egress; the two bills behave nothing alike.
  • If several machines need shared read-write access to the same tree, look at a managed file service rather than forcing either model.

Block storage on the developer clouds is straightforward to attach and detach, which makes it a good place to practise the split. A Linode account exposes Block Storage volumes alongside its object storage in one panel, and the DigitalOcean and Linode comparison covers how the two present the same primitives. For the object side in depth, continue with the object storage explainer.

Questions about a cloud account?

Ask about products, variants, availability or purchasing on either channel.