Valkey Open-source, Redis-compatible in-memory data store maintained by the Linux Foundation. Forked from Redis OSS 7.2.4 (BSD 3-Clause license). Drop-in replacement for Redis OSS 2.x through 7.2.x — same protocol, commands, and data formats. When to use : Caching, session storage, rate limiting, pub/sub messaging, task queues, leaderboards, distributed locks, real-time counters, or any workload requiring sub-millisecond key-value operations. When NOT to use : Primary relational data store, large object storage ( 512 MB values), workloads requiring strong ACID transactions across multiple key…

, 'MKSTREAM');\n\n// Producer\nawait valkey.xadd(\n 'stream:tasks',\n '*',\n 'type',\n 'process',\n 'payload',\n JSON.stringify(data),\n);\n\n// Consumer\nconst entries = await valkey.xreadgroup(\n 'GROUP',\n 'workers',\n 'consumer1',\n 'COUNT',\n 1,\n 'BLOCK',\n 5000,\n 'STREAMS',\n 'stream:tasks',\n '>',\n);\n\nif (entries) {\n const [, messages] = entries[0];\n for (const [id, fields] of messages) {\n await processTask(fields);\n await valkey.xack('stream:tasks', 'workers', id);\n }\n}\n```\n\n## Session Storage\n\n### Hash-Based Sessions\n\n```ts\nasync function createSession(\n sessionId: string,\n data: Record\u003cstring, string>,\n): Promise\u003cvoid> {\n const key = `session:${sessionId}`;\n await valkey.hset(key, data);\n await valkey.expire(key, 1800); // 30 minutes\n}\n\nasync function getSession(\n sessionId: string,\n): Promise\u003cRecord\u003cstring, string> | null> {\n const key = `session:${sessionId}`;\n const data = await valkey.hgetall(key);\n if (Object.keys(data).length === 0) return null;\n\n // Sliding expiration\n await valkey.expire(key, 1800);\n return data;\n}\n\nasync function destroySession(sessionId: string): Promise\u003cvoid> {\n await valkey.unlink(`session:${sessionId}`);\n}\n```\n\n### String-Based Sessions (JSON)\n\nSimpler but cannot update individual fields without read-modify-write:\n\n```ts\nawait valkey.set(`session:${id}`, JSON.stringify(sessionData), 'EX', 1800);\nconst session = JSON.parse(await valkey.get(`session:${id}`));\n```\n\nHash-based is preferred when individual fields are read or updated independently.\n\n## Pub/Sub\n\nFire-and-forget messaging. Messages are NOT persisted — if no subscriber is listening, the message is lost.\n\n```ts\n// Subscriber\nconst sub = valkey.duplicate(); // Dedicated connection for subscriptions\nawait sub.subscribe('notifications:user:123');\n\nsub.on('message', (channel, message) => {\n const event = JSON.parse(message);\n handleNotification(event);\n});\n\n// Publisher (from any connection)\nawait valkey.publish(\n 'notifications:user:123',\n JSON.stringify({ type: 'new_message', from: 'Alice' }),\n);\n```\n\n### Pattern Subscriptions\n\n```ts\nawait sub.psubscribe('notifications:*');\n\nsub.on('pmessage', (pattern, channel, message) => {\n // pattern = 'notifications:*'\n // channel = 'notifications:user:123'\n});\n```\n\nUse Pub/Sub for: real-time notifications, cache invalidation broadcasts, live dashboards.\nUse Streams instead when: you need message persistence, replay, or at-least-once delivery.\n\n## Leaderboards\n\nSorted sets provide O(log N) rank operations — ideal for leaderboards at any scale.\n\n```ts\n// Add or update score\nawait valkey.zadd('leaderboard:weekly', score, `player:${userId}`);\n\n// Increment score\nawait valkey.zincrby('leaderboard:weekly', pointsEarned, `player:${userId}`);\n\n// Top 10 with scores\nconst top10 = await valkey.zrevrange('leaderboard:weekly', 0, 9, 'WITHSCORES');\n\n// Player rank (0-based)\nconst rank = await valkey.zrevrank('leaderboard:weekly', `player:${userId}`);\n\n// Players in score range\nconst tier = await valkey.zrangebyscore(\n 'leaderboard:weekly',\n 1000,\n 2000,\n 'WITHSCORES',\n);\n```\n\n## Counters\n\nAtomic increment/decrement operations. No race conditions.\n\n```ts\n// Page views\nawait valkey.incr('page:views:home');\n\n// Credits\nawait valkey.incrby(`user:credits:${userId}`, 50);\n\n// Hash field counters\nawait valkey.hincrby('stats:daily', 'signups', 1);\nawait valkey.hincrby('stats:daily', 'api_calls', 1);\n\n// Decrement\nawait valkey.decrby(`user:credits:${userId}`, 10);\n```\n\n## Pipelining\n\nSend multiple commands without waiting for individual responses. Reduces round-trip overhead.\n\n```ts\nconst pipeline = valkey.pipeline();\npipeline.set('key1', 'val1', 'EX', 3600);\npipeline.set('key2', 'val2', 'EX', 3600);\npipeline.get('key3');\npipeline.incr('counter');\n\nconst results = await pipeline.exec();\n// results = [[null, 'OK'], [null, 'OK'], [null, 'val3'], [null, 42]]\n```\n\nPipeline in batches of ~1,000-10,000 commands to balance throughput and memory.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":7725,"content_sha256":"6e7957fef5cf20bc6b10c70a0a32accb4a08522eb97d52175a1bfd9520090574"},{"filename":"references/data-structures.md","content":"---\ntitle: Data Structures and Commands\ndescription: Core Valkey data types with key commands — strings, hashes, lists, sets, sorted sets, streams, HyperLogLog, bitmaps, and geospatial indexes\ntags:\n [\n strings,\n hashes,\n lists,\n sets,\n sorted-sets,\n streams,\n hyperloglog,\n bitmaps,\n geospatial,\n ]\n---\n\n## Strings\n\nBinary-safe sequences up to 512 MB. The most basic type — used for caching, counters, and flags.\n\n```bash\nSET user:123:name \"Alice\" EX 3600 # Set with 1-hour TTL\nGET user:123:name # Retrieve value\nMSET k1 \"v1\" k2 \"v2\" # Set multiple atomically\nMGET k1 k2 # Get multiple\nINCR page:views:home # Atomic increment (returns new value)\nINCRBY user:credits:123 50 # Increment by amount\nSETNX lock:resource \"token\" # Set only if not exists\n```\n\nKey flags for `SET`:\n\n| Flag | Meaning |\n| ----------------- | ------------------------------- |\n| `EX seconds` | TTL in seconds |\n| `PX milliseconds` | TTL in milliseconds |\n| `NX` | Only set if key does not exist |\n| `XX` | Only set if key already exists |\n| `GET` | Return old value before setting |\n\n## Hashes\n\nField-value maps attached to a single key. Ideal for objects and structured data.\n\n```bash\nHSET user:123 name \"Alice\" email \"[email protected]\" role \"admin\"\nHGET user:123 name # Single field\nHMGET user:123 name email # Multiple fields\nHGETALL user:123 # All fields and values\nHDEL user:123 role # Remove field\nHINCRBY user:123 login_count 1 # Increment numeric field\nHEXISTS user:123 email # Check field existence\nHKEYS user:123 # All field names\nHLEN user:123 # Field count\n```\n\nValkey 9.0+ supports **hash field expiration** — expire individual fields without destroying the whole key:\n\n```bash\nHGETEX user:123 FIELDS 1 temp_token EX 300 # Get field, set 5-min TTL on it\n```\n\n## Lists\n\nOrdered collections (insertion order). Implemented as linked lists — O(1) push/pop, O(N) index access.\n\n```bash\nRPUSH queue:emails \"msg1\" \"msg2\" # Append to tail\nLPUSH queue:emails \"msg0\" # Prepend to head\nRPOP queue:emails # Pop from tail\nLPOP queue:emails # Pop from head\nLRANGE queue:emails 0 -1 # Get all elements\nLLEN queue:emails # List length\nBRPOP queue:emails 30 # Blocking pop (30s timeout)\nLMOVE src dest RIGHT LEFT # Atomic move between lists\n```\n\n## Sets\n\nUnordered collections of unique strings. O(1) membership check.\n\n```bash\nSADD tags:post:1 \"typescript\" \"react\" \"testing\"\nSREM tags:post:1 \"testing\" # Remove member\nSISMEMBER tags:post:1 \"react\" # Check membership (O(1))\nSMEMBERS tags:post:1 # All members\nSCARD tags:post:1 # Count\nSINTER tags:post:1 tags:post:2 # Intersection\nSUNION tags:post:1 tags:post:2 # Union\nSDIFF tags:post:1 tags:post:2 # Difference\nSRANDMEMBER tags:post:1 2 # 2 random members\n```\n\n## Sorted Sets\n\nUnique strings ordered by floating-point score. O(log N) for most operations. The backbone of leaderboards, priority queues, and time-series indexes.\n\n```bash\nZADD leaderboard 1500 \"player:1\" 1200 \"player:2\" 1800 \"player:3\"\nZREVRANGE leaderboard 0 9 WITHSCORES # Top 10 (highest first)\nZRANGE leaderboard 0 9 WITHSCORES # Bottom 10 (lowest first)\nZRANK leaderboard \"player:1\" # Rank (0-based, ascending)\nZREVRANK leaderboard \"player:1\" # Rank (0-based, descending)\nZSCORE leaderboard \"player:1\" # Get score\nZINCRBY leaderboard 10 \"player:1\" # Increment score\nZRANGEBYSCORE leaderboard 1000 2000 # Members in score range\nZREM leaderboard \"player:2\" # Remove member\nZCARD leaderboard # Count\n```\n\n## Streams\n\nAppend-only log for event sourcing and message queuing. Persistent, replayable, with consumer groups.\n\n```bash\n# Produce\nXADD events:orders * action \"created\" order_id \"ord_123\" total \"4999\"\n\n# Consume (simple)\nXREAD COUNT 10 BLOCK 5000 STREAMS events:orders 0\nXRANGE events:orders - + # All entries\nXLEN events:orders # Stream length\n\n# Consumer groups (at-least-once delivery)\nXGROUP CREATE events:orders workers $ MKSTREAM\nXREADGROUP GROUP workers consumer1 COUNT 1 BLOCK 5000 STREAMS events:orders >\nXACK events:orders workers 1234567890-0 # Acknowledge processing\nXPENDING events:orders workers # View unacknowledged\nXTRIM events:orders MAXLEN ~ 10000 # Trim to ~10K entries\n```\n\n### Streams vs Pub/Sub\n\n| Feature | Pub/Sub | Streams |\n| --------------- | ----------------------- | ----------------------------- |\n| Persistence | No | Yes |\n| Replay | No | Yes (`XRANGE`) |\n| Consumer groups | No | Yes (`XGROUP`) |\n| Acknowledgment | No | Yes (`XACK`) |\n| Delivery | At-most-once | At-most-once or at-least-once |\n| Use case | Real-time notifications | Event sourcing, task queues |\n\n## HyperLogLog\n\nProbabilistic cardinality estimation using ~12 KB regardless of set size. 0.81% standard error.\n\n```bash\nPFADD unique:visitors:2025-02 \"user:1\" \"user:2\" \"user:3\"\nPFCOUNT unique:visitors:2025-02 # Approximate unique count\nPFMERGE unique:visitors:q1 unique:visitors:2025-01 unique:visitors:2025-02\n```\n\nUse for: unique visitor counts, distinct event tracking, cardinality where exact precision is not required.\n\n## Bitmaps\n\nBit-level operations on strings. Memory-efficient for boolean flags across large ID spaces.\n\n```bash\nSETBIT feature:dark-mode 1001 1 # User 1001 enabled dark mode\nGETBIT feature:dark-mode 1001 # Check flag\nBITCOUNT feature:dark-mode # Count enabled users\nBITOP AND both:features feature:dark-mode feature:beta\nBITPOS feature:dark-mode 1 # First user with flag set\n```\n\nUse for: feature flags, daily active user tracking, presence indicators.\n\n## Geospatial\n\nStore and query geographic coordinates using sorted sets internally.\n\n```bash\nGEOADD stores -122.4194 37.7749 \"sf-downtown\" -73.9857 40.7484 \"nyc-midtown\"\nGEOPOS stores \"sf-downtown\" # Get coordinates\nGEODIST stores \"sf-downtown\" \"nyc-midtown\" km # Distance\nGEOSEARCH stores FROMLONLAT -122.4 37.8 BYRADIUS 10 km ASC COUNT 5\n```\n\n## Key Management\n\nCommands that apply across all data types:\n\n```bash\nEXISTS key # Check existence (returns 0 or 1)\nTYPE key # Get data type\nTTL key # Remaining TTL in seconds (-1 = no TTL, -2 = expired)\nEXPIRE key 3600 # Set TTL\nPERSIST key # Remove TTL\nRENAME key newkey # Rename\nUNLINK key # Async delete (non-blocking)\nSCAN 0 MATCH \"user:*\" COUNT 100 # Iterate keys (cursor-based)\nOBJECT ENCODING key # Internal encoding (ziplist, hashtable, etc.)\nMEMORY USAGE key # Bytes used by key\n```\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":7612,"content_sha256":"597a482f3f2b64d457b353b56999d01a1b276853c1e3023bdbf88e7c40276f46"},{"filename":"references/docker-and-deployment.md","content":"---\ntitle: Docker and Deployment\ndescription: Docker Compose setup, persistence configuration, replication, Sentinel, Cluster mode, security, client libraries, and migration from Redis\ntags:\n [\n docker,\n compose,\n persistence,\n replication,\n sentinel,\n cluster,\n security,\n migration,\n ioredis,\n iovalkey,\n ]\n---\n\n## Docker Compose\n\n### Development Setup\n\n```yaml\nservices:\n valkey:\n image: valkey/valkey:8.1-alpine\n ports:\n - '6379:6379'\n volumes:\n - valkey-data:/data\n command: valkey-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru\n healthcheck:\n test: ['CMD', 'valkey-cli', 'ping']\n interval: 10s\n timeout: 5s\n retries: 3\n restart: unless-stopped\n\nvolumes:\n valkey-data:\n```\n\n### Production Setup\n\n```yaml\nservices:\n valkey:\n image: valkey/valkey:8.1-alpine\n ports:\n - '6379:6379'\n volumes:\n - valkey-data:/data\n command: >\n valkey-server\n --appendonly yes\n --appendfsync everysec\n --maxmemory 1gb\n --maxmemory-policy allkeys-lru\n --requirepass ${VALKEY_PASSWORD}\n --bind 0.0.0.0\n --protected-mode yes\n --save 900 1\n --save 300 10\n --save 60 10000\n healthcheck:\n test: ['CMD', 'valkey-cli', '-a', '${VALKEY_PASSWORD}', 'ping']\n interval: 10s\n timeout: 5s\n retries: 3\n deploy:\n resources:\n limits:\n memory: 1280m\n restart: unless-stopped\n\nvolumes:\n valkey-data:\n```\n\n### With Application Service\n\n```yaml\nservices:\n app:\n build: .\n environment:\n VALKEY_URL: valkey://valkey:6379\n depends_on:\n valkey:\n condition: service_healthy\n\n valkey:\n image: valkey/valkey:8.1-alpine\n volumes:\n - valkey-data:/data\n command: valkey-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru\n healthcheck:\n test: ['CMD', 'valkey-cli', 'ping']\n interval: 10s\n timeout: 5s\n retries: 3\n\nvolumes:\n valkey-data:\n```\n\n### Valkey Bundle (With Modules)\n\nIncludes JSON, Bloom, and Search modules:\n\n```yaml\nservices:\n valkey:\n image: valkey/valkey-bundle:latest\n ports:\n - '6379:6379'\n volumes:\n - valkey-data:/data\n```\n\n## Persistence\n\n### RDB (Point-in-Time Snapshots)\n\n```text\nsave 900 1 # Snapshot if 1+ keys changed in 900 seconds\nsave 300 10 # Snapshot if 10+ keys changed in 300 seconds\nsave 60 10000 # Snapshot if 10000+ keys changed in 60 seconds\ndbfilename dump.rdb\ndir /data\n```\n\nGood for backups. Some data loss on crash (up to the last snapshot interval).\n\n### AOF (Append-Only File)\n\n```text\nappendonly yes\nappendfsync everysec # Options: always, everysec, no\nauto-aof-rewrite-percentage 100\nauto-aof-rewrite-min-size 64mb\n```\n\n| `appendfsync` | Durability | Performance |\n| ------------- | ------------------- | ---------------------- |\n| `always` | No data loss | Slowest |\n| `everysec` | Up to 1 second loss | Balanced (recommended) |\n| `no` | OS-dependent | Fastest |\n\n### RDB + AOF (Recommended)\n\nEnable both. On restart, AOF is used for recovery (more complete). RDB provides efficient backups.\n\n## Replication\n\nAsynchronous primary-replica replication for read scaling and high availability.\n\n```text\n# On replica (valkey.conf)\nreplicaof primary-host 6379\nreplica-read-only yes\n```\n\nDocker Compose with replication:\n\n```yaml\nservices:\n valkey-primary:\n image: valkey/valkey:8.1-alpine\n command: valkey-server --appendonly yes\n volumes:\n - primary-data:/data\n\n valkey-replica:\n image: valkey/valkey:8.1-alpine\n command: valkey-server --replicaof valkey-primary 6379 --replica-read-only yes\n depends_on:\n - valkey-primary\n\nvolumes:\n primary-data:\n```\n\n## Sentinel (High Availability)\n\nAutomatic failover for primary-replica deployments. Run 3+ Sentinel instances for quorum.\n\n```text\n# sentinel.conf\nsentinel monitor myvalkey valkey-primary 6379 2 # 2 = quorum\nsentinel down-after-milliseconds myvalkey 5000\nsentinel failover-timeout myvalkey 60000\nsentinel parallel-syncs myvalkey 1\n```\n\nClients connect to Sentinel to discover the current primary:\n\n```ts\nimport Valkey from 'iovalkey';\n\nconst valkey = new Valkey({\n sentinels: [\n { host: 'sentinel-1', port: 26379 },\n { host: 'sentinel-2', port: 26379 },\n { host: 'sentinel-3', port: 26379 },\n ],\n name: 'myvalkey',\n});\n```\n\n## Cluster Mode\n\nData partitioned across nodes using 16,384 hash slots. Horizontal scaling.\n\n```text\n# valkey.conf (each node)\ncluster-enabled yes\ncluster-config-file nodes.conf\ncluster-node-timeout 5000\n```\n\nClient connection:\n\n```ts\nimport Valkey from 'iovalkey';\n\nconst cluster = new Valkey.Cluster([\n { host: 'node-1', port: 6379 },\n { host: 'node-2', port: 6379 },\n { host: 'node-3', port: 6379 },\n]);\n```\n\nValkey 9.0 improvements: atomic slot migration, numbered databases in cluster mode, scaling to 2,000+ nodes.\n\n## Security\n\n### Authentication\n\n```text\n# Single password (legacy)\nrequirepass your_strong_password\n\n# ACL (recommended)\nuser default off\nuser appuser on >password ~app:* +@read +@write -@admin\nuser readonly on >readpass ~* +@read\n```\n\n### TLS\n\n```text\ntls-port 6380\ntls-cert-file /path/to/valkey.crt\ntls-key-file /path/to/valkey.key\ntls-ca-cert-file /path/to/ca.crt\ntls-auth-clients yes\n```\n\n### Hardening Checklist\n\n- Set `requirepass` or configure ACLs\n- Bind to specific interfaces: `bind 127.0.0.1`\n- Enable `protected-mode yes` when no auth is set\n- Disable dangerous commands via ACLs or `rename-command FLUSHALL \"\"`\n- Run as unprivileged user (default in Docker image)\n- Never expose port 6379 directly to the internet\n\n## Client Libraries\n\n### Node.js / TypeScript Options\n\n| Package | Description | Recommendation |\n| ---------------------- | -------------------------------------------------- | ----------------------------------- |\n| `ioredis` | Popular Redis client, works with Valkey unchanged | Existing projects |\n| `iovalkey` | Official Valkey fork of ioredis, identical API | New projects (official maintenance) |\n| `redis` (node-redis) | Official Redis client, works with Valkey unchanged | If already using |\n| `@valkey/valkey-glide` | Rust-core client with Node.js bindings | Maximum performance |\n\n### Connection Example (iovalkey / ioredis)\n\n```ts\nimport Valkey from 'iovalkey';\n\nconst valkey = new Valkey({\n host: 'localhost',\n port: 6379,\n password: process.env.VALKEY_PASSWORD,\n maxRetriesPerRequest: 3,\n retryStrategy(times) {\n return Math.min(times * 50, 2000);\n },\n});\n\nvalkey.on('error', (err) => console.error('Valkey connection error:', err));\nvalkey.on('connect', () => console.log('Connected to Valkey'));\n```\n\n### Connection URL\n\n```ts\nconst valkey = new Valkey('redis://user:password@host:6379/0');\n```\n\nThe `redis://` scheme works — Valkey is protocol-compatible.\n\n## Migration from Redis\n\n### What Changes\n\n| Aspect | Redis | Valkey |\n| ------------ | ---------------------------- | ------------------------------ |\n| Binary | `redis-server` / `redis-cli` | `valkey-server` / `valkey-cli` |\n| Config file | `redis.conf` | `valkey.conf` |\n| License | RSALv2 / SSPLv1 | BSD 3-Clause |\n| Docker image | `redis` | `valkey/valkey` |\n\n### What Stays the Same\n\n- All commands and data structures\n- Wire protocol (RESP2 / RESP3)\n- RDB and AOF file formats (through Redis 7.2)\n- Client libraries (no code changes needed)\n- Cluster, Sentinel, and replication protocols\n- Lua scripting and module API\n- Default port (6379)\n\n### Migration Steps\n\n**Minimal downtime (replication):**\n\n1. Start Valkey instance\n2. Configure Valkey as replica of Redis: `replicaof redis-host 6379`\n3. Wait for sync to complete: `INFO replication` shows `master_link_status:up`\n4. Stop writes to Redis\n5. Promote Valkey: `replicaof no one`\n6. Update application connection strings\n7. Resume writes\n\n**Zero downtime (DNS swap):**\n\n1. Run Valkey as replica until caught up\n2. Promote Valkey to primary\n3. Update DNS or load balancer to point to Valkey\n4. Decommission Redis\n\n**Physical (requires downtime):**\n\n1. Stop Redis\n2. Copy RDB file to Valkey data directory\n3. Start Valkey\n\nRedis CE 7.4+ data files are NOT compatible with Valkey. Migrate from 7.4+ using replication or export/import.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":8635,"content_sha256":"fbb445065dddd55a7b312396d254af180152b627a2eed4b5ca036674c71a4323"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Valkey","type":"text"}]},{"type":"paragraph","content":[{"text":"Open-source, Redis-compatible in-memory data store maintained by the Linux Foundation. Forked from Redis OSS 7.2.4 (BSD 3-Clause license). Drop-in replacement for Redis OSS 2.x through 7.2.x — same protocol, commands, and data formats.","type":"text"}]},{"type":"paragraph","content":[{"text":"When to use","type":"text","marks":[{"type":"strong"}]},{"text":": Caching, session storage, rate limiting, pub/sub messaging, task queues, leaderboards, distributed locks, real-time counters, or any workload requiring sub-millisecond key-value operations.","type":"text"}]},{"type":"paragraph","content":[{"text":"When NOT to use","type":"text","marks":[{"type":"strong"}]},{"text":": Primary relational data store, large object storage (>512 MB values), workloads requiring strong ACID transactions across multiple keys without Lua scripting.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Reference","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Task","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Approach","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Key Point","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cache-aside","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"GET","type":"text","marks":[{"type":"code_inline"}]},{"text":" -> miss -> DB read -> ","type":"text"},{"text":"SET key val EX ttl","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Always set a TTL, even a long one","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Session storage","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"HSET session:{id} field val","type":"text","marks":[{"type":"code_inline"}]},{"text":" + ","type":"text"},{"text":"EXPIRE","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sliding TTL on each request","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Rate limiting","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"INCR","type":"text","marks":[{"type":"code_inline"}]},{"text":" + ","type":"text"},{"text":"EXPIRE","type":"text","marks":[{"type":"code_inline"}]},{"text":" (fixed window) or sorted set (sliding)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sorted set for precision","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Distributed lock","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SET lock:{res} token NX PX 30000","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Always set expiry to prevent deadlocks","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Queue (simple)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"LPUSH","type":"text","marks":[{"type":"code_inline"}]},{"text":" + ","type":"text"},{"text":"BRPOP","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Blocking pop with timeout","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Queue (reliable)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Streams + ","type":"text"},{"text":"XGROUP","type":"text","marks":[{"type":"code_inline"}]},{"text":" + ","type":"text"},{"text":"XACK","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Consumer groups for at-least-once","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pub/Sub","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SUBSCRIBE","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"PUBLISH","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fire-and-forget, no persistence","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Streams","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"XADD","type":"text","marks":[{"type":"code_inline"}]},{"text":" + ","type":"text"},{"text":"XREADGROUP","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Persistent, replayable, consumer groups","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Leaderboard","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sorted set: ","type":"text"},{"text":"ZADD","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"ZREVRANGE","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"O(log N) rank operations","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Unique count","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"PFADD","type":"text","marks":[{"type":"code_inline"}]},{"text":" + ","type":"text"},{"text":"PFCOUNT","type":"text","marks":[{"type":"code_inline"}]},{"text":" (HyperLogLog)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"~12 KB memory, 0.81% error","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Eviction policy","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"maxmemory-policy allkeys-lru","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Best default for most workloads","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Docker setup","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"valkey/valkey:8.1-alpine","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Health check: ","type":"text"},{"text":"valkey-cli ping","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Persistence","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AOF (","type":"text"},{"text":"appendonly yes","type":"text","marks":[{"type":"code_inline"}]},{"text":") + RDB snapshots","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"AOF for durability, RDB for backups","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Client library","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ioredis","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"iovalkey","type":"text","marks":[{"type":"code_inline"}]},{"text":" (official fork)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"All Redis clients work unchanged","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Migrate from Redis","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Swap binary, keep data files","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"RDB/AOF compatible through Redis 7.2","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Common Mistakes","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Mistake","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Correct Pattern","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Using ","type":"text"},{"text":"KEYS *","type":"text","marks":[{"type":"code_inline"}]},{"text":" in production","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"SCAN","type":"text","marks":[{"type":"code_inline"}]},{"text":" with cursor for iteration","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"No TTL on cache keys","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Always set TTL — unbounded growth causes OOM","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"DEL","type":"text","marks":[{"type":"code_inline"}]},{"text":" on large keys blocking server","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"UNLINK","type":"text","marks":[{"type":"code_inline"}]},{"text":" for async deletion","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pub/Sub for durable messaging","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use Streams with consumer groups for persistence","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Same TTL on all keys (thundering herd)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Add jitter: ","type":"text"},{"text":"EX (base + random(0, spread))","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"No ","type":"text"},{"text":"maxmemory","type":"text","marks":[{"type":"code_inline"}]},{"text":" set in production","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Set ","type":"text"},{"text":"maxmemory","type":"text","marks":[{"type":"code_inline"}]},{"text":" + eviction policy explicitly","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Using ","type":"text"},{"text":"MULTI/EXEC","type":"text","marks":[{"type":"code_inline"}]},{"text":" for locking","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"SET ... NX PX","type":"text","marks":[{"type":"code_inline"}]},{"text":" for distributed locks","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Storing large blobs (>1 MB values)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Store references; keep values small","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"No health check in Docker Compose","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Add ","type":"text"},{"text":"valkey-cli ping","type":"text","marks":[{"type":"code_inline"}]},{"text":" health check","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Ignoring ","type":"text"},{"text":"requirepass","type":"text","marks":[{"type":"code_inline"}]},{"text":" in production","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Always set authentication + ACLs","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Delegation","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Discover caching patterns and data model review","type":"text","marks":[{"type":"strong"}]},{"text":": Use ","type":"text"},{"text":"Explore","type":"text","marks":[{"type":"code_inline"}]},{"text":" agent","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Plan migration strategy from Redis to Valkey","type":"text","marks":[{"type":"strong"}]},{"text":": Use ","type":"text"},{"text":"Plan","type":"text","marks":[{"type":"code_inline"}]},{"text":" agent","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Implement full caching layer with tests","type":"text","marks":[{"type":"strong"}]},{"text":": Use ","type":"text"},{"text":"Task","type":"text","marks":[{"type":"code_inline"}]},{"text":" agent","type":"text"}]}]}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"If the ","type":"text"},{"text":"docker","type":"text","marks":[{"type":"code_inline"}]},{"text":" skill is available, delegate Compose networking and multi-stage build patterns to it. If the ","type":"text"},{"text":"performance-optimizer","type":"text","marks":[{"type":"code_inline"}]},{"text":" skill is available, delegate application-level caching strategy to it. If the ","type":"text"},{"text":"database-security","type":"text","marks":[{"type":"code_inline"}]},{"text":" skill is available, delegate ACL and TLS configuration review to it.","type":"text"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"References","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Data structures and commands","type":"text","marks":[{"type":"link","attrs":{"href":"references/data-structures.md","title":null}}]},{"text":" -- Strings, hashes, lists, sets, sorted sets, streams, HyperLogLog, bitmaps, geospatial","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Caching patterns","type":"text","marks":[{"type":"link","attrs":{"href":"references/caching-patterns.md","title":null}}]},{"text":" -- Cache-aside, write-through, TTL strategies, eviction policies, client-side caching, invalidation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Common patterns","type":"text","marks":[{"type":"link","attrs":{"href":"references/common-patterns.md","title":null}}]},{"text":" -- Rate limiting, distributed locks, queues, session storage, pub/sub, streams, leaderboards","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Docker and deployment","type":"text","marks":[{"type":"link","attrs":{"href":"references/docker-and-deployment.md","title":null}}]},{"text":" -- Compose setup, persistence, replication, Sentinel, Cluster, security, migration from Redis","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"valkey","author":"@skillopedia","source":{"stars":12,"repo_name":"agent-skills","origin_url":"https://github.com/oakoss/agent-skills/blob/HEAD/skills/valkey/SKILL.md","repo_owner":"oakoss","body_sha256":"b95b44419fba21796bf7d6d9f82db777023b26132640a6e2a105d1c439dea7db","cluster_key":"f7a583b8d07e8ade84a76651bb03d233c83b5ccdb8c5db021de0b4692bf0dcc8","clean_bundle":{"format":"clean-skill-bundle-v1","source":"oakoss/agent-skills/skills/valkey/SKILL.md","attachments":[{"id":"892f9977-2128-521a-936d-5d449d57e145","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/892f9977-2128-521a-936d-5d449d57e145/attachment.md","path":"references/caching-patterns.md","size":7569,"sha256":"eb816b22213d05e983cbf1912b0c84a04a94bba694330a410642076fe5e0a285","contentType":"text/markdown; charset=utf-8"},{"id":"a4002559-03f0-596c-803b-b76d9a530854","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/a4002559-03f0-596c-803b-b76d9a530854/attachment.md","path":"references/common-patterns.md","size":7725,"sha256":"6e7957fef5cf20bc6b10c70a0a32accb4a08522eb97d52175a1bfd9520090574","contentType":"text/markdown; charset=utf-8"},{"id":"ba713003-9649-5683-9e40-80667973feb9","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/ba713003-9649-5683-9e40-80667973feb9/attachment.md","path":"references/data-structures.md","size":7612,"sha256":"597a482f3f2b64d457b353b56999d01a1b276853c1e3023bdbf88e7c40276f46","contentType":"text/markdown; charset=utf-8"},{"id":"9d586ec5-b5fa-59ea-8919-ac7972a1bf66","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/9d586ec5-b5fa-59ea-8919-ac7972a1bf66/attachment.md","path":"references/docker-and-deployment.md","size":8635,"sha256":"fbb445065dddd55a7b312396d254af180152b627a2eed4b5ca036674c71a4323","contentType":"text/markdown; charset=utf-8"}],"bundle_sha256":"eb6f7201c53417e05b9a4cfed2272d104faec8156a05142167d92bf5812e8c94","attachment_count":4,"text_attachments":4,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/valkey/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"devops-infrastructure","category_label":"DevOps"},"exact_dupes_collapsed_into_this":0},"license":"MIT","version":"v1","category":"devops-infrastructure","metadata":{"author":"oakoss","source":"https://valkey.io/commands/","version":"1.0"},"import_tag":"clean-skills-v1","description":"Valkey (Redis-compatible) in-memory data store for caching, session storage, pub/sub, queues, and distributed locks. Use when configuring Valkey or Redis-compatible caching, choosing eviction policies, implementing rate limiting, setting up pub/sub or streams, writing Docker Compose services, migrating from Redis, or tuning performance. Use for valkey, redis, cache, session, pub/sub, streams, distributed-lock, rate-limit, sorted-set.","user-invocable":false}},"renderedAt":1782986921838}

Valkey Open-source, Redis-compatible in-memory data store maintained by the Linux Foundation. Forked from Redis OSS 7.2.4 (BSD 3-Clause license). Drop-in replacement for Redis OSS 2.x through 7.2.x — same protocol, commands, and data formats. When to use : Caching, session storage, rate limiting, pub/sub messaging, task queues, leaderboards, distributed locks, real-time counters, or any workload requiring sub-millisecond key-value operations. When NOT to use : Primary relational data store, large object storage ( 512 MB values), workloads requiring strong ACID transactions across multiple key…