Practice this topic in a realistic system design interview
Storage systems are not just buckets for bytes. The storage type you choose affects how your application reads data, writes data, shares data, protects data, and pays for data.
The three common models are:
Most real systems use more than one. A web application might keep its database on block storage, shared application files on file storage, and user uploads in object storage.
The important skill is not memorizing product names. It is learning what each storage model is good at.
This chapter explains block, file, and object storage in plain terms and shows where each one fits.
Block, file, and object storage all keep data somewhere durable. The difference is the shape they show to your application.
The table below gives the quick version.
| Aspect | Block Storage | File Storage | Object Storage |
|---|---|---|---|
| Main idea | Disk volume | File system | Bucket/container of objects |
| Data unit | Fixed-size blocks | Files and directories | Objects with keys and metadata |
| Access style | Read/write block ranges through a disk interface | Open/read/write files by path | PUT/GET/DELETE objects by key |
| Common protocols | Local: NVMe, SATA, SAS. Network: NVMe-oF, iSCSI, Fibre Channel | NFS, SMB (plus parallel file systems like Lustre) | HTTP/REST APIs |
| Update model | Efficient random reads and writes | In-place file updates | Usually replace the object |
| Sharing model | Usually attached to one writer | Built for shared file access | Many clients through an API, but not normal file sharing |
| Latency profile | Lowest, especially local SSD/NVMe | Usually higher than block because it goes over a network | Usually higher than block/file, but built to scale |
| Best fit | Databases, VM disks, transactional workloads | Shared directories, legacy apps, home directories | Media, backups, logs, data lakes, static assets |
| Cloud examples | EBS, Persistent Disk, Azure Managed Disks | EFS, Filestore, Azure Files, FSx | S3, Cloud Storage, Azure Blob Storage |
A simple rule covers most designs:
Use block storage when software needs a disk (databases, VM boot volumes, low-latency random I/O). Use file storage when multiple machines need the same directory tree with normal file operations. Use object storage when you are storing lots of independent blobs and care about scale, durability, HTTP access, and cost.
Block storage is the closest model to a physical disk.
It gives a server a volume that looks like a disk made of numbered blocks. The storage layer does not know what those blocks mean. They might contain part of a database table, part of a video file, a file-system journal entry, or empty space.
That simple, low-level model is why block storage is fast and flexible. The operating system, database, or file system decides how to organize the bytes.
Block storage hands out raw numbered blocks. The layers above it decide what those blocks mean.
The diagram shows the path from an application down to the blocks on the volume.
On a normal server, the operating system formats a block device with a file system such as ext4, XFS, APFS, or NTFS. That file system maps paths like /var/lib/postgresql/base/... to blocks on the disk.
Databases add another layer. PostgreSQL, MySQL, MongoDB, and similar systems may store data in files, but internally they think in pages. A query might need a few 8 KB or 16 KB pages from different places on the volume.
Block storage is good at that kind of small, random reading and writing.
Block storage fits workloads that need fast, durable, disk-like access, usually from one machine.
Block storage is the right default when small reads and writes matter.
Local NVMe can be extremely fast. Cloud block volumes add a network hop, but they are still designed for predictable low-latency disk access compared with file or object storage.
This is why databases usually sit on block storage. A database cannot wait for an HTTP object request every time it needs a page from an index.
Transactional systems need to write data and know when it is safely on disk. Databases use write-ahead logs, file-system barriers, and fsync()-style operations to build ACID guarantees on top of block storage.
The details still matter. A bad disk cache setting, weak storage controller, or wrong mount option can break those guarantees. But block storage is still the storage model databases are designed around.
Virtual machines need something that behaves like a disk. The guest operating system expects to partition it, format it, mount it, and boot from it. Block storage provides that interface directly.
Object storage cannot boot an operating system. File storage can hold VM image files, but the running VM still needs something that behaves like a block device.
A normal block volume has one active writer. This is not just a cloud provider rule. It comes from how file systems work.
Most file systems assume they own the disk. They cache metadata in memory, decide which blocks are free, update journals, and reorder writes.
If two machines mount the same ordinary block volume and both think they own it, their views can get out of sync. The result can be corrupted files or a corrupted file system.
Some cloud and SAN products support multi-attach block volumes. They can be useful, but they do not magically make shared writes safe.
You still need a cluster-aware file system such as GFS2 or OCFS2, or an application that knows how to coordinate writes correctly.
For most application teams, if multiple hosts need shared file access, file storage is the simpler and safer tool.
Cloud block storage gives a VM a persistent disk without making you manage the physical disk. Providers usually replicate the data inside one zone or failure domain, which means one area that can fail together. They also provide snapshots and let you choose performance classes.
| Provider | Service | Typical Use |
|---|---|---|
| AWS | EBS | Persistent disks for EC2 |
| Google Cloud | Persistent Disk / Hyperdisk | Persistent disks for Compute Engine |
| Azure | Managed Disks | Persistent disks for Azure VMs |
Cloud block volumes are usually tied to one zone. They can survive VM failure, but that does not make them a full disaster-recovery plan.
Production systems still need backups, snapshots, replication, or database-level recovery.
Use block storage for relational and document databases that need random reads and writes. Also use it for VM boot disks and attached application disks.
It also fits transaction logs and queues that need durable low-latency writes, and applications that want a local file system without sharing it across many machines.
Avoid block storage when many servers need to share the same files, or when you want to keep huge amounts of independent data cheaply for a long time. File and object storage are better fits for those cases.
File storage gives applications a shared file system over the network.
Applications use familiar paths such as /mnt/shared/reports/q1.pdf. A file server or managed service handles the storage, permissions, caching, and locking behind the scenes.
The key difference from block storage is sharing. File storage is built so multiple machines can mount the same directory tree at the same time.
Several machines can reach the same directory tree at once. The shared file system sits between the machines and the data.
The diagram below shows that arrangement.
Common protocols and systems include:
| Name | Type | Common Use |
|---|---|---|
| NFS | Network protocol | Unix/Linux file sharing, cloud file systems such as EFS and Filestore |
| SMB | Network protocol | Windows file sharing, Azure Files, FSx for Windows |
| Lustre | Parallel file system | High-throughput workloads such as HPC and large-scale processing |
The file server owns the file-system metadata: file names, directories, permissions, sizes, timestamps, and locks.
When a client opens a file, checks permissions, lists a directory, renames a path, or takes a lock, the request goes through that shared layer.
File storage works well when several machines need the same files and the application expects normal file operations.
Many applications expect ordinary file operations: create, open, read, write, seek, rename, delete. File storage keeps that programming model while allowing more than one machine to see the same files.
That is valuable for web servers reading the same uploaded files, Kubernetes workloads that need ReadWriteMany volumes, build systems and CI workers sharing a workspace, user home directories mounted on many machines, and legacy applications that cannot be rewritten for an object API.
File storage supports operations such as appending to a file, replacing a small part of a file, or renaming a directory. Object storage generally does not.
This matters for applications that treat files as working state that changes over time, not as finished blobs.
File servers can coordinate locks, permissions, and visibility between clients.
This does not make a file share a distributed database. Locks can be advisory, client caching can affect what each machine sees, and protocol behavior differs. Still, for many shared-file workloads, the built-in coordination is good enough and much simpler than building it yourself.
The sharing features of file storage are useful, but they come with costs. Those costs grow as the data set and number of files grow.
Every file system needs metadata: directory entries, permissions, sizes, timestamps, mappings from files to blocks, and locks. In network file storage, many client operations depend on a metadata service.
At small and medium scale, this is usually fine. At very large scale, metadata work can dominate performance. Common examples are listing huge directories, walking deep directory trees, or creating millions of tiny files.
Managed file storage gives you stronger file behavior than object storage, and that behavior costs money. You pay for the coordination layer, lower-latency access, and shared directory tree.
At large scale, storing old logs, archives, or user media on file storage is often much more expensive than storing them in object storage.
A file share is usually regional or zonal. Sharing one file system across regions brings hard problems: higher latency, replication lag, conflicts, and failure handling.
Object storage is usually a better base for global distribution, especially when paired with a CDN.
Each major cloud provider offers managed file shares, so you do not have to run your own file servers.
| Provider | Service | Notes |
|---|---|---|
| AWS | EFS | Managed NFS for Linux workloads |
| AWS | FSx | Managed file systems such as Windows File Server, Lustre, NetApp ONTAP, and OpenZFS |
| Google Cloud | Filestore | Managed NFS file shares |
| Azure | Azure Files | Managed SMB and NFS file shares |
Managed file services remove a lot of operational work: replication, patching, failover, capacity management, and backups.
They do not remove the need to understand your workload. A directory with millions of tiny files, an application that makes constant metadata calls, or many writers fighting over the same files can still perform poorly.
Use file storage when multiple machines need to read and write the same files, or when the application expects file paths and normal file operations.
It also fits shared home directories, build workspaces, and mounted content directories, and any case where rewriting the application to use object storage is not worth the complexity.
Avoid file storage when files are mostly written once, accessed over HTTP, or kept for a long time at large scale. Those are usually object-storage workloads.
Object storage treats data as independent objects.
Each object has:
users/42/avatar.jpg.There is no mounted disk and no real directory tree. You call an API: put this object, get that object, delete this object, list keys with this prefix.
Instead of using a mounted disk, the application talks to an API that stores and fetches whole objects by key.
The diagram shows that flow into a bucket.
Keys often look like paths:
The slash is just part of the name. It is not a real directory separator.
Consoles and SDKs may show folder-like views because humans like folders, but the object store is really looking up keys inside a bucket or container.
This design is one reason object storage scales so well. The system can spread keys across many servers, copy data across different failure domains, and grow without making the client manage those details.
Object storage is usually accessed through HTTP APIs:
That API shape has practical advantages. Browsers and mobile apps can upload directly with signed URLs. CDNs can cache and serve objects efficiently. Services in any language can use the same storage system. Firewalls and load balancers already understand HTTP.
But object storage is not a disk. A GET request is not the same as reading a local block. Object storage is built for durable, scalable object access, not tiny random writes in microseconds.
Object storage is built for large collections of independent items, especially items that are written once and read many times.
Images, videos, documents, backups, logs, model artifacts, and data lake files are excellent object-storage use cases. They are usually written once, read many times, and replaced rather than edited in place.
Cloud object stores are designed for very high durability. They copy or erasure-code data across multiple devices and failure domains, verify checksums, and repair lost or corrupted pieces in the background.
They also provide lifecycle policies. Old logs can move from frequent-access storage to cheaper archive tiers. Temporary exports can expire automatically.
These features matter when retention grows from gigabytes to petabytes.
Modern object stores give strong read-after-write consistency for object operations within a single region. In plain English: after a write succeeds, a later read sees that write.
S3 has worked this way since December 2020, and GCS and Azure Blob behave the same.
After a successful PUT, the next GET sees the new object, the next LIST includes it, and the next DELETE plus GET returns not found. Older documentation that described eventual consistency for new-key reads or for listings no longer applies.
Cross-region replication, event notifications, and bucket configuration changes remain eventually consistent.
Object storage has become the default storage layer for static websites, CDNs, data lakes, and ML pipelines. Query engines, stream processors, and data warehouses can read directly from object stores using formats such as Parquet, ORC, JSON, CSV, and Avro.
The same design that makes object storage scale also makes it a bad fit for a few disk-like workloads.
If you need to change a few bytes in the middle of a large object, object storage is the wrong tool. In most designs, you write a new object or a new version of the object.
Some systems support multipart upload, ranged reads, versioning, object composition, or append-like features. Those features are useful, but they do not make object storage behave like a local file system or database disk.
Object storage does not provide the normal file-system contract of open, seek, write, rename, and fsync.
FUSE adapters can make object storage look like a file system, but they cannot perfectly reproduce local file-system behavior.
They can be useful for read-heavy or compatibility workloads. They are risky for software that depends on exact file-system behavior.
Object storage operations travel through an API layer, authorization checks, routing, metadata lookup, and distributed storage nodes.
That is fine for serving a photo or reading a Parquet file split. It is not fine for the tight inner loop of a transactional database.
Object stores scale well, but request shape still matters. Hot objects, poor key design, excessive listing, millions of tiny objects, and chatty request patterns can all cause cost or performance problems.
Modern cloud object stores do a lot of automatic partitioning, so old advice such as always randomizing S3 key prefixes is usually unnecessary. The better rule is to avoid designs that concentrate all traffic on a small number of keys or require huge recursive listings.
Use object storage for user uploads, media files, backups, archives, compliance retention, application logs, event archives, data lakes, analytics datasets, static assets served through a CDN, ML datasets, model artifacts, and batch-processing inputs.
Avoid it for primary database storage, VM boot volumes, workloads that need frequent small in-place updates, and applications that need strict file-system behavior.
The fastest way to choose is to start with the access pattern, not the product name.
Ask what the application needs to do with the data.
Picking a storage type comes down to a few practical questions about access and sharing.
The table below pairs common workloads with the storage type that usually fits.
| Use Case | Recommended Storage | Reason |
|---|---|---|
| PostgreSQL, MySQL, MongoDB | Block | Low-latency random I/O and durable writes |
| VM boot disk | Block | Operating systems need a disk interface |
| Single-host container volume | Block | Fast local file-system behavior |
Kubernetes ReadWriteMany volume | File | Multiple pods need the same mounted file system |
| Shared user home directories | File | Familiar paths, permissions, and multi-host access |
| Legacy app expecting file paths | File | Avoids rewriting the application around an API |
| User uploads | Object | Durable, scalable, CDN-friendly |
| Static website assets | Object | HTTP access and CDN integration |
| Video storage and delivery | Object | Large files that rarely change and edge caching |
| Backups and archives | Object | Low-cost retention and lifecycle policies |
| Data lake | Object | Cheap scalable storage with analytics integration |
| Application logs | Object | Write-once retention and batch analytics |
| Session data | Usually neither | Use Redis or another low-latency store; persist separately if needed |
Production systems often use more than one storage model.
The database uses block storage because it needs fast page reads, WAL writes, and durable flushes. The application uses file storage only where it needs shared mounted files. User content and logs go to object storage because they are durable, HTTP-friendly, and much cheaper to keep over time.
This separation is one of the most common storage patterns in scalable systems.
Most storage problems come from picking the wrong model for the access pattern, then trying to force it to behave like something else.
These mistakes show up often in real systems.
Object storage is excellent for database backups, exports, and analytical copies. It is not a primary disk for a transactional database.
A database needs low-latency random writes and precise durable-write behavior.
File storage feels convenient because everything has a path. But for large collections of content that is written once and rarely changed, file storage can become expensive and metadata-heavy.
If the application mainly uploads and downloads whole files, object storage is usually a better fit.
Mount adapters are useful, but they can hide important differences: rename behavior, directory listings, partial writes, locks, and performance under many small operations.
Use them deliberately. Do not treat them as a free way to turn object storage into a normal disk.
A disk that survives VM restart is not automatically a disaster-recovery system. A file share replicated across zones is not automatically global active-active storage.
Object storage is highly durable, but availability, replication policy, deletion protection, and recovery process still need design.
Block storage is for disk-like workloads: databases, VM disks, low-latency random I/O, and durable writes. Multi-writer access is possible only with special coordination.
File storage is for shared file workloads where multiple machines need the same paths, permissions, locks, and in-place file operations. Watch out for metadata-heavy workloads and cost at scale.
Object storage is for independent objects at large scale: uploads, media, backups, logs, data lakes, static assets, and archives. It gives excellent durability and cost, but it is not a disk or a normal file system.
The best storage choice follows the access pattern. Ask how the data is read, written, shared, kept, and recovered. Once those answers are clear, the right storage model is usually obvious.
10 quizzes