AWS Storage Services Explained: S3, EBS, EFS, RDS, DynamoDB

AWS has eight distinct storage services. Choosing the wrong one means overpaying, hitting hard limits later, or building workarounds that should not exist. This page gives you a clear framework for picking the right service for each workload.

The short answer: use S3 for files and objects, EBS for EC2 disks, EFS for shared filesystems, RDS or Aurora for relational databases, DynamoDB for high-throughput key-value workloads, ElastiCache to speed up reads and sessions, and S3 Glacier for long-term archives.

Mental model

Think of the services like different types of storage in a large office building. S3 is the postal room where you drop off and collect whole parcels. EBS is your personal desk drawer — fast, nearby, yours alone. EFS is the shared filing cabinet the whole floor uses. RDS is the records department with an organised index you can search and cross-reference. DynamoDB is a fast-lookup directory where you search by ID only. ElastiCache is a whiteboard of answers you write up so you do not keep walking to the records department. Glacier is the basement archive you visit once a decade.

How to choose in 60 seconds

Decision framework
  • Storing files, objects, or raw bytes by name? Use S3. Scales to any size, very low cost per GB.
  • EC2 instance needs a local disk? Use EBS. Attaches directly, provides block-level I/O.
  • Multiple EC2 instances need the same files at once? Use EFS. A managed NFS filesystem any number of instances can mount.
  • Structured, relational data needing SQL and joins? Use RDS or Aurora for higher-availability workloads.
  • Key-based access patterns at massive throughput? Use DynamoDB.
  • Caching frequent reads or sub-millisecond session storage? Use ElastiCache (Redis or Memcached).
  • Compliance data you need to keep but almost never access? Use S3 Glacier or S3 Glacier Deep Archive.

AWS storage services at a glance

ServiceBest forNot ideal forAccess patternTypical examples
S3Files, objects, static assets, data lakes, backupsLow-latency block I/O, database files, frequent partial updatesHTTP GET/PUT (whole objects)Image uploads, log archives, CDN origin, Athena data lake
EBSEC2 OS volumes, databases running on EC2Shared access from many instances, large cold archivesBlock I/O (mounted as disk)EC2 root volume, self-managed PostgreSQL on EC2
EFSShared filesystem across multiple EC2 instancesSingle-instance workloads where EBS would be cheaperNFS (POSIX filesystem)Shared CMS media library, Lambda shared config files
RDSRelational databases with SQL, joins, transactionsVery high write throughput, schemaless or unstructured dataSQL queriesE-commerce product catalogue, user accounts, order history
AuroraRelational workloads needing high availability and performanceSmall dev or staging environments where cost mattersSQL queries (MySQL/PostgreSQL protocol)High-traffic SaaS application, multi-region read distribution
DynamoDBHigh-throughput key-based lookups at any scaleComplex SQL queries, ad hoc reporting, heavily relational dataKey-value or document (primary key, sort key)Gaming leaderboards, IoT telemetry, user profile store
ElastiCacheCaching frequent reads, session storage, pub/subPrimary durable storage (data can be lost on node failure)In-memory key-value (Redis/Memcached protocol)Database query cache, session tokens, rate-limit counters
S3 GlacierLong-term archives accessed rarely or neverFrequently accessed data (retrieval takes minutes to hours)Object retrieval (async restore)Regulatory archives, cold backup copies, medical records

When to use each service

Amazon S3#

S3 is AWS’s object storage. You store complete files (images, videos, PDFs, logs, code archives) and retrieve them over HTTP. Every object has a unique key inside a bucket. There are no folders, no file locks, and no partial updates.

Use it when: storing user uploads, serving static website assets, creating a data lake for analytics, or keeping application backups. See the Amazon S3 overview for a full breakdown of how it works.

Do not use it when: you need low-latency block I/O, the ability to update part of a file in place, or database queries on structured data.

Example workload: A web app where users upload profile photos. The app stores each photo in S3 and serves it via CloudFront. S3 handles any volume of uploads without provisioning storage in advance.


Amazon EBS#

EBS (Elastic Block Store) is a virtual hard drive attached to an EC2 instance. The OS mounts it like a physical disk. Databases, application binaries, and OS volumes all sit on EBS.

Use it when: running an EC2 instance (every instance needs a root EBS volume), or self-managing a database like PostgreSQL or MySQL on EC2. See EBS volumes explained for volume types, IOPS provisioning, and snapshots.

Do not use it when: multiple EC2 instances need simultaneous access to the same files. Standard EBS volumes attach to one instance at a time. EBS Multi-Attach is available on io1 and io2 volumes for specific clustered workloads, but it is not a general-purpose shared filesystem solution; use EFS for that.

Example workload: A PostgreSQL database running directly on an EC2 instance. The database files live on an EBS volume that provides consistent, low-latency I/O.


Amazon EFS#

EFS (Elastic File System) is a managed NFS filesystem. Multiple EC2 instances can mount and use it simultaneously, making it the right choice when shared file access is the core requirement.

Use it when: several EC2 instances need to read and write the same files, such as a shared media library for a CMS or a shared configuration directory for a multi-server application.

Do not use it when: only one instance needs the storage. EBS is simpler and cheaper for single-instance workloads. See S3 vs EFS for a direct comparison of when to choose each.

Example workload: A WordPress deployment spread across three EC2 instances behind a load balancer. All three mount the same EFS volume so uploaded media is consistent across every server without custom sync logic.


Amazon RDS#

RDS is a managed relational database service. AWS handles provisioning, patching, backups, and Multi-AZ failover. You get a standard MySQL, PostgreSQL, SQL Server, or Oracle database without managing the OS or storage yourself.

Use it when: your application needs SQL queries, foreign keys, JOINs, transactions, or a well-understood relational data model. For a full introduction see Amazon RDS overview, or jump to running MySQL on RDS or PostgreSQL on RDS.

Do not use it when: you need to scale writes beyond what a single database server can handle, or your access patterns are purely key-based without relational queries.

Example workload: A transactional e-commerce backend. Orders, products, customers, and inventory live in a PostgreSQL schema with foreign keys and multi-table transactions.


Amazon Aurora#

Aurora is AWS’s own relational database engine, protocol-compatible with MySQL and PostgreSQL. It uses a distributed storage layer that maintains six copies of data across three Availability Zones automatically.

Use it when: your production workload needs faster failover than standard RDS (under 30 seconds compared to 60-120 seconds), more than 5 read replicas, storage that auto-scales up to 128TB without manual intervention, or Aurora Global Database for read scaling across regions and disaster recovery.

Do not use it when: you are running a development or staging environment with low traffic. Aurora costs 20-40% more than equivalent standard RDS instances, and the availability benefits do not justify the price at small scale. See RDS vs Aurora for a detailed cost and capability comparison.

Example workload: A SaaS application with thousands of concurrent users and a strict uptime SLA. Aurora ensures failover completes in under 30 seconds and read replicas distribute query load across multiple AZs.

Aurora Global Database

Aurora Global Database replicates data to up to five secondary regions, with sub-second replication lag. Secondary regions serve read-only traffic. In a disaster recovery scenario, a secondary region can be promoted to primary. This makes it well-suited for global read scaling and cross-region disaster recovery, not active-active writes across regions.


Amazon DynamoDB#

DynamoDB is AWS’s managed NoSQL database. It stores items as key-value or document structures and scales horizontally to any throughput level. There is no SQL, no joins, and no schema enforcement beyond the primary key.

Use it when: you know your access patterns upfront (lookup by user ID, order ID, session token), you need write throughput beyond a single relational database, or your schema changes frequently without migration overhead. See DynamoDB overview for how tables, keys, and throughput modes work.

Do not use it when: you need complex SQL queries, ad hoc reporting, or a highly relational data model with many foreign keys.

The DynamoDB trap

DynamoDB forces you to define your query patterns upfront. Teams that choose it early because “it scales” often discover later that their reporting, filtering, or relationship requirements cannot be served by key-based lookups alone. If your query requirements are still evolving, start with RDS. Migrating from RDS to DynamoDB is always easier than the reverse. See RDS vs DynamoDB for a head-to-head comparison.

Example workload: A gaming application that stores player scores and retrieves leaderboards by game ID. Each lookup is a primary key query; throughput scales automatically with the player count.


Amazon ElastiCache#

ElastiCache is a managed in-memory cache. It supports two engines: Redis (richer data structures, optional persistence, pub/sub) and Memcached (simpler, multi-threaded). Reads happen in microseconds, not milliseconds.

Use it when: reducing repetitive database queries, storing session tokens, maintaining rate-limit counters, or building a pub/sub messaging layer.

Do not use it when: you need durable primary storage.

ElastiCache is not a database

ElastiCache holds data in memory. If a node is replaced and you have not configured Redis persistence and replication, that data is gone. Never use it as the sole store for anything you cannot afford to lose. It belongs in front of a durable store like RDS or DynamoDB, not instead of one.

Example workload: An API server that fetches the same product catalogue for hundreds of requests per second. ElastiCache stores the database query result in memory and serves it for a configurable TTL, eliminating repeated database load.


S3 Glacier and S3 Glacier Deep Archive#

S3 Glacier tiers live inside S3 but are designed for data you almost never need. Retrieval takes minutes to hours depending on the tier. The trade-off: storage costs as low as $0.00099 per GB/month for Deep Archive.

Use it when: archiving compliance records, old audit logs, cold backup copies, or any data where regulatory requirements demand retention but retrieval will be rare. Use S3 lifecycle policies to move objects to Glacier tiers automatically as they age, and S3 storage classes to understand when each tier makes financial sense.

Do not use it when: you need fast retrieval. Restore times range from minutes (Expedited) to up to 12 hours (Bulk retrieval in Deep Archive).

Example workload: A fintech company must retain transaction logs for seven years under financial regulations. Active logs stay in S3 Standard for 90 days, then a lifecycle rule moves them to S3 Glacier Deep Archive for long-term retention at minimal cost.

How it works: the storage model behind each service

AWS storage services fall into six categories. Understanding the category helps you choose the right service quickly.

The one-sentence version of each category

Object storage: a post room — you send and receive whole parcels by address label. Block storage: a local hard drive — your OS controls it completely. Shared filesystem: a network drive the whole team mounts. Relational database: a searchable, indexed records room with cross-references. NoSQL database: a lookup directory where you find records only by ID. Cache: a whiteboard of recent answers so you stop re-reading the files. Archive: the basement storage room you visit once a decade.

Object storage (S3, S3 Glacier): Data is stored as discrete objects identified by a key. You read or write whole objects at once. There is no filesystem, no file locking, and no in-place editing. Suitable for large volumes of unstructured data: files, backups, media, data lakes.

Block storage (EBS): The OS sees a raw disk device and manages the filesystem itself. Reads and writes happen at the block level, enabling the low-latency random I/O that databases and operating systems require. The disk attaches directly to a compute instance.

Shared file storage (EFS): A network filesystem (NFS) that multiple instances mount simultaneously. It provides standard filesystem semantics (directories, permissions, file locking) and scales storage automatically without pre-provisioning.

Relational databases (RDS, Aurora): A fully managed SQL database engine. Data is structured into tables with rows and columns, related by foreign keys. Supports ACID transactions, complex queries, and JOINs. AWS manages patching, backups, and infrastructure.

NoSQL databases (DynamoDB): Data is stored as items in a table, each identified by a primary key. No schema enforcement beyond the key, no SQL, no joins. Designed for predictable, high-throughput access at any scale.

In-memory cache (ElastiCache): Data lives in RAM for sub-millisecond reads. It sits in front of a slower, durable data store rather than replacing one. Data persistence is optional and requires explicit configuration.

Archive storage (S3 Glacier): An object storage tier optimised for rarely accessed data. Very low storage cost in exchange for slow, sometimes asynchronous retrieval.

Real-world use cases

User-uploaded images, PDFs, videos Store in S3. Return a pre-signed URL or CloudFront URL to the client. Do not proxy large files through your application server.

Static website or frontend assets (HTML, CSS, JS) S3 with CloudFront in front. S3 hosts the files; CloudFront caches them globally and terminates HTTPS. This costs very little at moderate traffic.

EC2 boot volume EBS (General Purpose SSD, gp3 by default). Every EC2 instance requires an EBS root volume. Choose gp3 for most workloads; io2 when databases need high, consistent IOPS.

Database running directly on EC2 EBS. Self-managed PostgreSQL or MySQL on EC2 stores data files on an EBS volume. If you do not want to manage the database yourself, use RDS instead.

Shared media files across multiple EC2 instances EFS. A content management system spread across multiple EC2 instances behind a load balancer needs a single shared location for user-uploaded content. EFS provides this without custom synchronisation logic.

Transactional web application database RDS (PostgreSQL or MySQL). Orders, accounts, and inventory benefit from SQL, transactions, and foreign keys. Enable Multi-AZ for production. RDS handles patching, backups, and failover.

High-throughput session storage, shopping cart, or leaderboard ElastiCache (Redis) for pure speed, or DynamoDB if you need the data to survive a cache flush. ElastiCache is faster but is not a durable store by default; DynamoDB is durable but slightly slower than in-memory.

Analytics and data lake workloads S3 as the storage layer, queried by Athena, Glue, EMR, or Redshift Spectrum. Store data in Parquet or ORC format for efficient columnar queries. See data warehouses vs data lakes for how to structure the broader architecture.

Long-term compliance archive S3 Glacier Deep Archive with Object Lock (WORM mode). Set a lifecycle policy to transition objects automatically. At $0.00099 per GB/month, this is the cheapest storage in AWS.

Key comparisons

S3 vs EBS vs EFS#

DimensionS3EBSEFS
Access methodHTTP API (GET/PUT)Block device (mounted by OS)NFS (mounted by OS)
Shared across instances?Yes (HTTP from anywhere)No by default (Multi-Attach on io1/io2 only)Yes (NFS mount)
Filesystem semantics?NoYes (formatted by OS)Yes (POSIX)
LatencyMilliseconds (HTTP)Sub-millisecond (local block)Low milliseconds (NFS)
Cost modelPer GB stored + requestsPer GB provisionedPer GB used (no pre-provisioning)
Best forFiles, backups, media, data lakesOS volumes, databases on EC2Shared content across instances

For a deeper breakdown, see S3 vs EFS compared.

RDS vs Aurora vs DynamoDB#

DimensionRDSAuroraDynamoDB
Query languageSQLSQL (MySQL/PostgreSQL protocol)DynamoDB API (no SQL)
Data modelRelational (tables, rows, keys)Relational (tables, rows, keys)Key-value / document
Joins and complex queries?YesYesNo
Write scalingSingle primary (scale up)Single primary (larger max instance than RDS)Horizontal (any throughput)
Failover time60-120 secondsUnder 30 secondsManaged (multi-AZ by default)
Relative costBaseline20-40% more than equivalent RDSPay per request or provisioned capacity
Best forStandard relational workloadsHigh-availability relational workloadsHigh-throughput key-based access

For a full comparison, see RDS vs DynamoDB and RDS vs Aurora.

DynamoDB vs ElastiCache for sessions and caching#

Both can store session tokens and shopping cart data. The difference is durability versus speed.

DynamoDB persists data to disk. If your application restarts or a cache layer is cleared, session data survives. TTL is supported natively, so expired sessions delete themselves. Reads take single-digit milliseconds.

ElastiCache (Redis) keeps data in memory. Reads are sub-millisecond. Data can be lost if a node is replaced and persistence is not configured. Redis supports optional persistence and replication, but it is primarily a cache layer, not a durable database.

Use ElastiCache when speed is the priority and session loss on node failure is acceptable. Use DynamoDB when you need durable session storage and can tolerate slightly higher latency.

Common mistakes

  1. Using S3 like a database. Some teams store records as individual JSON files in S3 and fetch and parse them in the application. This works at very small scale but has no query support, no atomicity, and breaks under concurrent writes. Use a real database for structured data that changes.
  2. Defaulting to RDS for everything because SQL is familiar. RDS is wrong for IoT telemetry, high-throughput gaming data, or key-value session storage. Forcing relational thinking onto problems that naturally fit DynamoDB or ElastiCache creates unnecessary schema complexity and query overhead.
  3. Defaulting to DynamoDB for everything because it scales. DynamoDB is difficult to query flexibly. If your query requirements grow beyond primary-key lookups, you will end up maintaining secondary indexes and denormalised data copies for queries that would be trivial in SQL. Understand your queries before committing to it.
  4. Confusing EFS with EBS. EBS is a local disk attached to one instance. EFS is a shared network filesystem mounted by many instances. They solve different problems. Using EBS when you need shared access forces you to build your own sync logic or copy files between servers.
  5. Treating ElastiCache as a primary database. ElastiCache is a cache in front of a database, not a replacement for one. If you rely on it as the only copy of important data without a backing store, you will lose data when a node fails. Use it alongside RDS or DynamoDB, not instead of them.
  6. Paying for Aurora when standard RDS is enough. Aurora’s benefits (fast failover, six-way replication, many read replicas) are most valuable in high-traffic production environments. For development databases, low-traffic staging environments, or small internal tools, standard RDS is cheaper and just as capable.
  7. Ignoring S3 storage class costs. Leaving rarely accessed data in S3 Standard wastes money. S3 Intelligent-Tiering and lifecycle policies to Glacier tiers can cut storage costs significantly for data with declining access patterns. See S3 cost optimisation for practical guidance.

Frequently asked questions

Which AWS storage service should I use for a web app?

Most web apps use at least two: RDS (or Aurora) for the relational database, and S3 for file uploads, static assets, and backups. If your app handles high-traffic sessions or caching, add ElastiCache. If you need key-value lookups at very high throughput without SQL, DynamoDB is worth evaluating.

What is the difference between S3, EBS, and EFS?

S3 is object storage accessed over HTTP: great for files, backups, and data lakes, but not mountable as a drive. EBS is block storage attached directly to an EC2 instance (with Multi-Attach available on io1/io2 volumes for specific clustered workloads): it behaves like a hard drive and is used for OS volumes and databases on EC2. EFS is a shared NFS filesystem that multiple EC2 instances can mount simultaneously, ideal when several servers need to read and write the same files.

When should I use DynamoDB instead of RDS?

Use DynamoDB when your access patterns are key-based and well-defined, you need to scale writes beyond a single database server, or your schema changes frequently. Use RDS when you need SQL queries, complex joins, transactions across many rows, or a relational data model. DynamoDB is not a drop-in replacement for a relational database.

Is Aurora worth the extra cost over standard RDS?

For most small-to-medium web applications on a single region, standard RDS MySQL or PostgreSQL is sufficient and cheaper. Aurora is worth the extra cost when you need sub-30-second failover, more than 5 read replicas, storage that auto-scales past 64TB, or Aurora Global Database for global read distribution and disaster recovery across regions.

Can I use S3 as a database?

Not in the traditional sense. S3 stores whole objects and has no concept of queries, transactions, or partial updates. You can query data stored in S3 using Amazon Athena (which runs SQL against S3 files), but for live transactional data your application reads and writes frequently, use RDS or DynamoDB instead.

Last verified: 5 April 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.