← all posts

AWS Database Design Patterns

January 22, 2025
AWS Database Design Patterns

Database selection should begin with the access pattern. The wrong database is often a sign that the workload was described too vaguely.

The most common database mistake in AWS is not picking the wrong service name. It is optimizing for a future query pattern no one can describe yet.

Start with these questions:

  1. Is the schema relational?
  2. Are queries predictable?
  3. Is write scale regional or global?
  4. Is the workload read-heavy?
  5. Does the application need transactions?

If the team cannot answer those questions clearly, the right move is usually to clarify the workload first, not to compare product pages harder.

RDS

RDS is the managed path for familiar relational engines such as MySQL, PostgreSQL, SQL Server, MariaDB, and Oracle.

Use RDS when the application expects a traditional relational database and does not need Aurora-specific scaling or global database features.

RDS read replicas help read scale and reporting, but failover and cross-region write strategy require careful design.

RDS Multi-AZ is high availability, not horizontal read scale. The standby is there for failover, not as a general reader fleet. That distinction matters because teams often describe active-passive designs as if they were active-active.

Aurora

Aurora is AWS's cloud-optimized relational database. It is a strong choice for high availability, fast failover, read scaling, and global database patterns.

Use Aurora when relational semantics matter but you need cloud-native resilience and scale. Aurora Global Database is a common fit for cross-region disaster recovery with low replication lag.

Aurora also has a few operational advantages that change real-world design. Reader autoscaling is cleaner than managing replica fleets yourself, and Aurora cloning is genuinely useful for fast staging environments because it uses copy-on-write rather than a full duplicate immediately.

What Aurora does not magically give you is true multi-region multi-active writes. Global read distribution is easy. Global write semantics are not.

DynamoDB

DynamoDB is managed NoSQL key-value and document storage. It excels when access patterns are known and high scale is required.

Good DynamoDB design starts with partition keys, sort keys, and query patterns. Bad DynamoDB design starts with "we might query anything later."

The two DynamoDB mistakes I see most are:

  1. Treating it like a schemaless SQL database and assuming ad hoc queries can be figured out later.
  2. Ignoring partition design until hot keys become a production incident.

Use Global Tables when you need true multi-region multi-active writes. This is one of the places where DynamoDB is stronger than Aurora: the multi-region write story is much cleaner if the workload fits the model.

DAX And ElastiCache

DAX is a DynamoDB-specific cache. Use it for read-heavy DynamoDB workloads that can benefit from microsecond read latency.

ElastiCache is a general-purpose cache for Redis or Memcached patterns. Use Redis for session stores, leaderboards, distributed locks, pub/sub, and application caches.

Do not put ElastiCache in front of DynamoDB by default. If the target is DynamoDB and the problem is repeated reads, evaluate DAX first.

ElastiCache is what you reach for when the cache serves the application broadly. DAX is what you reach for when the cache exists specifically to remove read pressure from DynamoDB.

RDS Proxy

Serverless and bursty workloads can overwhelm relational databases with too many connections. RDS Proxy pools connections and is especially useful for Lambda plus RDS or Aurora.

This is one of those services that does not change your data model but can change production behavior meaningfully. If your app pattern is "many short-lived functions, one relational backend," RDS Proxy often matters more than another round of query tuning.

Recovery Features Matter Too

Selection is not only about the happy path. Ask how you will recover:

  1. RDS and Aurora rely on snapshots, replicas, and failover topology.
  2. DynamoDB gives you PITR and backup options with a different operational model.
  3. Aurora clones can create near-instant staging copies without the pain of full logical export/import.

The Decision Rule

  1. Need SQL and familiar engines: RDS.
  2. Need cloud-native relational scale, fast failover, or global DR: Aurora.
  3. Need massive predictable key-value access or true multi-region multi-active writes: DynamoDB.
  4. Need DynamoDB read acceleration: DAX.
  5. Need general application caching: ElastiCache.
  6. Need connection pooling for serverless relational workloads: RDS Proxy.

Databases are long-lived decisions. Optimize for access patterns, failure modes, and operational ownership, not just service popularity.

;