Amazon ElastiCache
Service 19

Amazon ElastiCache

DatabaseIn-MemoryCache

ElastiCache is a managed in-memory cache. You point the application at a cache endpoint, store frequently read data there, and serve those reads in microseconds instead of returning to a slower database for every request. It runs the Valkey, Redis OSS, and Memcached engines.

Common uses: caching query results in front of RDS, Aurora, or DynamoDB; session stores for stateless tiers; leaderboards; rate-limiting counters; pub/sub. Treat it as an optimization, not a system of record.

Engines: Valkey, Redis OSS, and Memcached

Valkey is the open-source fork created after Redis Inc. relicensed Redis in 2024; it is wire-compatible with Redis OSS, supported by ElastiCache, and priced about 20% below Redis OSS at equal sizes. Both offer rich data types (hashes, lists, sorted sets, streams, geo), replication with automatic failover, optional persistence, pub/sub, and scripting.

Memcached fits a narrow case: saturating a single very large node with simple multi-threaded key-value caching. For almost everything else, Valkey or Redis OSS does more — pick by application fit and team preference.

Operating Shapes and Cluster Modes

Serverless gives an endpoint with no nodes to manage — AWS handles capacity, replication, and failover, billed per ECPU and GB-hour so a quiet cache costs little. It is the simplest starting point. Node-based clusters let you pick node type and placement, and win on cost at steady, high throughput with reserved nodes.

Cluster mode disabledone shard
primary
replicareplica
One primary + up to 5 replicas. The dataset must fit one node; scales reads and availability, not writes or size.
Cluster mode enabledsharded
shard 1shard 2shard 3
+ replicas per shard
Keyspace split across up to 500 shards. Scales writes, reads, and dataset size; the client must be cluster-aware.

For Valkey/Redis, cluster mode disabled is one primary plus up to five replicas (the dataset must fit one node; scales reads and availability). Cluster mode enabled shards the keyspace across up to 500 shards, scaling writes, reads, and dataset size, but needs a cluster-aware client.

Caching Patterns, TTL, and Eviction

The default pattern is cache-aside: check the cache, on a miss read the database and write the result back with a TTL. Write-through keeps the cache consistent at the cost of doubling write work; write-behind is fast but risks data loss and is rarely right for a cache.

Set a TTL on every key — a cache without TTLs fills with stale data and becomes a fragile undocumented database. The eviction policy (e.g. allkeys-lru) decides what is dropped when memory is full; noeviction refuses writes and is for cases where silently dropping data is unacceptable.

ElastiCache vs DAX vs MemoryDB

ElastiCache — a general cache for any source, with rich data types and pub/sub. The default for caching RDS/Aurora results or session state.

DAX — caching DynamoDB specifically — speaks the DynamoDB API and removes cache-aside boilerplate.

MemoryDB — a durable in-memory primary database (same wire protocol) when you need a system of record, not a cache.

Common Mistakes
  • Running without TTLs on keys, so the cache slowly fills with stale data and becomes an accidental database.
  • Treating the cache as a system of record — design so the app keeps working (more slowly) when the cache is empty or down.
  • Reaching for Memcached for rich workloads when Valkey/Redis offers replication, data types, and persistence it lacks.
  • Using cluster mode disabled when the dataset exceeds a single node's memory or writes must scale — that needs cluster mode enabled.
  • Caching raw single rows by primary key when caching the finished page or rendered JSON would pay back far more.
  • Ignoring rising Evictions and CacheMisses in CloudWatch, which signal an undersized cache or a bad TTL/pattern.
Best Practices
  • Start with Serverless; move to node-based only with a measured, steady workload and a clear cost reason.
  • Set a TTL on every key, even a long one.
  • Use cache-aside as the default pattern; add complexity only when measurements demand it.
  • Use cluster mode enabled for sharded or write-scaling workloads; disabled otherwise.
  • Cache the result of expensive work, not raw rows.
  • Plan for cache loss — the cache is an optimization, not the source of truth.
Comparable services GCP MemorystoreAzure Azure Cache for Redis

Knowledge Check

What is the cache-aside pattern?

  • The app checks the cache first, and on a miss reads the database and writes the result back with a TTL
  • Every write is sent to both the cache and the database synchronously in the very same call
  • Writes go only to the cache first and are then asynchronously flushed out to the database some time later
  • The database itself pushes every committed change straight into the cache automatically on each write

Why should every ElastiCache key have a TTL?

  • Without TTLs the cache fills with stale data and degrades into a fragile, undocumented database
  • TTLs on every key are required before cross-node replication will work at all
  • Keys stored without any TTL set are billed at double the normal per-key rate
  • Setting a TTL on a key is what makes all subsequent reads strongly consistent across every replica

When is Memcached the better engine choice over Valkey/Redis?

  • When saturating a single very large node with simple multi-threaded key-value caching
  • When you need rich data structures such as sorted sets, pub/sub channels, and on-disk persistence
  • When you need built-in automatic replication across nodes and instant failover on node loss
  • For essentially every general-purpose caching workload you might encounter in practice

A Valkey workload's dataset no longer fits in a single node and writes must scale. Which cluster mode fits?

  • Cluster mode enabled — the keyspace is sharded across many shards
  • Cluster mode disabled — just add more read replicas to grow the single shard
  • Memcached running in plain single-node mode without any sharding at all
  • Neither option works — ElastiCache hard-caps every dataset to a single node

You got correct