AWS Builder Center
ElastiCache for Valkey Just Became a Durable Data Store. Here's What That Actually Means (Part 1: Architecture & Trade-offs)

ElastiCache for Valkey Just Became a Durable Data Store. Here's What That Actually Means (Part 1: Architecture & Trade-offs)

This is Part 1 of a two-part series. This post covers the internal architecture of Durability, its consistency semantics, constraints, operational design, cost, multi-Region patterns, and how it changes the way you connect Valkey to Aurora. Part 2 covers hands-on benchmarking and fault injection testing.

Series: ElastiCache for Valkey Just Became a Durable Data Store (2 articles)

  1. 1
    ElastiCache for Valkey Just Became a Durable Data Store. Here's What That Actually Means (Part 1: Architecture & Trade-offs) This article
Project Manager/General Manager

Introduction

While studying for an AWS certification exam, I picked up an assumption that I carried with me for years whenever I used ElastiCache: cache data is disposable. If a failover happened, whatever hadn't been replicated yet was gone. If the cluster restarted, everything was gone, and you had to warm the cache back up. So the rule I internalized was simple: anything you write to ElastiCache that you can't afford to lose, write to RDS or Aurora first.
That's more or less why the cache-aside pattern became the default. It exists to work around a cache that can't be trusted to keep your data.
That assumption stopped being universally true in June 2026. AWS announced "Durability for Amazon ElastiCache for Valkey," and ElastiCache can now be used as a durable data store.
As a headline, "ElastiCache is now durable" is where most coverage stops. But once you're actually deciding whether to adopt this, you want to know what's happening under the hood and where the edges of the guarantee are. So I read through the official documentation and pulled together what I found. This post digs into:
  • The internal architecture of the Multi-AZ transactional log (how durability and replication end up being the same mechanism)
  • Consistency semantics (does the primary's strong consistency survive a failover, and what do reads from a replica actually guarantee)
  • How to read AWS's own published benchmark numbers (why async is faster than no-durability at all, and why sync reads degrade under high load)
  • Constraints and operational design (DurabilityLag, backpressure, the write throughput ceiling, why this doesn't play well with PrivateLink, and what it means for your application code)
  • ElastiCache vs. MemoryDB and the Global Datastore trade-off (durability and Global Datastore can't be combined)
Hands-on benchmarking with memtier_benchmark and fault injection testing with FIS are in Part 2.
I'm assuming familiarity with basic ElastiCache/Valkey operations, replication and failover in general, and the concepts of eventual and strong consistency.

The old architecture, and what made it painful

The standard way to use ElastiCache was the cache-aside pattern.
This pattern created a few recurring pain points.
1. Data loss on failover
ElastiCache's replication was an asynchronous stream from primary to replica. If the primary node went down, any write that hadn't yet reached a replica was gone. You could get an ACK for a write and still lose it.
2. Total data loss on restart
A restart after maintenance or a failure wiped the cache clean, which could send a flood of requests straight to the database, a classic cache stampede. You either needed a separate warm-up mechanism or a database that could absorb that load.
3. Running two stores for one dataset
You had to maintain ElastiCache for fast reads and RDS for durability, at the same time, forever. Both the cost and the design complexity doubled.
If you needed to solve these problems, the answer used to be MemoryDB (more on that later).

The internal architecture of Durability

Two durability modes

Synchronous writes (Sync)
Before returning an ACK to the client, the write is persisted to a Multi-AZ transactional log spanning two or more AZs. An acknowledged write survives failures. Write latency stays in single-digit milliseconds, and reads stay at microseconds. This mode adds an 18% surcharge on top of the node's hourly rate (more on cost later).
Asynchronous writes (Async)
The write is persisted to the transactional log in the background, after the ACK is returned. Up to 10 seconds of acknowledged writes can be lost in a failure. Both writes and reads stay at microseconds, and there's no additional cost.

The transactional log isn't a "persistence device." It's a replication path

This is the most interesting part of the whole feature, in my opinion. The Multi-AZ transactional log isn't just a place to park a WAL (write-ahead log). It has effectively become the data distribution path inside the cluster.
Here's what the official docs and blog posts describe about how this works:
  • A replica doesn't stream directly from the primary. It receives writes that were committed to the transactional log, in the same order they executed on the primary, and applies them
  • During a failover, a replica catches up on the log before being promoted. A new primary only starts accepting writes after it has caught up on committed data. In Sync mode, this is exactly the mechanism that produces zero data loss
  • Recovering a failed node doesn't put load on the primary. A replacement replica is restored independently from the log (plus a snapshot). The old problem of replica resync eating the primary's CPU and bandwidth is gone by construction
  • The system survives every node in a shard dying at once. Every node gets replaced, all of them sync from the log, and once committed data is restored, one node is automatically elected the new primary. In Sync mode, this scenario also produces zero data loss
In other words, the old topology of asynchronous primary-to-replica replication gets replaced, once durability is enabled, with primary-to-log-to-replica. That's the same architecture MemoryDB has used from the start (persistence and replication both routed through a Multi-AZ transactional log), so it seems fair to read this as a proven MemoryDB architecture being brought over to ElastiCache. (AWS hasn't stated that the implementations are identical.)

Consistency semantics

The official Consistency page lays this out clearly, and it's the part worth getting exactly right.
Sync mode
  • Reads and writes on the primary are strongly consistent. Every acknowledged write is guaranteed to be reflected in subsequent reads from the primary
  • That strong consistency survives a failover, because a new primary only gets promoted after catching up on committed data in the log
  • Reads from a replica (via READONLY) are eventually consistent. The most recent write might not be visible yet, and the lag is observable through CloudWatch metrics
  • Reads from a single replica are sequentially consistent, though. Writes are applied in the same order they executed on the primary, so you'll never see a newer value and then a stale one on the same replica
Async mode
  • Consistency during normal operation is identical to Sync
  • Strong consistency breaks across a failover. Up to 10 seconds of acknowledged writes can be lost, so reads on the new primary might not reflect writes that were already acknowledged
  • Async isn't recommended for workloads that need strong consistency guarantees, which AWS states explicitly
The asymmetry is worth internalizing: Async carries no penalty during normal operation, and only degrades its consistency guarantee during a failure. That's a useful axis for deciding which workloads belong on which mode.

How to read AWS's own benchmark numbers

The AWS Database Blog published measurements on r7g.4xlarge at an 80:20 read:write ratio.
50K TPS
ModeWrite P50/P90Read P50/P90
No durability147us / 185us260us / 301us
Async112us / 152us245us / 289us
Sync2.15ms / 2.36ms245us / 288us
100K TPS
ModeWrite P50/P90Read P50/P90
No durability160us / 196us263us / 301us
Async128us / 158us245us / 286us
Sync2.72ms / 3.12ms879us / 992us
Look closely at this table and two things stand out.
1. Async writes are faster than no durability at all
Write P50 goes from 147us to 112us at 50K TPS, and from 160us to 128us at 100K TPS. Enabling durability makes writes faster. That runs against intuition, since adding a sync step should slow things down, but I think it can be explained by the architecture change described above. With durability enabled, replication to replicas happens through the transactional log, which frees the primary from the job of pushing a replication stream to replicas itself. That's my hypothesis for why command processing gets lighter. It could be within measurement noise, but the fact that the reversal holds consistently across both TPS tiers suggests it isn't just chance.
2. Sync reads degrade under high load, too
The claim that "reads stay at microseconds" is technically true, but at 100K TPS, Sync's read P50 is 879us, about 3.5x the other modes. It's still measured in microseconds, but in practice that's close to 1ms. If you're targeting high throughput with Sync, you need to budget not just for the 2-3ms write, but for the read tail latency too. The 2-3ms write figure for Sync itself looks reasonable once you account for cross-AZ round-trip time plus the log's quorum write.

Configuration and constraints (you can't enable this after the fact)

This is the point people most often get wrong, and the official docs are unambiguous about it. Whether durability is on or off can only be decided when the cluster is created.
  • You cannot retrofit durability onto an existing non-durable cluster
  • Once enabled, you cannot disable it
  • The only thing you can change later is switching between sync and async (ModifyReplicationGroup)
This asymmetry matters for how you design a new cluster. If you decide you want durability after the cluster is already running, your only option is to build a new cluster and cut over the endpoint. But if you enable Async up front, there's no extra charge (as covered below, Async's node price is the same as no-durability), and you can move to Sync later in about 50 seconds with no downtime. If your design can absorb the constraints (CME, TLS, a supported instance family), my personal recommendation is to default new clusters to Async enabled. Free only refers to price, though; you still have to build a cluster-aware client and reject-time retry logic, and CMD, Serverless, or unsupported families are simply out of scope.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# specify durability at creation time (this is the only point where it can be enabled)
aws elasticache create-replication-group \
--replication-group-id my-durable-cluster \
--engine valkey \
--engine-version 9.1 \
--cache-node-type cache.r7g.large \
--num-node-groups 1 \
--replicas-per-node-group 1 \
--multi-az-enabled \
--automatic-failover-enabled \
--transit-encryption-enabled \
--durability sync

# switch between sync and async (durable clusters only)
aws elasticache modify-replication-group \
--replication-group-id my-durable-cluster \
--durability async \
--apply-immediately
--durability accepts sync, async, disabled, or default (default is resolved by ElastiCache from the engine version and configuration, and currently resolves to disabled). You can check which mode is actually in effect through the EffectiveDurability property in the API response. Snapshots store EffectiveDurability, and restoring from a snapshot carries the durability setting forward.
Enabling durability automatically turns on encryption at rest (a service-managed KMS key or your own CMK, visible in the StorageEncryptionType field). Encryption in transit (TLS) must be enabled at creation. That means a durable cluster is always a TLS connection.
Constraints at a glance
ItemConstraint
EngineValkey 9.0 or later (9.1 added in late June 2026; durability supports 9.0+, so it works on 9.1 too)
Instance familiesR7g, R6g, M7g, M6g, C7gn only
Cluster modeCluster Mode Enabled (CME) required. CMD (Cluster Mode Disabled) isn't supported
TopologyMulti-AZ required, at least one replica per shard required
EncryptionEncryption at rest is enabled automatically; TLS must be enabled at creation
Write throughputUp to 100 MiBps per primary
Not supportedElastiCache Serverless, Global Datastore, Outposts, Local Zones, data tiering
MigrationOnline migration from self-hosted Valkey/Redis OSS isn't supported
With search indexesWrites to indexed keys can be throttled (more below)
The CME requirement matters more than it looks. If your application is used to the simplicity of CMD's single endpoint, you'll need to move to a cluster-aware client (slot awareness, handling MOVED redirects). MULTI/EXEC is also subject to the same single-slot constraint, which means designing hash tags ({...}).
This also spills into network design. You technically can register nodes as NLB IP targets, but a CME-aware client receives each node's real address via CLUSTER SLOTS or MOVED after connecting, and it connects to that address directly. So you can't hide the cluster behind a single VIP and expect it to work. This isn't an ElastiCache-specific limitation; it's a property of the cluster protocol in general, and the consequence is that you can't expose a durable cluster to another account through PrivateLink (which requires an NLB behind it). If you need to share access across accounts within the same Region, use VPC Peering (this lets you reference a security group across accounts). Cross-Region Peering itself works fine, but per AWS's own documentation , this security-group-referencing mechanism specifically does not work across Regions; you have to fall back to CIDR blocks instead. If a PrivateLink boundary is genuinely required by your security posture, don't expose Valkey directly; put an API layer in front of it and publish that instead.
The 100 MiBps per-primary ceiling feeds directly into shard sizing. For a 1 KiB write, the amount written to the log (including key and metadata) works out to roughly 1.1-1.2 KiB per write, which puts the theoretical ceiling for a single shard at somewhere around 80,000-90,000 writes/sec. If your expected write volume exceeds that, shard from the start (increase --num-node-groups). Once you hit the ceiling, the TrafficManagementActive metric flips to 1 and writes get throttled.

Write throttling when search indexes are in play

If you're using search indexes (Valkey 9.0's vector/full-text search) on a durable cluster, writes targeting indexed keys are conditionally throttled. The specifics are interesting.
  • The decision is based on whether the search module's writer-thread CPU utilization, averaged over a rolling 2-hour window, exceeds 50%. Short bursts don't trigger it
  • Throttling means delay, not rejection. Commands never error out; they just get slower
  • If current CPU is at or below 50%, the system won't throttle further even if the 2-hour average is above the threshold, so write capacity never drops below 50% of normal
  • Only write commands touching indexed keys are affected: HSET-family commands, JSON.* commands, DEL/RENAME/COPY/RESTORE. Writes to non-indexed keys and all reads are unaffected
  • You can observe this through SearchWriteThrottleActive, SearchWriteThrottledClientsCount, SearchWriteThrottleEvents, and SearchWriteCPUUtilization
Read this as a mechanism protecting the transactional log's bandwidth from amplified writes caused by index updates. If you're designing for durable clusters with sustained, high-volume ingest and search combined, put SearchWriteCPUUtilization on a dashboard from day one.

Operational design (metrics and backpressure)

Durable clusters get dedicated CloudWatch metrics.
MetricMeaningHow to use it operationally
DurabilityLagAge, in ms, of the oldest write that's acknowledged but not yet durable. Always 0 in SyncThis is Async's effective RPO. As it approaches 10,000ms, writes start getting rejected, so alert around the 5,000ms range
DurabilityBufferExceededErrorCountCount of write commands rejected because the durability buffer exceeded 10 seconds. Always 0 in SyncNonzero means your application's writes are erroring. Watch this alongside your client's retry configuration
TrafficManagementActive1 if throttling is active because the transactional log's throughput ceiling was exceededIf this stays at 1 continuously, that's a signal to shard or change node type
Here's exactly what happens in Async mode. The primary continuously tracks the age of the oldest write that's acknowledged but not yet durable (the durability buffer). Once that age exceeds 10 seconds, the primary rejects all incoming writes until the log catches up on persistence. Reads keep returning at microsecond latency the whole time, and once the log catches up, writes resume automatically. In other words, "up to 10 seconds of loss" isn't a best-effort estimate; it's a hard ceiling enforced by backpressure.
This has two operational implications.
  1. If you're using Async, client-side retries are a hard requirement. Write rejections from a buffer overrun come back as a cluster-down error, and if your application doesn't have automatic retry with exponential backoff configured, a transient log-side congestion event becomes an outright outage (the official docs point to their client best practices post  for exactly this reason)
  2. Async's RPO is observable. "Up to 10 seconds" is a ceiling, not a typical value; DurabilityLag under normal conditions is far lower than that. You can measure your workload's actual effective RPO and use it to decide whether Sync or Async is the right fit

What changes in your application code

Durability is implemented at the infrastructure layer, so no command or API changes at all. What changes is everything around it. Here's a summary of the constraints and operational points above, from the application's point of view.
What it means
Changes (required)Moving off a non-durable cluster requires CME + TLS support (a cluster-aware client, hash tag design; see the constraints table). Async requires exponential backoff retries to handle write rejections on buffer overrun (see above). Sync moves writes from microseconds to 2-3ms, which means redesigning timeouts, connection pooling, and pipelining
You can removeWarm-up/reload logic after a restart or failover. The "write to the RDB first, just in case" ordering constraint (Valkey-first is now viable). With Sync, compensation and reconciliation batches built around the assumption that acknowledged data can vanish
UnchangedA write that errors out is still indeterminate (you don't know if it landed). Retry-on-failure and idempotent design are still required. Reads from a replica (READONLY) are still eventually consistent. You still have to decide whether you can tolerate Async's rollback window (up to 10 seconds) across a failover
Enabling durability doesn't make consistency someone else's problem. All it guarantees is that acknowledged writes don't disappear. How you handle writes that never got acknowledged, and replica consistency, still needs the same design discipline you'd apply to ElastiCache without durability.

ElastiCache vs. MemoryDB: AWS's recommendation has changed

The old rule was: if you're in a single Region and can't tolerate data loss, MemoryDB was the only option. That's no longer true.
AWS's official documentation (as of June 2026) states:
You should consider using MemoryDB if your workload requires multi-Region active-active replication with conflict-free data types (CRDTs). For single-Region durable workloads, consider using ElastiCache with durability enabled.
MemoryDB is now positioned specifically for multi-Region active-active workloads that need CRDTs, and nothing else.
Architecturally, ElastiCache's durability sits in the same design lineage as MemoryDB's Multi-AZ transactional log, as described above. MemoryDB writes always ACK after persisting to the local Multi-AZ transactional log, which is the exact same ACK semantics as ElastiCache's Sync mode. It's fair to say a single-Region MemoryDB equivalent has arrived inside ElastiCache.

Comparison

AspectElastiCache + DurabilityMemoryDB
DurabilitySingle-Region (Multi-AZ)Single/Multi-Region
Multi-Region active-activeNoYes (CRDT)
Write latencyms (Sync) / us (Async)ms
Read latencyusus
Async mode (us writes + 10s RPO)YesNo (always synchronous)
CostTokyo, r7g.large, 2 nodes: Async $307/mo, Sync $362/moTokyo, r7g.large, 2 nodes: $379/mo

Which one should you pick

  • Do you need durability?
    • No → ElastiCache (no durability)
    • Yes → Do you need multi-Region active-active?
      • No → ElastiCache with durability (Sync/Async)
      • Yes → MemoryDB

Cost comparison (Tokyo Region, r7g.large, 1 primary + 1 replica x 730 hours)

Prices pulled from AWS's public pricing API and pricing pages (as of June 2026). Sync Durability adds an 18% surcharge on the node's hourly rate; Async adds nothing.
ConfigurationNode price/hrMonthly (2 nodes)Notes
ElastiCache Valkey (no durability)$0.2104~$307--
ElastiCache Valkey (Async)$0.2104~$307No additional charge
ElastiCache Valkey (Sync)$0.2483 ($0.2104 x 1.18)~$362+18% on node price
MemoryDB Valkey$0.2597~$379--
The gap between Sync Durability's monthly cost (~$362) and MemoryDB's (~$379) is just $17. "ElastiCache is cheaper if all you want is durability" is technically correct, but once you're on Sync it's close to a rounding error. Where ElastiCache is clearly cheaper is Async ($307, no additional cost at all), which means the real price inflection point is the Sync/Async decision, not ElastiCache vs. MemoryDB. The functional inflection point is whether you need multi-Region active-active.

Long-term commitment discounts widen the gap further

Everything above compares on-demand pricing. Look at long-term commitment discounts and the picture shifts. There are two things going on here.
Both services have Reserved Nodes, but only ElastiCache has a Valkey-priced one
Both ElastiCache and MemoryDB offer 1-year and 3-year Reserved Nodes (RIs), with up to 55% off at full upfront payment on either side. But MemoryDB's Reserved Nodes are priced against the Redis OSS engine, as stated explicitly in the official docs, and there's no Valkey-specific Reserved Node offering. You can apply it to Valkey nodes through size-flexible reservations, but the discount is still computed against the Redis OSS on-demand rate ($0.371/hr), not Valkey's on-demand rate ($0.2597/hr).
Here's the effective 3-year-all-upfront rate for r7g.large in Tokyo, pulled from AWS's pricing API:
On-demand3-year all-upfront effective rateDiscount
ElastiCache Valkey$0.2104/hr$0.0947/hr~55%
MemoryDB (Redis OSS-priced)$0.371/hr$0.1669/hr~55%
The discount percentage is the same on both sides, about 55%, but the baseline it's discounted from is pinned to the more expensive engine (Redis OSS) on the MemoryDB side. The on-demand gap was about 23% ($0.2597 vs. $0.2104). At 3-year all-upfront, the effective-rate gap widens to about 76% ($0.1669 vs. $0.0947).
MemoryDB isn't on the Database Savings Plans coverage list, either
Database Savings Plans, announced at re:Invent in December 2025, gives you up to 35% off with a 1-year usage commitment and no upfront payment. ElastiCache for Valkey is explicitly covered: 20% off for provisioned, 30% off for Serverless. AWS's list of covered services (Aurora, RDS, DynamoDB, ElastiCache, DocumentDB, Neptune, Keyspaces, Timestream, DMS, OpenSearch Service) doesn't include MemoryDB. I haven't found an explicit statement excluding it, but it's consistently absent across every list I checked.
So even for the case where you just want a lightweight, 1-year commitment discount, ElastiCache Valkey has a path that MemoryDB doesn't. On either axis, 3-year Reserved Nodes or Database Savings Plans, ElastiCache Valkey's long-term commitment discounts are meaningfully more generous.

Going multi-Region: Global Datastore or MemoryDB

ElastiCache has a multi-Region feature called Global Datastore, and there's an important constraint attached to it. Global Datastore can't be combined with durability (stated explicitly in the official Limitations  page). That means going multi-Region on ElastiCache means giving up durability in favor of Global Datastore, and if you need both durability and multi-Region at the same time, MemoryDB is your only option. Your choices come down to three:
  1. Single-Region + durability -> ElastiCache with durability
  2. Multi-Region (DR/reads) -> ElastiCache Global Datastore (no durability)
  3. Multi-Region + durability -> MemoryDB Multi-Region (active-active)

ElastiCache Global Datastore (active-passive)

  • The write ACK happens after the write completes in the primary Region. Propagation to the secondary is asynchronous
  • Failover on a primary Region failure is manual by default (you can automate it with SNS + Lambda)
  • No additional service charge (you only pay for nodes); supported from Valkey 7.2 onward
  • Meant for DR, read offloading, and geographic optimization. A node-level failure within a Region can still lose data as before, since durability isn't supported here

MemoryDB Multi-Region (active-active)

  • The write ACK happens after persistence to the local Region's Multi-AZ transactional log. Propagation to other Regions is asynchronous (usually under 1 second)
  • Conflicts resolve automatically through CRDTs. Concurrent writes to the same key resolve via last-writer-wins (key-level for strings, field-level for hashes/sets/sorted sets)
  • Local writes keep being accepted even during a Region partition, and they converge via CRDT once connectivity is restored
  • Availability SLA is 99.999%
(Note: Tokyo and Osaka are both AWS Regions inside Japan, commonly paired for in-country disaster recovery. The same pattern applies to any two Regions on either side of a multi-Region setup.)

Comparison summary

ElastiCache Global DatastoreMemoryDB Multi-Region
TopologyActive-PassiveActive-Active
Durability within the local RegionNone (can't combine with durability)Yes (Multi-AZ transactional log)
Write ACKAfter the write in the primary RegionAfter local Multi-AZ persistence
Writes from other RegionsNot allowedAllowed
Conflict resolutionDoesn't happenCRDT + last-writer-wins
FailoverManual by defaultAutomatic
Use caseDR, read offloadingA global app that writes from multiple Regions
If all you want is to go multi-Region, Global Datastore covers most of those cases, but you give up durability within a Region to get it. There's currently no way to build "RPO of zero within a Region, DR across Regions" on ElastiCache alone, and that gap is where MemoryDB still has a clear edge.


Do you still need a relational database?

Short answer: yes. To be clear about terminology, "RDB" in this section means relational database, not Valkey's RDB snapshot file format.
Adding durability to ElastiCache doesn't change Valkey's structural limits.
OperationValkey's limitAlternative service
Joins across tables, complex aggregation, window functionsOnly limited aggregation commandsRDS/Aurora, Redshift/Athena
ACID transactions spanning multiple shardsOnly within a single slot (needs hash tag design)RDS/Aurora
Schema management, foreign key constraintsNoneRDS
Cheap, large-scale persistenceAssumes the whole dataset fits in memory (data tiering can't be combined with durability)RDS/S3
Large-scale full-text search, graphs, long-term time-series analysis9.0 has search, but it doesn't scale to thisOpenSearch / Neptune / Timestream
Regulatory audit loggingLimited feature setAurora + CloudTrail
The old two-tier picture, ElastiCache as the cache and the RDB as the persistent store, shifts. ElastiCache now also handles the fast, persistent tier, while the RDB is reserved for complex queries and large-scale data. The RDB doesn't become unnecessary; its job changes.

Pairing Valkey with Aurora: which pattern to use

Durability makes "write to Valkey first, then flow it to Aurora" a realistic option. Previously, you had to write to Aurora first because you couldn't trust Valkey's data to stick around. There are four common patterns, and I'll frame the choice as a decision table.
PatternWrite pathReal-time-nessConsistencyGood fit
1. Write-ThroughApp writes to both Valkey and AuroraImmediateStrong (hard to guarantee)Operations that need an audit trail
2. Valkey First (outbox)App -> Valkey -> Aurora asyncFastestEventualSessions, scores, IoT
3. Aurora First + CDCApp -> Aurora -> reflected into ValkeySub-secondStrongProduct/price master data
4. CQRSWrites to Aurora, reads from ValkeySub-secondReads are eventualLarge-scale e-commerce, dashboards
Patterns 1, 3, and 4 have existed all along. What durability changes for them is stability: the Valkey-side view no longer vanishes on a failure, so you can drop the warm-up design entirely. In pattern 3, Valkey's data stays intact even if CDC delivery pauses. In pattern 4, continued reads from Valkey during an Aurora outage are now guaranteed within the range of already-replicated data. In pattern 1, you still need compensation logic for a Valkey success followed by an Aurora failure (and since this is CME, MULTI/EXEC still needs hash tags to keep everything in one slot).


Summary

Picking by use case

Use caseChoice
Cache only (RDB is the source of truth)ElastiCache (no durability)
Cache, but I want data to survive a restartElastiCache Async Durability
Sessions, real-time balances, payment tokens (can't lose data, needs strong consistency)ElastiCache Sync Durability
DR setup, offload reads to a secondary Region (no need for durability within a Region)ElastiCache Global Datastore
Multi-Region active-active, or durability within a Region combined with multi-RegionMemoryDB Multi-Region
Complex queries, aggregation, OLAPRDS/Aurora/Redshift, alongside ElastiCache

What this post covered

  • Internal architecture: the Multi-AZ transactional log does double duty as both persistence and replication, and that's exactly why Sync's "an acknowledged write never disappears" guarantee holds, with the primary's strong consistency preserved across a failover (a replica is eventually consistent, plus sequentially consistent). Async trades that guarantee for lower latency, at the cost of up to a 10-second rollback window on failure
  • Constraints: durability can only be enabled at creation (no retrofitting, no disabling, only sync/async is switchable later). The service requires CME, Multi-AZ plus a replica, TLS, and a supported instance family. It can't be combined with Global Datastore, Serverless, or data tiering, and the CME requirement means you can't share it through PrivateLink either
  • Application impact: commands don't change, but CME forces your client to become cluster-aware (hash tags for multi-key operations), Async needs retry logic for its write rejections, and Sync needs a reworked latency budget. DurabilityLag is your effective RPO to watch, with backpressure kicking in at 10 seconds
  • Cost: on Tokyo r7g.large with 2 nodes, that's Async at $307/mo (no surcharge), Sync at $362/mo (+18%), and MemoryDB Valkey at $379/mo, and ElastiCache's edge grows the longer your commitment (3-year Reserved Nodes or Database Savings Plans)
Part 2 puts these claims to the test.

Series: ElastiCache for Valkey Just Became a Durable Data Store (2 articles)

  1. 1
    ElastiCache for Valkey Just Became a Durable Data Store. Here's What That Actually Means (Part 1: Architecture & Trade-offs) This article
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article