Amazon ElastiCache
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.
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 — 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.
- 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.
- 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.
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