{
  "schema_version": 2,
  "id": "develop/using-commands/multi-key-operations",
  "title": "Multi-key operations",
  "url": "https://redis.io/docs/latest/develop/using-commands/multi-key-operations/",
  "summary": "Multi-key command behavior across Redis configurations and clustering setups",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-01-16T06:26:38-08:00",
  "page_type": "content",
  "content_hash": "cc91ff397cbab28aea88db3b64860bf4b02bd8cda1d3680ec16f26937ed1365b",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "Multi-key operations in Redis allow you to work with multiple keys in a single command, but their behavior varies significantly depending on your Redis configuration and clustering setup. This page provides a quick reference for developers working with multi-key operations across different Redis configurations."
    },
    {
      "id": "configurations",
      "title": "Configurations",
      "role": "configuration",
      "text": "Redis supports five distinct configurations, each with different multi-key command behaviors:\n\n1. **ROS/RS clustering disabled** - Single Redis instance\n2. **ROS, clustering enabled** - Redis Open Source cluster\n3. **RS, clustering enabled, OSS cluster API enabled** - Redis Software with ROS cluster compatibility\n4. **RS, clustering enabled, OSS cluster API disabled** - Redis Software proprietary clustering\n5. **RS, Active-Active** - Redis Software Active-Active (considered clustered even with a single shard)\n\nROS stands for Redis Open Source and RS stands for Redis Software."
    },
    {
      "id": "command-behaviors",
      "title": "Command behaviors",
      "role": "syntax",
      "text": "For each configuration, commands exhibit one of three behaviors:\n\n- **single-slot**: Commands must operate on keys within the same hash slot\n- **cross-slot (all shards)**: Commands can operate across all shards in the cluster\n- **cross-slot (within a single shard)**: Commands can operate across slots but only within a single shard"
    },
    {
      "id": "read-only-commands",
      "title": "Read-only commands",
      "role": "content",
      "text": "| Behavior | Commands |\n|----------|----------|\n| **ROS/RS clustering disabled:**<br>&ndash; the whole DB (single shard)<br><br>**ROS clustering enabled, RS clustering enabled (OSS cluster API enabled):**<br>&ndash; the current shard<br><br>**RS clustering enabled (OSS cluster API disabled):**<br>&ndash; all shards | DBSIZE, KEYS, SCAN |\n| **ROS/RS clustering disabled:**<br>&ndash; cross-slot<br><br>**ROS clustering enabled, RS clustering enabled (OSS cluster API enabled):**<br>&ndash; single-slot<br><br>**RS clustering enabled (OSS cluster API disabled):**<br>&ndash; cross-slot (all shards) | EXISTS, MGET |\n| **ROS/RS clustering disabled:**<br>&ndash; cross-slot<br><br>**ROS clustering enabled, RS clustering enabled (OSS cluster API enabled), RS clustering enabled (OSS cluster API disabled):**<br>&ndash; single-slot | PFCOUNT, SDIFF, SINTER, SINTERCARD, SUNION, WATCH, XREAD, XREADGROUP, ZDIFF, ZINTER, ZINTERCARD, ZUNION |\n| **ROS/RS clustering disabled:**<br>&ndash; cross-slot<br><br>**ROS clustering enabled, RS clustering enabled (OSS cluster API enabled), RS clustering enabled (OSS cluster API disabled):**<br>&ndash; single-shard | JSON.MGET<br><br>Users won't get a CROSSSLOT error. However, when clustering is enabled, and not all specified keys are in the same slot, users will get partial results for all the slots on the current shard. |\n| **ROS/RS clustering disabled:**<br>&ndash; cross-slot (all shards)<br><br>**ROS clustering enabled, RS clustering enabled (OSS cluster API enabled), RS clustering enabled (OSS cluster API disabled):**<br>&ndash; cross-slot (all shards), cannot be part of a transaction | TS.MGET, TS.MRANGE, TS.MREVRANGE, TS.QUERYINDEX |"
    },
    {
      "id": "read-write-commands",
      "title": "Read-write commands",
      "role": "content",
      "text": "| Behavior | Commands |\n|----------|----------|\n| **ROS/RS clustering disabled:**<br>&ndash; the whole DB (single shard)<br><br>**ROS clustering enabled, RS clustering enabled (OSS cluster API enabled):**<br>&ndash; the current shard<br><br>**RS clustering enabled (OSS cluster API disabled):**<br>&ndash; all shards | FLUSHALL, FLUSHDB |\n| **ROS/RS clustering disabled:**<br>&ndash; cross-slot<br><br>**ROS clustering enabled, RS clustering enabled (OSS cluster API enabled):**<br>&ndash; single-slot<br><br>**RS clustering enabled (OSS cluster API disabled):**<br>&ndash; cross-slot (all shards) | DEL, MSET, TOUCH, UNLINK<br><br>Note: on Active-Active, DEL, MSET, and UNLINK are single-slot |\n| **ROS/RS clustering disabled:**<br>&ndash; cross-slot<br><br>**ROS clustering enabled, RS clustering enabled (OSS cluster API enabled), RS clustering enabled (OSS cluster API disabled):**<br>&ndash; single-slot | BITOP, BLMOVE, BLMPOP, BLPOP, BRPOP, BRPOPLPUSH, BZMPOP, BZPOPMAX, BZPOPMIN, CMS.MERGE, COPY, GEORADIUS or GEORADIUSBYMEMBER (with STORE or STOREDIST), GEOSEARCHSTORE, JSON.MSET, LMOVE, LMPOP, MSETNX, PFMERGE, RENAME, RENAMENX, RPOPLPUSH, SDIFFSTORE, SINTERSTORE, SMOVE, SUNIONSTORE, TDIGEST.MERGE, TS.MADD, ZDIFFSTORE, ZINTERSTORE, ZMPOP, ZRANGESTORE, ZUNIONSTORE |\n| **ROS/RS clustering disabled:**<br>&ndash; cross-slot<br><br>**ROS clustering enabled, RS clustering enabled (OSS cluster API enabled), RS clustering enabled (OSS cluster API disabled):**<br>&ndash; single-shard | TS.CREATERULE, TS.DELETERULE<br><br>Users won't get a CROSSSLOT error. However, when clustering is enabled and the two specified keys are not in the same slot, users will get `(error) ERR TSDB: the key does not exist`. |"
    },
    {
      "id": "pipelines-transactions-and-scripts",
      "title": "Pipelines, transactions, and scripts",
      "role": "content",
      "text": "| Behavior | Operations |\n|----------|------------|\n| **ROS/RS clustering disabled:**<br>&ndash; cross-slot<br>**ROS clustering enabled, RS clustering enabled (OSS cluster API enabled):**<br>&ndash; single-slot<br>**RS clustering enabled (OSS cluster API disabled):**<br>&ndash; cross-slot (all shards) | Pipelines |\n| **ROS/RS clustering disabled:**<br>&ndash; cross-slot<br>**ROS clustering enabled, RS clustering enabled (OSS cluster API enabled), RS clustering enabled (OSS cluster API disabled):**<br>&ndash; single-slot | Keys in a `MULTI/EXEC` transaction<br>Keys in a Lua script executed using EVAL or EVALSHA |"
    },
    {
      "id": "examples-by-configuration",
      "title": "Examples by Configuration",
      "role": "example",
      "text": ""
    },
    {
      "id": "single-instance-no-clustering",
      "title": "Single Instance (No Clustering)",
      "role": "content",
      "text": "In a single Redis instance, all multi-key operations work without restrictions:\n\n[code example]"
    },
    {
      "id": "clustered-environments",
      "title": "Clustered Environments",
      "role": "content",
      "text": "In clustered setups, you need to consider slot distribution:\n\n[code example]"
    },
    {
      "id": "active-active-databases",
      "title": "Active-Active Databases",
      "role": "content",
      "text": "Active-Active databases have additional restrictions for write operations:\n\n[code example]"
    },
    {
      "id": "troubleshooting-multi-key-operations",
      "title": "Troubleshooting Multi-Key Operations",
      "role": "errors",
      "text": ""
    },
    {
      "id": "common-error-messages",
      "title": "Common Error Messages",
      "role": "content",
      "text": "- **CROSSSLOT**: Keys in request don't hash to the same slot\n- **MOVED**: Key has moved to a different node (during resharding)\n- **TRYAGAIN**: Operation temporarily unavailable (during migration)"
    },
    {
      "id": "solutions",
      "title": "Solutions",
      "role": "content",
      "text": "1. **Use hash tags** to group related keys\n2. **Redesign data model** to minimize cross-slot operations  \n3. **Check cluster state** during errors\n4. **Implement retry logic** for temporary failures"
    },
    {
      "id": "performance-considerations",
      "title": "Performance Considerations",
      "role": "performance",
      "text": "- **Single-slot operations** are fastest as they don't require coordination\n- **Cross-slot operations** may have higher latency due to internal routing\n- **Pattern commands** (KEYS, FLUSHALL) scan all shards and can be expensive\n- **Module operations** may have optimized cross-slot implementations\n\nChoose your Redis configuration and design your data model based on your multi-key operation requirements."
    }
  ],
  "examples": [
    {
      "id": "single-instance-no-clustering-ex0",
      "language": "redis",
      "code": "# Pipeline operations work across any keys\nPIPELINE\nSET user:1 \"Alice\"\nSET product:100 \"Widget\"\nGET user:1\nGET product:100\nEXEC\n\n# Transactions work with any keys\nMULTI\nSET counter:a 1\nSET counter:b 2\nINCR counter:a\nINCR counter:b\nEXEC",
      "section_id": "single-instance-no-clustering"
    },
    {
      "id": "clustered-environments-ex0",
      "language": "redis",
      "code": "# This may fail if keys are in different slots\nMSET user:1 \"Alice\" user:2 \"Bob\"\n\n# Use hash tags to ensure same slot\nMSET {users}:1 \"Alice\" {users}:2 \"Bob\"\n\n# Check which slot a key belongs to\nCLUSTER KEYSLOT user:1\nCLUSTER KEYSLOT {users}:1",
      "section_id": "clustered-environments"
    },
    {
      "id": "active-active-databases-ex0",
      "language": "redis",
      "code": "# Read operations can work across slots\nMGET user:1 user:2 product:100\n\n# Write operations must be in same slot\nMSET {data}:user:1 \"Alice\" {data}:user:2 \"Bob\"",
      "section_id": "active-active-databases"
    }
  ]
}
