# ElastiCache

## 1. What It Is

**Amazon ElastiCache** runs managed in-memory data stores: **Valkey** (the open-source Redis fork, now AWS's default), **Redis OSS**, and **Memcached** (`databases/caching/01-redis`, `02-memcached`, `03-redis_vs_memcached`). AWS handles provisioning, patching, replication, failover, backups and monitoring. **MemoryDB** is the related service when you need Redis-compatible storage as a *durable primary database* (multi-AZ transaction log).

Typical uses: caching DB query results and rendered fragments (`databases/caching/04-…` to `08-…`), sessions, rate limiting counters, leaderboards (sorted sets), pub/sub, distributed locks (with care), queues for small jobs.

## 2. Deployment Options

| Option | Shape | Notes |
|---|---|---|
| **Serverless** | no nodes to size; scales memory and throughput automatically | pay per GB-hour stored + ECPUs; quickest start, spiky workloads |
| **Node-based, cluster mode disabled** | 1 primary + up to 5 replicas, one shard | simplest; vertical scaling; all keys on one primary |
| **Node-based, cluster mode enabled** | up to 500 shards, each primary + replicas; keys distributed by hash slot | horizontal scaling of memory and writes (`databases/caching/08-distributed_caching`) |
| **Memcached** | multiple independent nodes, client-side sharding | no replication/persistence; multithreaded; pure cache |

Production Redis/Valkey: **Multi-AZ with automatic failover**, at least one replica in another AZ, **encryption in transit (TLS) and at rest**, **AUTH / RBAC users** (IAM authentication supported), placed in **private subnets** with a security group allowing only app security groups on port 6379.

## 3. Endpoints

- **Primary endpoint** (cluster mode disabled): always points at the current primary — use for writes; DNS flips on failover.
- **Reader endpoint**: load-balances across replicas — use for read scaling (replication is asynchronous; reads may be slightly stale).
- **Configuration endpoint** (cluster mode enabled): cluster-aware clients discover the slot map and talk to the right shard (`MOVED`/`ASK` redirects).

Clients must handle failover: reconnect with backoff, short connect timeouts, and (for cluster mode) refresh topology.

## 4. Sizing and Eviction

- Size memory for the **working set + overhead** (~25% for fragmentation/replication buffers; keep `DatabaseMemoryUsagePercentage` under ~75–80%).
- Set `maxmemory-policy` in the parameter group: `allkeys-lru` (or `allkeys-lfu`) for caches; `volatile-*` or `noeviction` when Redis holds data that must not silently disappear.
- **Reserved memory** for background saves/replication (`reserved-memory-percent`).
- Graviton node types (`cache.r7g`, `cache.m7g`) for price/performance; data tiering (`r6gd`) moves cold data to SSD for large datasets.

## 5. Key Metrics to Watch

| Metric | Why |
|---|---|
| `CPUUtilization` / `EngineCPUUtilization` | Redis executes commands on one main thread — engine CPU > ~80% means saturation |
| `DatabaseMemoryUsagePercentage`, `Evictions` | evictions with a low hit ratio = undersized cache |
| `CacheHitRate` (hits / (hits+misses)) | cache effectiveness |
| `CurrConnections`, `NewConnections` | connection storms (Lambda!) |
| `ReplicationLag` | stale reads from replicas |
| `NetworkBandwidthOutAllowanceExceeded` | instance network limits (hot keys, big values) |

## 6. Patterns and Pitfalls on AWS

- **Lambda + Redis**: many concurrent environments × connections — reuse the client outside the handler, keep connection counts in mind, or use ElastiCache Serverless.
- **Hot keys and big keys**: one shard melts — split values, add local L1 caching, use read replicas.
- **`KEYS *`, big `SMEMBERS`, long Lua scripts** block the single thread → latency spikes for everyone; use `SCAN` and bounded operations.
- **Cache stampede after failover or flush**: jittered TTLs, single-flight, warm-up (`databases/caching/07-ttl`).
- **Global Datastore**: cross-region replication (one primary region, read replicas elsewhere, promotable for DR).

## Under the Hood: What Happens During a Failover

In a Multi-AZ Redis/Valkey replication group, ElastiCache monitors the primary node. When it detects a failure (node or AZ), it **promotes the replica with the least replication lag** to primary, updates the **primary endpoint's DNS record** to point to the new node (typically within ~30–60 s total), and replaces the failed node, which rejoins as a replica. Because replication is **asynchronous**, writes acknowledged by the old primary but not yet streamed to the replica are lost — acceptable for a cache, worth knowing for sessions or counters. Clients holding TCP connections to the old primary get errors or timeouts; well-configured clients reconnect, re-resolve DNS (respect the low TTL), and retry. In cluster mode, each shard fails over independently and clients refresh their slot map when they receive `MOVED` or connection errors.

![Applications in private subnets connect over TLS to an ElastiCache replication group with a primary and replicas across availability zones; writes use the primary endpoint and reads the reader endpoint; on failure the least-lagged replica is promoted and the primary endpoint DNS is repointed](diagrams/01-elasticache-topology.svg)

## Quick Reference

```
Valkey/Redis: serverless or node-based (cluster mode off: 1 shard; on: up to 500 shards) · Memcached: simple cache
prod: Multi-AZ + auto failover, TLS + at-rest encryption, AUTH/RBAC/IAM, private subnets + SG on 6379
endpoints: primary (writes) · reader (replicas) · configuration (cluster mode)
watch: EngineCPU, memory %, evictions, hit rate, connections, replication lag
avoid: KEYS *, huge values, hot keys, unbounded connections from Lambda
