Guide · AWS MemoryDB · Database
AWS MemoryDB for MCP Servers
MemoryDB is a durable, Redis-protocol-compatible primary database — not a cache. When your MCP server's probe state, session records, or rate-limiting counters must survive a failover without data loss, MemoryDB is the right primitive. This guide covers the architecture differences from ElastiCache, CDK cluster setup, ACL authentication, and how AliveMCP monitors MemoryDB clusters as part of your MCP server health stack.
MemoryDB vs ElastiCache: the durability distinction
Both MemoryDB and ElastiCache Redis use the Redis protocol and look the same from application code. The difference is the write-path commitment guarantee.
ElastiCache Redis flushes writes to in-memory replicas asynchronously. If the primary fails before replication completes, those writes are lost. The documentation explicitly calls this out: ElastiCache is optimized as a cache and ephemeral state store, not a primary database. For probe result caches or ephemeral session tokens, that's fine.
MemoryDB commits every write to a Multi-AZ transaction log across at least two Availability Zones before acknowledging success to the client. RPO is effectively zero — if the primary fails immediately after an ACK, the successor replica replays the transaction log and has the write. This makes MemoryDB suitable as a primary database for state that must not be lost on failover.
| Dimension | ElastiCache Redis | MemoryDB for Redis |
|---|---|---|
| Write durability | Asynchronous replication — some writes lost on failover | Multi-AZ transaction log — zero data loss (RPO=0) |
| Primary use case | Cache, ephemeral state | Primary database with Redis interface |
| Redis compatibility | Redis 6.x / 7.x subset (some commands not supported) | Redis 6.2 / 7.0 full protocol compliance |
| Cluster topology | Cluster mode optional | Cluster mode always on (1–500 shards) |
| ACL authentication | AUTH token or ACL (Redis 6.x+) | ACL users required (no plain AUTH token) |
| Failover RTO | ~30–60 seconds | ~30–60 seconds (similar RTO, better RPO) |
| Data tiering (SSD) | Not supported | Supported on r6gd nodes |
| Price premium | Baseline | ~20–30% higher for equivalent node type |
| Snapshots | RDB snapshots | RDB snapshots + transaction log backup |
| Cross-region | Global Datastore (replication) | Cross-region snapshots only (no live replication) |
For MCP servers the decision rule is straightforward: if data loss on failover is acceptable (caches, ephemeral rate-limit windows, short-lived sessions), use ElastiCache. If the data is your source of truth — probe state that feeds SLA reports, persistent session tokens, billing-relevant counters — use MemoryDB.
MemoryDB architecture for MCP server backends
MemoryDB always runs in cluster mode. A cluster consists of one or more shards; each shard has one primary node and zero to five replicas. Data is sharded across 16,384 hash slots distributed evenly across your shards. Your Redis client must use cluster-mode-aware connections (standard with ioredis, redis-py cluster mode, or Lettuce).
The cluster discovery endpoint is the address your application connects to. MemoryDB returns CLUSTER SLOTS or CLUSTER SHARDS responses so the client builds an internal slot-to-node map. Individual node endpoints exist but should not be used directly from application code — connecting to a node endpoint bypasses cluster routing and breaks when slots move during a failover or re-shard.
Common MCP server use cases for MemoryDB
- Probe result state store: each probe writes its verdict (
up,degraded,down) to a hash key per MCP endpoint. On failover, the successor node replays the transaction log and the monitoring dashboard reads accurate state immediately — no stale "unknown" period. - Persistent rate-limiting counters: INCR-based sliding window counters for MCP tool invocation rate limits. With ElastiCache a failover resets all counters; with MemoryDB counters survive, preventing a burst window on failover.
- Durable session tokens: if your MCP server issues session tokens with a 24-hour TTL, losing them on failover forces all connected clients to re-authenticate. MemoryDB keeps the tokens alive across failovers.
- Sorted set uptime archives: ZADD with Unix timestamps as scores, server slug as value; historical uptime scores survive cluster operations. On r6gd nodes with data tiering, weeks of history stay accessible without oversizing RAM.
CDK cluster setup
MemoryDB L1 constructs (CfnCluster, CfnSubnetGroup, CfnACL, CfnUser) are in aws-cdk-lib/aws-memorydb. There are no L2 constructs as of CDK v2.
import * as cdk from 'aws-cdk-lib';
import { aws_memorydb as memorydb, aws_ec2 as ec2 } from 'aws-cdk-lib';
// Subnet group: use isolated subnets (no internet access needed)
const subnetGroup = new memorydb.CfnSubnetGroup(this, 'MemoryDbSubnetGroup', {
subnetGroupName: 'mcp-probes-memorydb',
subnetIds: vpc.selectSubnets({ subnetType: ec2.SubnetType.PRIVATE_ISOLATED }).subnetIds,
description: 'MemoryDB subnets for MCP probe state',
});
// Security group: allow inbound 6379 from MCP server SG only
const memorydbSg = new ec2.SecurityGroup(this, 'MemoryDbSg', { vpc });
memorydbSg.addIngressRule(
mcpServerSg,
ec2.Port.tcp(6379),
'MemoryDB cluster mode port from MCP server'
);
// ACL (see ACL guide for user details — start with a minimal ACL)
const acl = new memorydb.CfnACL(this, 'MemoryDbAcl', {
aclName: 'mcp-probes-acl',
userNames: ['mcp-probe-writer', 'mcp-probe-reader'],
});
// Cluster
const cluster = new memorydb.CfnCluster(this, 'MemoryDbCluster', {
clusterName: 'mcp-probes',
nodeType: 'db.r7g.large', // r7g = DRAM-only; r6gd = data tiering
numShards: 2, // 16,384 slots split across 2 shards
numReplicasPerShard: 1, // 1 replica = 2 nodes per shard
subnetGroupName: subnetGroup.subnetGroupName,
securityGroupIds: [memorydbSg.securityGroupId],
aclName: acl.aclName, // ACL is required; no unauthenticated clusters
tlsEnabled: true, // always true in production
autoMinorVersionUpgrade: true,
snapshotRetentionLimit: 7, // 7-day automated backup retention
snapshotWindow: '05:00-06:00', // UTC window — avoid overlap with maintenance
maintenanceWindow: 'sun:07:00-sun:08:00',
parameterGroupName: 'default.memorydb-redis7',
engineVersion: '7.1',
});
cluster.addDependency(subnetGroup);
cluster.addDependency(acl);
// Cluster discovery endpoint (use this — not individual node endpoints)
new cdk.CfnOutput(this, 'MemoryDbClusterEndpoint', {
value: cluster.attrClusterEndpointAddress,
description: 'MemoryDB cluster discovery endpoint — use with cluster-mode client',
});
The ACL dependency is critical: the cluster will fail to start if its ACL is still in CREATING state. The addDependency call ensures CloudFormation waits for the ACL to reach ACTIVE before provisioning the cluster.
Parameter group choices
The default parameter groups (default.memorydb-redis7, default.memorydb-redis6.2) work for most use cases. Create a custom parameter group when you need to tune:
maxmemory-policy: defaults tonoeviction— MemoryDB is a database, not a cache; eviction should be explicit. For data-tiering nodes, avoidallkeys-lru.hz: background task frequency (default 10). Increase to 100 for faster TTL expiry on short-lived probe state keys.lazyfree-lazy-eviction: set toyeson large clusters to avoid eviction blocking the event loop.
Connecting from your MCP server
Use a cluster-mode-aware client. The cluster endpoint looks like clustercfg.mcp-probes.xxxxx.memorydb.us-east-1.amazonaws.com:6379 — note the clustercfg. prefix, which signals cluster discovery mode.
// Node.js with ioredis
import Redis from 'ioredis';
const redisClient = new Redis.Cluster(
[{ host: process.env.MEMORYDB_ENDPOINT, port: 6379 }],
{
dnsLookup: (address, callback) => callback(null, address),
redisOptions: {
tls: {}, // TLS required (tlsEnabled: true)
username: 'mcp-probe-writer',
password: process.env.MEMORYDB_PASSWORD,
},
// Cluster mode options
enableReadyCheck: true,
scaleReads: 'slave', // read from replicas to reduce primary load
clusterRetryStrategy: (times) => Math.min(100 * 2 ** times, 3000),
}
);
// Multi-key commands require keys to be in the same hash slot
// Use hash tags to co-locate related keys: {server-slug}:probes:latest {server-slug}:probes:history
await redisClient.hset('{mcp-server-slug}:probe', 'status', 'up', 'ts', Date.now());
await redisClient.expire('{mcp-server-slug}:probe', 86400);
Hash tags ({...}) guarantee that keys with the same tag land in the same hash slot, enabling multi-key operations like MGET and transactions (MULTI/EXEC) across logically related keys. For MCP probe state, use the server slug as the hash tag so all metrics for one server co-locate.
Common connection failure modes
| Error | Cause | Fix |
|---|---|---|
| WRONGPASS | ACL user password incorrect or user not in cluster's ACL | Verify Secrets Manager value matches CfnUser authentication string; confirm user is in the active ACL |
| NOPERM | ACL user's access string doesn't cover the command or keyspace | Expand access string in CfnUser; wait for ACL to reach ACTIVE state |
| MOVED | Client not in cluster mode (connecting to node endpoint, not cluster endpoint) | Use clustercfg. endpoint with cluster-mode client; never connect to individual node endpoints |
| Connection refused / TLS handshake failure | TLS disabled on client, security group blocks port 6379 | Enable TLS in client config; verify SG inbound rule allows MCP server SG |
| CLUSTERDOWN | Cluster in failover — primary election in progress | Retry with backoff; MemoryDB RTO is typically 30–60 seconds |
IAM authentication vs ACL authentication
MemoryDB does not support IAM-based authentication (unlike RDS). The only auth mechanism is ACL users with authentication strings stored as Secrets Manager secrets. Your MCP server's task role needs SecretsManager:GetSecretValue on the MemoryDB ACL user secret, but the actual Redis AUTH happens via the username/password in the connection string — not via IAM credentials.
The IAM role your MCP server runs under still needs no MemoryDB permissions for data plane operations. IAM is only used for control-plane operations (CDK/CloudFormation creating and modifying the cluster) and for rotating the ACL user passwords via Lambda rotation functions.
How AliveMCP monitors MemoryDB clusters for MCP servers
MemoryDB clusters serving MCP server state introduce a new failure mode: the cluster is up, but writes to it are timing out or returning errors. Your MCP server may continue processing requests and returning 200 responses, while its probe state or session store is silently diverging from reality. AliveMCP addresses this at three levels:
- Write-path validation: AliveMCP's MCP probe issues a
HSETwrite to a canary key in your MemoryDB cluster as part of the probe sequence. If the write fails or times out, AliveMCP flags the MCP server as degraded — the probe distinguishes between "MCP endpoint responded" and "MCP server's backend state store is healthy." - Cluster metric monitoring: AliveMCP subscribes to MemoryDB CloudWatch metrics:
EngineCPUUtilization,DatabaseMemoryUsagePercentage,CurrConnections, andGetTypeCmdsLatency. Thresholds are configurable per team; breaches trigger alerts before the cluster becomes a bottleneck. - Failover detection: during a MemoryDB primary failover, writes fail with
CLUSTERDOWNfor 30–60 seconds. AliveMCP's probe retry logic distinguishes a transient failover (recovers within 90 seconds → warning alert, not outage) from a persistent outage (does not recover → incident opened).
MemoryDB monitoring is available on the Team tier; the canary-write probe is a Team+ feature that validates both the MCP endpoint and its durable backend in a single probe run.