RDS + Aurora + ElastiCache

Summary: RDS is AWS’s managed relational database service; Aurora is AWS’s own high-performance, cloud-native database engine compatible with MySQL and Postgres. ElastiCache adds a managed in-memory caching layer (Redis or Memcached) to offload read pressure from your databases.


RDS (Relational Database Service)

RDS is a managed service for SQL-based relational databases. Supported engines: Postgres, MySQL, MariaDB, Oracle, MSSQL, and Aurora.

Advantages over self-managed DB on EC2

  • Automated provisioning and OS patching
  • Continuous backups with point-in-time restore
  • Monitoring dashboards
  • Read replicas for read scaling
  • Multi-AZ setup for disaster recovery
  • Maintenance windows for upgrades
  • Vertical and horizontal scaling
  • Storage backed by EBS
  • No SSH access - RDS runs on EC2 instances under the hood, but AWS owns the OS layer entirely, so you only interact with the database engine via its connection endpoint

Storage Auto Scaling

Storage Auto Scaling automatically increases your RDS instance’s storage when it’s running low, with no manual intervention.

  • Set a Maximum Storage Threshold to cap how far it can scale
  • Triggers automatically when all three conditions are met:
    • Free storage drops below 10% of allocated storage
    • Low-storage state persists for at least 5 continuous minutes (debounce - avoids scaling on a transient spike)
    • 6 hours have passed since the last storage modification
  • Useful for applications with unpredictable workloads

Read Replicas

Read Replicas are async, read-only copies of your primary RDS instance used to scale read-heavy workloads.

  • Up to 15 read replicas
  • Can be within the same AZ, cross-AZ, or cross-region
  • Replication is async - reads are eventually consistent
  • Replicas can be promoted to become standalone databases
  • Applications must update their connection string to use replicas

RDS read replicas

Use case: Run reporting or analytics on a read replica so the production database is unaffected. Read replicas handle SELECT only - no INSERT, UPDATE, or DELETE. This is the classic OLAP (analytical workload) vs OLTP (transactional workload) split.

RDS read replica use case example

Network cost: Cross-AZ data transfer has a cost in AWS, but read replicas within the same region are exempt from that fee.

Multi-AZ (Disaster Recovery)

  • Sync replication to a standby instance in a different AZ
  • One DNS name - automatic failover to standby on failure
  • Covers: AZ loss, network loss, instance failure, storage failure
  • No manual intervention or app code changes needed
  • Not used for scaling - the standby is passive until failover

RDS disaster recovery

Read Replicas vs. Multi-AZ

Read Replicas = async replication, for read scaling. Multi-AZ = sync replication, for disaster recovery only. The standby in Multi-AZ does not serve traffic under normal conditions.

Read Replicas can also be set up as Multi-AZ for combined read scaling + DR.

Single-AZ to Multi-AZ Migration

  • Zero downtime - no need to stop the DB, just click “Modify”
  • Internally: snapshot taken → new DB restored from snapshot in new AZ → synchronization established

RDS Security

  • At-rest encryption via AWS KMS (Key Management Service - stores and manages the encryption keys used to encrypt the underlying EBS volume)
    • Must be enabled at launch time
    • If the master is unencrypted, read replicas cannot be encrypted
    • To encrypt an unencrypted DB: take a snapshot → restore as encrypted
  • In-flight encryption: TLS-ready by default; use AWS TLS root certificates client-side
  • IAM Authentication: connect using IAM roles instead of username/password
  • Security Groups: control network access to the DB
  • No SSH access, except on RDS Custom
  • Audit Logs can be sent to CloudWatch Logs for extended retention

RDS Proxy

RDS Proxy is a fully managed connection pooler that sits between your application and RDS/Aurora.

  • Pools and shares DB connections, reducing CPU/RAM stress and open connection count
  • Serverless, auto-scaling, Multi-AZ
  • Reduces failover time for RDS and Aurora by up to 66%
  • No code changes required for most apps - just point your connection string at the proxy
  • Enforces IAM authentication; stores credentials in AWS Secrets Manager
  • Never publicly accessible - must be accessed from within a VPC

AWS RDS Proxy


Amazon Aurora

Aurora is AWS’s proprietary, cloud-optimized relational database engine compatible with MySQL and Postgres.

  • Claims 5x performance improvement over MySQL on RDS
  • Storage automatically grows in 10 GB increments, up to 128 TB
  • Up to 15 replicas with sub-10 ms replica lag (faster than standard RDS replication)
  • Instantaneous failover - High Availability native
  • Costs ~20% more than standard RDS, but more efficient

High Availability and Read Scaling

  • 6 copies of data across 3 AZs:
    • 4 out of 6 copies needed for writes
    • 3 out of 6 copies needed for reads
    • Self-healing via peer-to-peer replication
    • Storage striped across hundreds of volumes
  • One Aurora instance is the master (handles all writes)
  • Automated master failover in under 30 seconds
  • Master + up to 15 Aurora Read Replicas serve reads
  • Supports Cross Region Replication

Aurora DB Cluster

Aurora DB Cluster

Aurora exposes two endpoints:

  • Writer Endpoint - always points to the master
  • Reader Endpoint - load-balances reads across all read replicas

Backed by a shared storage volume that all instances access.

Aurora Features

  • Automatic failover
  • Backup and recovery
  • Isolation and security
  • Industry compliance
  • Push-button scaling
  • Automated patching with zero downtime
  • Advanced monitoring
  • Routine maintenance
  • Backtrack - restore data to any point in time without using traditional backups

Amazon ElastiCache

ElastiCache is AWS’s fully managed in-memory caching service - a separate AWS service, not a feature of RDS. It is to Redis/Memcached what RDS is to relational databases: you get a managed cache without running Redis or Memcached on EC2 yourself.

  • In-memory databases: very high performance, very low latency
  • Offloads read pressure from relational databases for read-intensive workloads
  • Helps make applications stateless (store session data in the cache rather than on the app instance)
  • AWS manages OS patching, setup, configuration, monitoring, failure recovery, and backups
  • Requires application code changes to integrate

Use Case: DB Cache

Application checks ElastiCache first; on a cache miss, fetches from RDS and stores the result in ElastiCache for future requests.

  • Relieves read load on RDS
  • Cache must have an invalidation strategy to prevent stale data from accumulating

ElastiCache DB Cache example

Use Case: User Session Store

  1. User logs in on any application instance
  2. App writes session data to ElastiCache
  3. User hits a different app instance
  4. That instance retrieves the session from ElastiCache - user is already logged in

ElastiCache user session store

Redis vs. Memcached

FeatureRedisMemcached
Multi-AZ with auto-failoverYesNo
Read replicas / HAYesNo
Data persistence (AOF)YesNo
Backup and restoreYesYes (serverless)
Complex data types (sets, sorted sets)YesNo
Multi-threadedNoYes
Horizontal shardingNoYes

AOF (Append Only File): Redis’s persistence mechanism. Every write command is logged sequentially to a file. On restart, Redis replays the log to rebuild the dataset, surviving crashes without losing data.

Memcached is a simpler, older caching system - pure key-value with no durability, no replication, and no complex data types. Its advantage is a multi-threaded architecture that can be faster for pure caching at high concurrency. If you’ve used Redis, Memcached is the stripped-down version with none of the extras.

Redis vs. Memcached on the exam

Choose Redis when you need persistence, replication, high availability, or complex data types. Choose Memcached for pure ephemeral caching with simple key-value access.

Caching Design Patterns

Before caching, consider:

  • Safe? Data can tolerate being slightly stale
  • Effective? Data changes slowly; a small set of keys are frequently accessed
  • Anti-pattern: Data changes rapidly, or the full key space is accessed uniformly

1. Lazy Loading (Cache-Aside / Lazy Population)

Fetch from cache first. On a miss, load from DB and populate the cache.

Pros:

  • Only requested data is cached
  • Node failures aren’t fatal - just increased latency while cache warms up

Cons:

  • Cache miss = 3 round trips (check cache → hit DB → write to cache) - noticeable delay
  • Stale data: DB can be updated while the cache still holds the old value

ElastiCache DB Cache lazy loading

The exam includes pseudocode for this pattern:

def get_user(user_id):
    record = cache.get(user_id)
    if record is None:
        record = db.query("SELECT * FROM users WHERE id = ?", user_id)
        cache.set(user_id, record)
        return record
    else:
        return record

2. Write-Through

Update the cache every time the DB is written to.

Pros:

  • Cache is never stale
  • Reads are always fast - data is pre-warmed

Cons:

  • Write penalty: each DB write requires 2 operations (write DB + write cache)
  • Cache churn: data gets cached even if it’s never read
  • Missing data: keys that have never been written won’t exist in the cache yet. Mitigation: layer lazy loading on top - on a cache miss, fall back to the DB and populate the cache. Write-through keeps existing data fresh; lazy loading fills in keys that haven’t been explicitly written yet.

cache write-through

def save_user(user_id, values):
    record = db.query("UPDATE users ... WHERE id = ?", user_id, values)
    cache.set(user_id, record)
    return record

3. Cache Evictions and TTL

Cache eviction occurs when:

  • You explicitly delete the item
  • Memory is full and the item was least recently used (LRU eviction)
  • The item’s TTL (Time-to-Live) expires

TTL is useful for any time-sensitive data: leaderboards, comments, activity feeds. Range from seconds to days depending on stale-data tolerance. If evictions are happening too frequently due to memory pressure, scale up (larger node) or scale out (more nodes).

Best practices:

  • Lazy loading is a good foundation for read-side caching
  • Combine write-through with lazy loading for full coverage
  • Always set a sensible TTL, except when using write-through (data is kept fresh on writes)
  • Only cache data that makes sense to cache

Amazon MemoryDB for Redis

MemoryDB is a Redis-compatible, fully durable in-memory database service - as opposed to ElastiCache, which is primarily a cache layer.

ElastiCache for RedisMemoryDB for Redis
Primary roleCache in front of DBPrimary database
DurabilityOptionalFull (Multi-AZ transactional log)
Data loss on failurePossibleNo
  • Up to 160 million requests/second
  • Scales from 10s of GB to 100s of TB
  • Use cases: web/mobile apps, online gaming, media streaming

MemoryDB vs. ElastiCache

ElastiCache is the cache layer in front of your database. MemoryDB is the database itself - fully durable, Redis-compatible, and designed to be your primary store.


Review Questions