{
  "schema_version": 2,
  "id": "commands/xadd",
  "title": "XADD",
  "url": "https://redis.io/docs/latest/commands/xadd/",
  "summary": "Appends a new message to a stream. Creates the key if it doesn't exist.",
  "since": "5.0.0",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-09-18T16:45:25+01:00",
  "page_type": "content",
  "content_hash": "d8269a877e7f4fa027b035a62f7d458e9860edc921356a863f0515353d67bc62",
  "sections": [
    {
      "id": "required-arguments",
      "title": "Required arguments",
      "role": "content",
      "text": "<details open>\n<summary><code>key</code></summary>\n\nThe name of the stream key.\n</details>\n\n<details open>\n<summary><code>id</code></summary>\n\nThe stream entry ID. Use `*` to auto-generate a unique ID, or specify a well-formed ID in the format `<ms>-<seq>` (for example, `1526919030474-55`).\n</details>\n\n<details open>\n<summary><code>field value [field value ...]</code></summary>\n\nOne or more field-value pairs that make up the stream entry. You must provide at least one field-value pair.\n</details>"
    },
    {
      "id": "optional-arguments",
      "title": "Optional arguments",
      "role": "parameters",
      "text": "<details open>\n<summary><code>NOMKSTREAM</code></summary>\n\nPrevents the creation of a new stream if the key does not exist. Available since Redis 6.2.0.\n</details>\n\n<details open>\n<summary><code>IDMPAUTO producer-id | IDMP producer-id idempotent-id</code></summary>\n\nEnables idempotent message processing (at-most-once production) to prevent duplicate entries. Available since Redis 8.6.\n\n- `IDMPAUTO producer-id`: Automatically generates a unique idempotent ID (iid) for the specified producer-id. Redis tracks this iid to prevent duplicate messages from the same producer-id.\n- `IDMP producer-id idempotent-id`: Uses the specified idempotent-id for the given producer-id. If this producer-id/idempotent-id combination was already used, the command returns the ID of the original entry instead of creating a duplicate.\n\nThe producer-id identifies the source of the message, while the idempotent-id ensures uniqueness within that producer-id's message stream. Redis maintains an internal map of recent producer-id/idempotent-id combinations to detect and prevent duplicates.\n\nBoth modes can only be specified when the entry ID is `*` (auto-generated).\n\nUse [`XCFGSET`](https://redis.io/docs/latest/commands/xcfgset) to configure how long idempotent IDs are retained (`IDMP-DURATION`) and the maximum number tracked per producer (`IDMP-MAXSIZE`).\n\nSee [Idempotent message processing](https://redis.io/docs/latest/develop/data-types/streams/idempotency) for more information.\n\n</details>\n\n<details open>\n<summary><code>KEEPREF | DELREF | ACKED</code></summary>\n\nSpecifies how to handle consumer group references when trimming. If there are no consumer groups, these arguments have no effect. Available since Redis 8.2.\n\nIf no option is specified, `KEEPREF` is used by default. Unlike the `XDELEX` and `XACKDEL` commands where one of these options is required, here they are optional to maintain backward compatibility:\n\n- `KEEPREF` (default): When trimming, removes entries from the stream according to the specified strategy (`MAXLEN` or `MINID`), regardless of whether they are referenced by any consumer groups, but preserves existing references to these entries in all consumer groups' PEL (Pending Entries List).\n- `DELREF`: When trimming, removes entries from the stream according to the specified strategy and also removes all references to these entries from all consumer groups' PEL.\n- `ACKED`: When trimming, only removes entries that were read and acknowledged by all consumer groups. Note that if the number of referenced entries is larger than `MAXLEN`, trimming will still stop at the limit.\n</details>\n\n<details open>\n<summary><code>MAXLEN | MINID [= | ~] threshold [LIMIT count]></code></summary>\n\nTrims the stream to maintain a specific size or remove old entries:\n\n<details open>\n<summary><code>MAXLEN | MINID</code></summary>\n\nThe trimming strategy:\n- `MAXLEN`: Evicts entries as long as the stream's length exceeds the specified threshold\n- `MINID`: Evicts entries with IDs lower than the specified threshold (available since Redis 6.2.0)\n</details>\n\n<details open>\n<summary><code>= | ~</code></summary>\n\nThe trimming operator:\n- `=`: Exact trimming (default) - trims to the exact threshold\n- `~`: Approximate trimming - more efficient, may leave slightly more entries than the threshold\n</details>\n\n<details open>\n<summary><code>threshold</code></summary>\n\nThe trimming threshold:\n- For `MAXLEN`: `threshold` is a non-negative integer specifying the maximum number of entries that may remain in the stream after trimming. Redis enforces this by removing the oldest entries - that is, the entries with the lowest stream IDs - so that only the newest entries are kept.\n- For `MINID`: `threshold` is a stream ID. All entries whose IDs are less than `threshold` are trimmed. All entries with IDs greater than or equal to `threshold` are kept.\n</details>\n\n<details open>\n<summary><code>LIMIT count</code></summary>\n\nLimits the number of entries to examine during trimming. Available since Redis 6.2.0. When not specified, Redis uses a default value of 100 * the number of entries in a macro node. Specifying 0 disables the limiting mechanism entirely.\n</details>\n\n</details>\n  \nEach entry consists of a list of field-value pairs.\nRedis stores the field-value pairs in the same order you provide them.\nCommands that read the stream, such as [`XRANGE`](https://redis.io/docs/latest/commands/xrange) or [`XREAD`](https://redis.io/docs/latest/commands/xread), return the fields and values in exactly the same order you added them with `XADD`.\n\n> [!NOTE]\n> `XADD` is the only Redis command that can add data to a stream. However,\n> other commands, such as [`XDEL`](https://redis.io/docs/latest/commands/xdel) and [`XTRIM`](https://redis.io/docs/latest/commands/xtrim), can\n> remove data from a stream."
    },
    {
      "id": "examples",
      "title": "Examples",
      "role": "example",
      "text": "Basic XADD: Add entries to a stream with auto-generated IDs, check stream the stream size, and read entries\n\n**Difficulty:** Beginner\n\n**Commands:** XADD, XLEN, XRANGE\n\n**Complexity:**\n- XADD: O(1)\n- XLEN: O(1)\n- XRANGE: O(N)\n\n**Available in:** Redis CLI, C#, Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), JavaScript (Node.js), PHP, Python, Ruby, Rust (Asynchronous), Rust (Synchronous)\n\n##### Redis CLI\n\n[code example]\n\n##### C#\n\n[code example]\n\n##### Go\n\n[code example]\n\n##### Java (Asynchronous - Lettuce)\n\n[code example]\n\n##### Java (Reactive - Lettuce)\n\n[code example]\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### PHP\n\n[code example]\n\n##### Python\n\n[code example]\n\n##### Ruby\n\n[code example]\n\n##### Rust (Asynchronous)\n\n[code example]\n\n##### Rust (Synchronous)\n\n[code example]"
    },
    {
      "id": "idempotent-message-processing-examples",
      "title": "Idempotent message processing examples",
      "role": "content",
      "text": "Idempotent XADD (Redis 8.6+): Use IDMP and IDMPAUTO for at-most-once message delivery, preventing duplicate entries\n\n**Difficulty:** Intermediate\n\n**Commands:** XADD, XCFGSET\n\n**Complexity:**\n- XADD: O(1)\n- XCFGSET: O(1)\n\n**Available in:** Redis CLI, C#, Go, Java (Asynchronous - Lettuce), Java (Reactive - Lettuce), Java (Synchronous - Jedis), JavaScript (Node.js), JavaScript (Node.js), PHP, Python, Ruby, Rust (Asynchronous), Rust (Synchronous)\n\n##### Redis CLI\n\n[code example]\n\n##### C#\n\n[code example]\n\n##### Go\n\n[code example]\n\n##### Java (Asynchronous - Lettuce)\n\n[code example]\n\n##### Java (Reactive - Lettuce)\n\n[code example]\n\n##### Java (Synchronous - Jedis)\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### JavaScript (Node.js)\n\n[code example]\n\n##### PHP\n\n[code example]\n\n##### Python\n\n[code example]\n\n##### Ruby\n\n[code example]\n\n##### Rust (Asynchronous)\n\n[code example]\n\n##### Rust (Synchronous)\n\n[code example]"
    },
    {
      "id": "details",
      "title": "Details",
      "role": "content",
      "text": ""
    },
    {
      "id": "specifying-a-stream-id-as-an-argument",
      "title": "Specifying a Stream ID as an argument",
      "role": "content",
      "text": "A stream entry ID identifies a specific entry inside a stream.\n\n`XADD` auto-generates a unique ID for you if you specify the `*` character (asterisk) as the ID argument. However, you can also specify a well-formed ID to add the new entry with that exact ID, though this is useful only in rare cases.\n\nSpecify IDs using two numbers separated by a `-` character:\n\n    1526919030474-55\n\nBoth numbers are 64-bit integers. When Redis auto-generates an ID, the\nfirst part is the Unix time in milliseconds of the Redis instance generating\nthe ID. The second part is a sequence number used to\ndistinguish IDs generated in the same millisecond.\n\nYou can also specify an incomplete ID that consists only of the milliseconds part, which Redis interprets as a zero value for the sequence part.\nTo have only the sequence part automatically generated, specify the milliseconds part followed by the `-` separator and the `*` character:\n\n[code example]\n\nRedis guarantees that IDs are always incremental: the ID of any entry you insert will be greater than any previous ID, so entries are totally ordered inside a stream. To guarantee this property, if the current top ID in the stream has a time greater than the current local time of the instance, Redis uses the top entry time instead and increments the sequence part of the ID. This may happen when, for instance, the local clock jumps backward, or after a failover when the new master has a different absolute time.\n\nWhen you specify an explicit ID to `XADD`, the minimum valid ID is `0-1`, and you *must* specify an ID that is greater than any other ID currently inside the stream, otherwise the command fails and returns an error. Specifying explicit IDs is usually useful only if you have another system generating unique IDs (for instance an SQL table) and you want the Redis stream IDs to match those from your other system."
    },
    {
      "id": "capped-streams",
      "title": "Capped streams",
      "role": "content",
      "text": "`XADD` incorporates the same semantics as the [`XTRIM`](https://redis.io/docs/latest/commands/xtrim) command - refer to its documentation page for more information.\nThis allows you to add new entries and keep the stream's size in check with a single call to `XADD`, effectively capping the stream with an arbitrary threshold.\nAlthough exact trimming is possible and is the default, due to the internal representation of streams, it is more efficient to add an entry and trim the stream with `XADD` using **almost exact** trimming (the `~` argument).\n\nFor example, calling `XADD` in the following form:\n\n    XADD mystream MAXLEN ~ 1000 * ... entry fields here ...\n\nThis adds a new entry but also evicts old entries so that the stream contains only 1000 entries, or at most a few tens more."
    },
    {
      "id": "additional-information-about-streams",
      "title": "Additional information about streams",
      "role": "content",
      "text": "For more information about Redis streams, see the\n[introduction to Redis Streams document](https://redis.io/docs/latest/develop/data-types/streams)."
    },
    {
      "id": "redis-software-and-redis-cloud-compatibility",
      "title": "Redis Software and Redis Cloud compatibility",
      "role": "content",
      "text": "| Redis<br />Software | Redis<br />Cloud | <span style=\"min-width: 9em; display: table-cell\">Notes</span> |\n|:----------------------|:-----------------|:------|\n| <span title=\"Supported\">&#x2705; Standard</span><br /><span title=\"Supported\"><nobr>&#x2705; Active-Active</nobr></span> | <span title=\"Supported\">&#x2705; Standard</span><br /><span title=\"Supported\"><nobr>&#x2705; Active-Active</nobr></span> |  |"
    },
    {
      "id": "return-information",
      "title": "Return information",
      "role": "returns",
      "text": "**RESP2:**\n\nOne of the following:\n* [Bulk string reply](../../develop/reference/protocol-spec#bulk-strings): The ID of the added entry. The ID is the one automatically generated if an asterisk (`*`) is passed as the _id_ argument, otherwise the command just returns the same ID specified by the user during insertion. When using IDMP and a duplicate is detected, returns the ID of the original entry.\n* [Nil reply](../../develop/reference/protocol-spec#bulk-strings): if the NOMKSTREAM option is given and the key doesn't exist.\n\n**RESP3:**\n\nOne of the following:\n* [Bulk string reply](../../develop/reference/protocol-spec#bulk-strings): The ID of the added entry. The ID is the one automatically generated if an asterisk (`*`) is passed as the _id_ argument, otherwise the command just returns the same ID specified by the user during insertion. When using IDMP and a duplicate is detected, returns the ID of the original entry.\n* [Null reply](../../develop/reference/protocol-spec#nulls): if the NOMKSTREAM option is given and the key doesn't exist."
    }
  ],
  "examples": [
    {
      "id": "examples-ex0",
      "language": "plaintext",
      "code": "> XADD mystream * name Sara surname OConnor\n\"4378417975-0\"\n> XADD mystream * field1 value1 field2 value2 field3 value3\n\"4378417976-0\"\n> XLEN mystream\n(integer) 2\n> XRANGE mystream - +\n1) 1) \"1774378417975-0\"\n   2) 1) \"name\"\n      2) \"Sara\"\n      3) \"surname\"\n      4) \"OConnor\"\n2) 1) \"1774378417976-0\"\n   2) 1) \"field1\"\n      2) \"value1\"\n      3) \"field2\"\n      4) \"value2\"\n      5) \"field3\"\n      6) \"value3\"",
      "section_id": "examples"
    },
    {
      "id": "examples-ex1",
      "language": "csharp",
      "code": "var res1 = db.StreamAdd(\"mystream\", new NameValueEntry[] {\n            new NameValueEntry(\"name\", \"Sara\"),\n            new NameValueEntry(\"surname\", \"OConnor\")\n        });\n        Console.WriteLine(res1);  // >>> 1726055713866-0\n\n        var res2 = db.StreamAdd(\"mystream\", new NameValueEntry[] {\n            new NameValueEntry(\"field1\", \"value1\"),\n            new NameValueEntry(\"field2\", \"value2\"),\n            new NameValueEntry(\"field3\", \"value3\")\n        });\n        Console.WriteLine(res2);  // >>> 1726055713866-1\n\n        var res3 = db.StreamLength(\"mystream\");\n        Console.WriteLine(res3);  // >>> 2\n\n        var res4 = db.StreamRange(\"mystream\", \"-\", \"+\");\n        foreach (var entry in res4)\n        {\n            Console.WriteLine($\"{entry.Id} -> {string.Join(\", \", entry.Values.Select(v => $\"{v.Name}={v.Value}\"))}\");\n        }\n        // >>> 1726055713866-0 -> name=Sara, surname=OConnor\n        // >>> 1726055713866-1 -> field1=value1, field2=value2, field3=value3",
      "section_id": "examples"
    },
    {
      "id": "examples-ex2",
      "language": "go",
      "code": "res1, err := rdb.XAdd(ctx, &redis.XAddArgs{\n\t\tStream: \"mystream\",\n\t\tValues: map[string]interface{}{\n\t\t\t\"name\":    \"Sara\",\n\t\t\t\"surname\": \"OConnor\",\n\t\t},\n\t}).Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(res1 != \"\") // >>> true\n\n\tres2, err := rdb.XAdd(ctx, &redis.XAddArgs{\n\t\tStream: \"mystream\",\n\t\tValues: map[string]interface{}{\n\t\t\t\"field1\": \"value1\",\n\t\t\t\"field2\": \"value2\",\n\t\t\t\"field3\": \"value3\",\n\t\t},\n\t}).Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(res2 != \"\") // >>> true\n\n\tres3, err := rdb.XLen(ctx, \"mystream\").Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(res3) // >>> 2\n\n\tres4, err := rdb.XRange(ctx, \"mystream\", \"-\", \"+\").Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(len(res4)) // >>> 2",
      "section_id": "examples"
    },
    {
      "id": "examples-ex3",
      "language": "java",
      "code": "Map<String, String> entry1 = new HashMap<>();\n            entry1.put(\"name\", \"Sara\");\n            entry1.put(\"surname\", \"OConnor\");\n\n            CompletableFuture<Void> xadd1Ops = asyncCommands.xadd(\"mystream\", entry1)\n                .thenCompose(res1 -> {\n                    System.out.println(res1); // >>> 1726055713866-0\n                    Map<String, String> entry2 = new HashMap<>();\n                    entry2.put(\"field1\", \"value1\");\n                    entry2.put(\"field2\", \"value2\");\n                    entry2.put(\"field3\", \"value3\");\n                    return asyncCommands.xadd(\"mystream\", entry2);\n                })\n                .thenCompose(res2 -> {\n                    System.out.println(res2); // >>> 1726055713866-1\n                    return asyncCommands.xlen(\"mystream\");\n                })\n                .thenCompose(res3 -> {\n                    System.out.println(res3); // >>> 2\n                    return asyncCommands.xrange(\"mystream\", Range.unbounded());\n                })\n                .thenAccept(res4 -> {\n                    for (var entry : res4) {\n                        System.out.println(entry.getId() + \" -> \" + entry.getBody());\n                    }\n                    // >>> 1726055713866-0 -> {name=Sara, surname=OConnor}\n                    // >>> 1726055713866-1 -> {field1=value1, field2=value2, field3=value3}\n                })\n                .toCompletableFuture();\n\n            xadd1Ops.join();",
      "section_id": "examples"
    },
    {
      "id": "examples-ex4",
      "language": "java",
      "code": "Map<String, String> entry1 = new HashMap<>();\n            entry1.put(\"name\", \"Sara\");\n            entry1.put(\"surname\", \"OConnor\");\n\n            Mono<String> addEntry1 = reactiveCommands.xadd(\"mystream\", entry1)\n                .doOnNext(res1 -> {\n                    System.out.println(res1); // >>> 1726055713866-0\n                });\n\n            addEntry1.block();\n\n            Map<String, String> entry2 = new HashMap<>();\n            entry2.put(\"field1\", \"value1\");\n            entry2.put(\"field2\", \"value2\");\n            entry2.put(\"field3\", \"value3\");\n\n            Mono<String> addEntry2 = reactiveCommands.xadd(\"mystream\", entry2)\n                .doOnNext(res2 -> {\n                    System.out.println(res2); // >>> 1726055713866-1\n                });\n\n            addEntry2.block();\n\n            Mono<Long> getLen = reactiveCommands.xlen(\"mystream\")\n                .doOnNext(res3 -> {\n                    System.out.println(res3); // >>> 2\n                });\n\n            getLen.block();\n\n            Mono<List<StreamMessage<String, String>>> getRange = reactiveCommands\n                .xrange(\"mystream\", Range.unbounded())\n                .collectList()\n                .doOnNext(res4 -> {\n                    for (var entry : res4) {\n                        System.out.println(entry.getId() + \" -> \" + entry.getBody());\n                    }\n                    // >>> 1726055713866-0 -> {name=Sara, surname=OConnor}\n                    // >>> 1726055713866-1 -> {field1=value1, field2=value2, field3=value3}\n                });\n\n            getRange.block();",
      "section_id": "examples"
    },
    {
      "id": "examples-ex5",
      "language": "java",
      "code": "Map<String, String> entry1 = new HashMap<>();\n        entry1.put(\"name\", \"Sara\");\n        entry1.put(\"surname\", \"OConnor\");\n        StreamEntryID res1 = jedis.xadd(\"mystream\", entry1, XAddParams.xAddParams());\n        System.out.println(res1); // >>> 1726055713866-0\n\n        Map<String, String> entry2 = new HashMap<>();\n        entry2.put(\"field1\", \"value1\");\n        entry2.put(\"field2\", \"value2\");\n        entry2.put(\"field3\", \"value3\");\n        StreamEntryID res2 = jedis.xadd(\"mystream\", entry2, XAddParams.xAddParams());\n        System.out.println(res2); // >>> 1726055713866-1\n\n        long res3 = jedis.xlen(\"mystream\");\n        System.out.println(res3); // >>> 2\n\n        List<StreamEntry> res4 = jedis.xrange(\"mystream\", \"-\", \"+\");\n        for (StreamEntry entry : res4) {\n            System.out.println(entry.getID() + \" -> \" + entry.getFields());\n        }\n        // >>> 1726055713866-0 -> {name=Sara, surname=OConnor}\n        // >>> 1726055713866-1 -> {field1=value1, field2=value2, field3=value3}",
      "section_id": "examples"
    },
    {
      "id": "examples-ex6",
      "language": "javascript",
      "code": "const res1 = await client.xAdd('mystream', '*', {\n  'name': 'Sara',\n  'surname': 'OConnor'\n});\nconsole.log(res1); // >>> 1726055713866-0\n\nconst res2 = await client.xAdd('mystream', '*', {\n  'field1': 'value1',\n  'field2': 'value2',\n  'field3': 'value3'\n});\nconsole.log(res2); // >>> 1726055713866-1\n\nconst res3 = await client.xLen('mystream');\nconsole.log(res3); // >>> 2\n\nconst res4 = await client.xRange('mystream', '-', '+');\nconsole.log(res4);\n// >>> [\n//   { id: '1726055713866-0', message: { name: 'Sara', surname: 'OConnor' } },\n//   { id: '1726055713866-1', message: { field1: 'value1', field2: 'value2', field3: 'value3' } }\n// ]",
      "section_id": "examples"
    },
    {
      "id": "examples-ex7",
      "language": "javascript",
      "code": "const res1 = await redis.xadd('mystream', '*', 'name', 'Sara', 'surname', 'OConnor');\nconsole.log(res1); // >>> 1726055713866-0\n\nconst res2 = await redis.xadd('mystream', '*', 'field1', 'value1', 'field2', 'value2', 'field3', 'value3');\nconsole.log(res2); // >>> 1726055713866-1\n\nconst res3 = await redis.xlen('mystream');\nconsole.log(res3); // >>> 2\n\nconst res4 = await redis.xrange('mystream', '-', '+');\nconsole.log(res4);\n// >>> [\n//   ['1726055713866-0', ['name', 'Sara', 'surname', 'OConnor']],\n//   ['1726055713866-1', ['field1', 'value1', 'field2', 'value2', 'field3', 'value3']]\n// ]",
      "section_id": "examples"
    },
    {
      "id": "examples-ex8",
      "language": "javascript",
      "code": "const res1 = await client.xAdd('mystream', '*', {\n  'name': 'Sara',\n  'surname': 'OConnor'\n});\nconsole.log(res1); // >>> 1726055713866-0\n\nconst res2 = await client.xAdd('mystream', '*', {\n  'field1': 'value1',\n  'field2': 'value2',\n  'field3': 'value3'\n});\nconsole.log(res2); // >>> 1726055713866-1\n\nconst res3 = await client.xLen('mystream');\nconsole.log(res3); // >>> 2\n\nconst res4 = await client.xRange('mystream', '-', '+');\nconsole.log(res4);\n// >>> [\n//   { id: '1726055713866-0', message: { name: 'Sara', surname: 'OConnor' } },\n//   { id: '1726055713866-1', message: { field1: 'value1', field2: 'value2', field3: 'value3' } }\n// ]",
      "section_id": "examples"
    },
    {
      "id": "examples-ex9",
      "language": "javascript",
      "code": "const res1 = await redis.xadd('mystream', '*', 'name', 'Sara', 'surname', 'OConnor');\nconsole.log(res1); // >>> 1726055713866-0\n\nconst res2 = await redis.xadd('mystream', '*', 'field1', 'value1', 'field2', 'value2', 'field3', 'value3');\nconsole.log(res2); // >>> 1726055713866-1\n\nconst res3 = await redis.xlen('mystream');\nconsole.log(res3); // >>> 2\n\nconst res4 = await redis.xrange('mystream', '-', '+');\nconsole.log(res4);\n// >>> [\n//   ['1726055713866-0', ['name', 'Sara', 'surname', 'OConnor']],\n//   ['1726055713866-1', ['field1', 'value1', 'field2', 'value2', 'field3', 'value3']]\n// ]",
      "section_id": "examples"
    },
    {
      "id": "examples-ex10",
      "language": "php",
      "code": "$res1 = $redis->xadd('mystream', ['name' => 'Sara', 'surname' => 'OConnor']);\n        echo $res1 . PHP_EOL; // >>> 1726055713866-0\n\n        $res2 = $redis->xadd('mystream', ['field1' => 'value1', 'field2' => 'value2', 'field3' => 'value3']);\n        echo $res2 . PHP_EOL; // >>> 1726055713866-1\n\n        $res3 = $redis->xlen('mystream');\n        echo $res3 . PHP_EOL; // >>> 2\n\n        $res4 = $redis->xrange('mystream', '-', '+');\n        foreach ($res4 as $id => $fields) {\n            echo $id . ' -> ' . json_encode($fields) . PHP_EOL;\n        }\n        // >>> 1726055713866-0 -> {\"name\":\"Sara\",\"surname\":\"OConnor\"}\n        // >>> 1726055713866-1 -> {\"field1\":\"value1\",\"field2\":\"value2\",\"field3\":\"value3\"}",
      "section_id": "examples"
    },
    {
      "id": "examples-ex11",
      "language": "python",
      "code": "res1 = r.xadd(\"mystream\", {\"name\": \"Sara\", \"surname\": \"OConnor\"})\nprint(res1)  # >>> 1726055713866-0\n\nres2 = r.xadd(\"mystream\", {\"field1\": \"value1\", \"field2\": \"value2\", \"field3\": \"value3\"})\nprint(res2)  # >>> 1726055713866-1\n\nres3 = r.xlen(\"mystream\")\nprint(res3)  # >>> 2\n\nres4 = r.xrange(\"mystream\", \"-\", \"+\")\nprint(res4)\n# >>> [\n#   ('1726055713866-0', {'name': 'Sara', 'surname': 'OConnor'}),\n#   ('1726055713866-1', {'field1': 'value1', 'field2': 'value2', 'field3': 'value3'})\n# ]",
      "section_id": "examples"
    },
    {
      "id": "examples-ex12",
      "language": "ruby",
      "code": "res1 = r.xadd('mystream', { 'name' => 'Sara', 'surname' => 'OConnor' })\nputs res1 # >>> 1726055713866-0\n\nres2 = r.xadd('mystream', { 'field1' => 'value1', 'field2' => 'value2', 'field3' => 'value3' })\nputs res2 # >>> 1726055713866-1\n\nres3 = r.xlen('mystream')\nputs res3 # >>> 2\n\nres4 = r.xrange('mystream', '-', '+')\nputs res4.inspect\n# >>> [\n#   [\"1726055713866-0\", {\"name\"=>\"Sara\", \"surname\"=>\"OConnor\"}],\n#   [\"1726055713866-1\", {\"field1\"=>\"value1\", \"field2\"=>\"value2\", \"field3\"=>\"value3\"}]\n# ]",
      "section_id": "examples"
    },
    {
      "id": "examples-ex13",
      "language": "rust",
      "code": "let client = redis::Client::open(\"redis://127.0.0.1/\").unwrap();\n        let mut con = client.get_multiplexed_async_connection().await.unwrap();\n\n\n        let res1: String = redis::cmd(\"XADD\")\n            .arg(\"mystream\")\n            .arg(\"*\")\n            .arg(\"name\")\n            .arg(\"Sara\")\n            .arg(\"surname\")\n            .arg(\"OConnor\")\n            .query_async(&mut con)\n            .await\n            .unwrap();\n        println!(\"XADD result: {}\", res1); // >>> 1726055713866-0\n\n        let res2: String = redis::cmd(\"XADD\")\n            .arg(\"mystream\")\n            .arg(\"*\")\n            .arg(\"field1\")\n            .arg(\"value1\")\n            .arg(\"field2\")\n            .arg(\"value2\")\n            .arg(\"field3\")\n            .arg(\"value3\")\n            .query_async(&mut con)\n            .await\n            .unwrap();\n        println!(\"XADD result: {}\", res2); // >>> 1726055713866-1\n\n        let res3: i64 = con.xlen(\"mystream\").await.unwrap();\n        println!(\"XLEN result: {}\", res3); // >>> 2\n\n        let res4: redis::streams::StreamRangeReply = con.xrange_all(\"mystream\").await.unwrap();\n        for entry in &res4.ids {\n            println!(\"{} -> {:?}\", entry.id, entry.map);\n        }\n        // >>> 1726055713866-0 -> {\"name\": \"Sara\", \"surname\": \"OConnor\"}\n        // >>> 1726055713866-1 -> {\"field1\": \"value1\", \"field2\": \"value2\", \"field3\": \"value3\"}",
      "section_id": "examples"
    },
    {
      "id": "examples-ex14",
      "language": "rust",
      "code": "let client = redis::Client::open(\"redis://127.0.0.1/\").unwrap();\n        let mut con = client.get_connection().unwrap();\n\n\n        let res1: String = redis::cmd(\"XADD\")\n            .arg(\"mystream\")\n            .arg(\"*\")\n            .arg(\"name\")\n            .arg(\"Sara\")\n            .arg(\"surname\")\n            .arg(\"OConnor\")\n            .query(&mut con)\n            .unwrap();\n        println!(\"XADD result: {}\", res1); // >>> 1726055713866-0\n\n        let res2: String = redis::cmd(\"XADD\")\n            .arg(\"mystream\")\n            .arg(\"*\")\n            .arg(\"field1\")\n            .arg(\"value1\")\n            .arg(\"field2\")\n            .arg(\"value2\")\n            .arg(\"field3\")\n            .arg(\"value3\")\n            .query(&mut con)\n            .unwrap();\n        println!(\"XADD result: {}\", res2); // >>> 1726055713866-1\n\n        let res3: i64 = con.xlen(\"mystream\").unwrap();\n        println!(\"XLEN result: {}\", res3); // >>> 2\n\n        let res4: redis::streams::StreamRangeReply = con.xrange_all(\"mystream\").unwrap();\n        for entry in &res4.ids {\n            println!(\"{} -> {:?}\", entry.id, entry.map);\n        }\n        // >>> 1726055713866-0 -> {\"name\": \"Sara\", \"surname\": \"OConnor\"}\n        // >>> 1726055713866-1 -> {\"field1\": \"value1\", \"field2\": \"value2\", \"field3\": \"value3\"}",
      "section_id": "examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex0",
      "language": "plaintext",
      "code": "> XADD mystream IDMP producer1 msg1 * field value\n\"1774378417976-0\"\n> XADD mystream IDMP producer1 msg1 * field different_value\n\"1774378417976-0\"\n> XADD mystream IDMPAUTO producer2 * field value\n\"1774378417977-0\"\n> XADD mystream IDMPAUTO producer2 * field value\n\"1774378417977-0\"\n> XCFGSET mystream IDMP-DURATION 300 IDMP-MAXSIZE 1000\nOK",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex1",
      "language": "csharp",
      "code": "// Note: IDMP is a Redis 8.6 feature - using Execute for raw command access\n        var res5 = db.Execute(\"XADD\", \"mystream\", \"IDMP\", \"producer1\", \"msg1\", \"*\", \"field\", \"value\");\n        Console.WriteLine(res5);  // >>> 1726055713867-0\n\n        // Attempting to add the same message again with IDMP returns the original entry ID\n        var res6 = db.Execute(\"XADD\", \"mystream\", \"IDMP\", \"producer1\", \"msg1\", \"*\", \"field\", \"different_value\");\n        Console.WriteLine(res6);  // >>> 1726055713867-0 (same ID as res5, message was deduplicated)\n\n        var res7 = db.Execute(\"XADD\", \"mystream\", \"IDMPAUTO\", \"producer2\", \"*\", \"field\", \"value\");\n        Console.WriteLine(res7);  // >>> 1726055713867-1\n\n        // Auto-generated idempotent ID prevents duplicates for same producer+content\n        var res8 = db.Execute(\"XADD\", \"mystream\", \"IDMPAUTO\", \"producer2\", \"*\", \"field\", \"value\");\n        Console.WriteLine(res8);  // >>> 1726055713867-1 (same ID as res7, duplicate detected)\n\n        // Configure idempotent message processing settings\n        var res9 = db.Execute(\"XCFGSET\", \"mystream\", \"IDMP-DURATION\", \"300\", \"IDMP-MAXSIZE\", \"1000\");\n        Console.WriteLine(res9);  // >>> OK",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex2",
      "language": "go",
      "code": "res5, err := rdb.XAdd(ctx, &redis.XAddArgs{\n\t\tStream:       \"mystream\",\n\t\tValues:       map[string]interface{}{\"field\": \"value\"},\n\t\tProducerID:   \"producer1\",\n\t\tIdempotentID: \"msg1\",\n\t}).Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(res5 != \"\") // >>> true\n\n\t// Attempting to add the same message again with IDMP returns the original entry ID\n\tres6, err := rdb.XAdd(ctx, &redis.XAddArgs{\n\t\tStream:       \"mystream\",\n\t\tValues:       map[string]interface{}{\"field\": \"different_value\"},\n\t\tProducerID:   \"producer1\",\n\t\tIdempotentID: \"msg1\",\n\t}).Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(res5 == res6) // >>> true (same ID, message was deduplicated)\n\n\tres7, err := rdb.XAdd(ctx, &redis.XAddArgs{\n\t\tStream:         \"mystream\",\n\t\tValues:         map[string]interface{}{\"field\": \"value\"},\n\t\tProducerID:     \"producer2\",\n\t\tIdempotentAuto: true,\n\t}).Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(res7 != \"\") // >>> true\n\n\t// Auto-generated idempotent ID prevents duplicates for same producer+content\n\tres8, err := rdb.XAdd(ctx, &redis.XAddArgs{\n\t\tStream:         \"mystream\",\n\t\tValues:         map[string]interface{}{\"field\": \"value\"},\n\t\tProducerID:     \"producer2\",\n\t\tIdempotentAuto: true,\n\t}).Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(res7 == res8) // >>> true (same ID, duplicate detected)\n\n\t// Configure idempotent message processing settings\n\tres9, err := rdb.XCfgSet(ctx, &redis.XCfgSetArgs{\n\t\tStream:   \"mystream\",\n\t\tDuration: 300,  // 300 seconds\n\t\tMaxSize:  1000, // 1000 idempotent IDs\n\t}).Result()\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Println(res9) // >>> OK",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex3",
      "language": "java",
      "code": "Map<String, String> idmpEntry1 = new HashMap<>();\n            idmpEntry1.put(\"field\", \"value\");\n\n            CompletableFuture<Void> xadd2Ops = asyncCommands.xadd(\n                    \"mystream\",\n                    XAddArgs.Builder.idmp(\"producer1\", \"msg1\"),\n                    idmpEntry1)\n                .thenCompose(res5 -> {\n                    System.out.println(res5); // >>> 1726055713867-0\n                    // Attempting to add same message again with IDMP returns original entry ID\n                    Map<String, String> idmpEntry2 = new HashMap<>();\n                    idmpEntry2.put(\"field\", \"different_value\");\n                    return asyncCommands.xadd(\"mystream\",\n                        XAddArgs.Builder.idmp(\"producer1\", \"msg1\"), idmpEntry2);\n                })\n                .thenCompose(res6 -> {\n                    System.out.println(res6); // >>> 1726055713867-0 (deduplicated)\n                    Map<String, String> idmpAutoEntry1 = new HashMap<>();\n                    idmpAutoEntry1.put(\"field\", \"value\");\n                    return asyncCommands.xadd(\"mystream\",\n                        XAddArgs.Builder.idmpAuto(\"producer2\"), idmpAutoEntry1);\n                })\n                .thenCompose(res7 -> {\n                    System.out.println(res7); // >>> 1726055713867-1\n                    Map<String, String> idmpAutoEntry2 = new HashMap<>();\n                    idmpAutoEntry2.put(\"field\", \"value\");\n                    return asyncCommands.xadd(\"mystream\",\n                        XAddArgs.Builder.idmpAuto(\"producer2\"), idmpAutoEntry2);\n                })\n                .thenAccept(res8 -> {\n                    System.out.println(res8); // >>> 1726055713867-1 (duplicate detected)\n                })\n                .toCompletableFuture();\n\n            xadd2Ops.join();",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex4",
      "language": "java",
      "code": "Map<String, String> idmpEntry1 = new HashMap<>();\n            idmpEntry1.put(\"field\", \"value\");\n\n            Mono<String> addIdmp1 = reactiveCommands.xadd(\n                    \"mystream\",\n                    XAddArgs.Builder.idmp(\"producer1\", \"msg1\"),\n                    idmpEntry1)\n                .doOnNext(res5 -> {\n                    System.out.println(res5); // >>> 1726055713867-0\n                });\n\n            addIdmp1.block();\n\n            // Attempting to add the same message again with IDMP returns the original entry ID\n            Map<String, String> idmpEntry2 = new HashMap<>();\n            idmpEntry2.put(\"field\", \"different_value\");\n\n            Mono<String> addIdmp2 = reactiveCommands.xadd(\n                    \"mystream\",\n                    XAddArgs.Builder.idmp(\"producer1\", \"msg1\"),\n                    idmpEntry2)\n                .doOnNext(res6 -> {\n                    System.out.println(res6); // >>> 1726055713867-0 (deduplicated)\n                });\n\n            addIdmp2.block();\n\n            Map<String, String> idmpAutoEntry1 = new HashMap<>();\n            idmpAutoEntry1.put(\"field\", \"value\");\n\n            Mono<String> addIdmpAuto1 = reactiveCommands.xadd(\n                    \"mystream\",\n                    XAddArgs.Builder.idmpAuto(\"producer2\"),\n                    idmpAutoEntry1)\n                .doOnNext(res7 -> {\n                    System.out.println(res7); // >>> 1726055713867-1\n                });\n\n            addIdmpAuto1.block();\n\n            // Auto-generated idempotent ID prevents duplicates for same producer+content\n            Map<String, String> idmpAutoEntry2 = new HashMap<>();\n            idmpAutoEntry2.put(\"field\", \"value\");\n\n            Mono<String> addIdmpAuto2 = reactiveCommands.xadd(\n                    \"mystream\",\n                    XAddArgs.Builder.idmpAuto(\"producer2\"),\n                    idmpAutoEntry2)\n                .doOnNext(res8 -> {\n                    System.out.println(res8); // >>> 1726055713867-1 (duplicate detected)\n                });\n\n            addIdmpAuto2.block();",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex5",
      "language": "java",
      "code": "Map<String, String> idmpEntry1 = new HashMap<>();\n        idmpEntry1.put(\"field\", \"value\");\n        StreamEntryID res5 = jedis.xadd(\"mystream\", idmpEntry1, \n            XAddParams.xAddParams().idmp(\"producer1\", \"msg1\"));\n        System.out.println(res5); // >>> 1726055713867-0\n\n        // Attempting to add the same message again with IDMP returns the original entry ID\n        Map<String, String> idmpEntry2 = new HashMap<>();\n        idmpEntry2.put(\"field\", \"different_value\");\n        StreamEntryID res6 = jedis.xadd(\"mystream\", idmpEntry2,\n            XAddParams.xAddParams().idmp(\"producer1\", \"msg1\"));\n        System.out.println(res6); // >>> 1726055713867-0 (same ID as res5, message was deduplicated)\n\n        Map<String, String> idmpAutoEntry1 = new HashMap<>();\n        idmpAutoEntry1.put(\"field\", \"value\");\n        StreamEntryID res7 = jedis.xadd(\"mystream\", idmpAutoEntry1,\n            XAddParams.xAddParams().idmpAuto(\"producer2\"));\n        System.out.println(res7); // >>> 1726055713867-1\n\n        // Auto-generated idempotent ID prevents duplicates for same producer+content\n        Map<String, String> idmpAutoEntry2 = new HashMap<>();\n        idmpAutoEntry2.put(\"field\", \"value\");\n        StreamEntryID res8 = jedis.xadd(\"mystream\", idmpAutoEntry2,\n            XAddParams.xAddParams().idmpAuto(\"producer2\"));\n        System.out.println(res8); // >>> 1726055713867-1 (same ID as res7, duplicate detected)\n\n        // Configure idempotent message processing settings\n        String res9 = jedis.xcfgset(\"mystream\",\n            XCfgSetParams.xCfgSetParams().idmpDuration(300).idmpMaxsize(1000));\n        System.out.println(res9); // >>> OK",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex6",
      "language": "javascript",
      "code": "const res5 = await client.xAdd('mystream', '*', { 'field': 'value' }, {\n  IDMP: { pid: 'producer1', iid: 'msg1' }\n});\nconsole.log(res5); // >>> 1726055713867-0\n\n// Attempting to add the same message again with IDMP returns the original entry ID\nconst res6 = await client.xAdd('mystream', '*', { 'field': 'different_value' }, {\n  IDMP: { pid: 'producer1', iid: 'msg1' }\n});\nconsole.log(res6); // >>> 1726055713867-0 (same ID as res5, message was deduplicated)\n\nconst res7 = await client.xAdd('mystream', '*', { 'field': 'value' }, {\n  IDMPAUTO: { pid: 'producer2' }\n});\nconsole.log(res7); // >>> 1726055713867-1\n\n// Auto-generated idempotent ID prevents duplicates for same producer+content\nconst res8 = await client.xAdd('mystream', '*', { 'field': 'value' }, {\n  IDMPAUTO: { pid: 'producer2' }\n});\nconsole.log(res8); // >>> 1726055713867-1 (same ID as res7, duplicate detected)\n\n// Configure idempotent message processing settings\nconst res9 = await client.xCfgSet('mystream', {\n  IDMP_DURATION: 300,\n  IDMP_MAXSIZE: 1000\n});\nconsole.log(res9); // >>> OK",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex7",
      "language": "javascript",
      "code": "const res5 = await redis.call('XADD', 'mystream', 'IDMP', 'producer1', 'msg1', '*', 'field', 'value');\nconsole.log(res5); // >>> 1726055713867-0\n\n// Attempting to add the same message again with IDMP returns the original entry ID\nconst res6 = await redis.call('XADD', 'mystream', 'IDMP', 'producer1', 'msg1', '*', 'field', 'different_value');\nconsole.log(res6); // >>> 1726055713867-0 (same ID as res5, message was deduplicated)\n\nconst res7 = await redis.call('XADD', 'mystream', 'IDMPAUTO', 'producer2', '*', 'field', 'value');\nconsole.log(res7); // >>> 1726055713867-1\n\n// Auto-generated idempotent ID prevents duplicates for same producer+content\nconst res8 = await redis.call('XADD', 'mystream', 'IDMPAUTO', 'producer2', '*', 'field', 'value');\nconsole.log(res8); // >>> 1726055713867-1 (same ID as res7, duplicate detected)\n\n// Configure idempotent message processing settings\nconst res9 = await redis.call('XCFGSET', 'mystream', 'IDMP-DURATION', 300, 'IDMP-MAXSIZE', 1000);\nconsole.log(res9); // >>> OK",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex8",
      "language": "javascript",
      "code": "const res5 = await client.xAdd('mystream', '*', { 'field': 'value' }, {\n  IDMP: { pid: 'producer1', iid: 'msg1' }\n});\nconsole.log(res5); // >>> 1726055713867-0\n\n// Attempting to add the same message again with IDMP returns the original entry ID\nconst res6 = await client.xAdd('mystream', '*', { 'field': 'different_value' }, {\n  IDMP: { pid: 'producer1', iid: 'msg1' }\n});\nconsole.log(res6); // >>> 1726055713867-0 (same ID as res5, message was deduplicated)\n\nconst res7 = await client.xAdd('mystream', '*', { 'field': 'value' }, {\n  IDMPAUTO: { pid: 'producer2' }\n});\nconsole.log(res7); // >>> 1726055713867-1\n\n// Auto-generated idempotent ID prevents duplicates for same producer+content\nconst res8 = await client.xAdd('mystream', '*', { 'field': 'value' }, {\n  IDMPAUTO: { pid: 'producer2' }\n});\nconsole.log(res8); // >>> 1726055713867-1 (same ID as res7, duplicate detected)\n\n// Configure idempotent message processing settings\nconst res9 = await client.xCfgSet('mystream', {\n  IDMP_DURATION: 300,\n  IDMP_MAXSIZE: 1000\n});\nconsole.log(res9); // >>> OK",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex9",
      "language": "javascript",
      "code": "const res5 = await redis.call('XADD', 'mystream', 'IDMP', 'producer1', 'msg1', '*', 'field', 'value');\nconsole.log(res5); // >>> 1726055713867-0\n\n// Attempting to add the same message again with IDMP returns the original entry ID\nconst res6 = await redis.call('XADD', 'mystream', 'IDMP', 'producer1', 'msg1', '*', 'field', 'different_value');\nconsole.log(res6); // >>> 1726055713867-0 (same ID as res5, message was deduplicated)\n\nconst res7 = await redis.call('XADD', 'mystream', 'IDMPAUTO', 'producer2', '*', 'field', 'value');\nconsole.log(res7); // >>> 1726055713867-1\n\n// Auto-generated idempotent ID prevents duplicates for same producer+content\nconst res8 = await redis.call('XADD', 'mystream', 'IDMPAUTO', 'producer2', '*', 'field', 'value');\nconsole.log(res8); // >>> 1726055713867-1 (same ID as res7, duplicate detected)\n\n// Configure idempotent message processing settings\nconst res9 = await redis.call('XCFGSET', 'mystream', 'IDMP-DURATION', 300, 'IDMP-MAXSIZE', 1000);\nconsole.log(res9); // >>> OK",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex10",
      "language": "php",
      "code": "$res5 = $redis->xadd('mystream', ['field' => 'value'], '*', ['idmp' => ['producer1', 'msg1']]);\n        echo $res5 . PHP_EOL; // >>> 1726055713867-0\n\n        // Attempting to add the same message again with IDMP returns the original entry ID\n        $res6 = $redis->xadd('mystream', ['field' => 'different_value'], '*', ['idmp' => ['producer1', 'msg1']]);\n        echo $res6 . PHP_EOL; // >>> 1726055713867-0 (same ID as res5, message was deduplicated)\n\n        $res7 = $redis->xadd('mystream', ['field' => 'value'], '*', ['idmpauto' => 'producer2']);\n        echo $res7 . PHP_EOL; // >>> 1726055713867-1\n\n        // Auto-generated idempotent ID prevents duplicates for same producer+content\n        $res8 = $redis->xadd('mystream', ['field' => 'value'], '*', ['idmpauto' => 'producer2']);\n        echo $res8 . PHP_EOL; // >>> 1726055713867-1 (same ID as res7, duplicate detected)\n\n        // Configure idempotent message processing settings\n        $res9 = $redis->xcfgset('mystream', 300, 1000);\n        echo $res9 . PHP_EOL; // >>> OK",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex11",
      "language": "python",
      "code": "res5 = r.xadd(\"mystream\", {\"field\": \"value\"}, idmp=(\"producer1\", b\"msg1\"))\nprint(res5)  # >>> 1726055713867-0\n\n# Attempting to add the same message again with IDMP returns the original entry ID\nres6 = r.xadd(\"mystream\", {\"field\": \"different_value\"}, idmp=(\"producer1\", b\"msg1\"))\nprint(res6)  # >>> 1726055713867-0 (same ID as res5, message was deduplicated)\n\nres7 = r.xadd(\"mystream\", {\"field\": \"value\"}, idmpauto=\"producer2\")\nprint(res7)  # >>> 1726055713867-1\n\n# Auto-generated idempotent ID prevents duplicates for same producer+content\nres8 = r.xadd(\"mystream\", {\"field\": \"value\"}, idmpauto=\"producer2\")\nprint(res8)  # >>> 1726055713867-1 (same ID as res7, duplicate detected)\n\n# Configure idempotent message processing settings\nres9 = r.xcfgset(\"mystream\", idmp_duration=300, idmp_maxsize=1000)\nprint(res9)  # >>> True",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex12",
      "language": "ruby",
      "code": "res5 = r.call('XADD', 'mystream', 'IDMP', 'producer1', 'msg1', '*', 'field', 'value')\nputs res5 # >>> 1726055713867-0\n\n# Attempting to add the same message again with IDMP returns the original entry ID\nres6 = r.call('XADD', 'mystream', 'IDMP', 'producer1', 'msg1', '*', 'field', 'different_value')\nputs res6 # >>> 1726055713867-0 (same ID as res5, message was deduplicated)\n\nres7 = r.call('XADD', 'mystream', 'IDMPAUTO', 'producer2', '*', 'field', 'value')\nputs res7 # >>> 1726055713867-1\n\n# Auto-generated idempotent ID prevents duplicates for same producer+content\nres8 = r.call('XADD', 'mystream', 'IDMPAUTO', 'producer2', '*', 'field', 'value')\nputs res8 # >>> 1726055713867-1 (same ID as res7, duplicate detected)\n\n# Configure idempotent message processing settings\nres9 = r.call('XCFGSET', 'mystream', 'IDMP-DURATION', 300, 'IDMP-MAXSIZE', 1000)\nputs res9 # >>> OK",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex13",
      "language": "rust",
      "code": "// Note: IDMP is a Redis 8.6 feature - using raw commands\n        let res5: String = redis::cmd(\"XADD\")\n            .arg(\"idmpstream\")\n            .arg(\"IDMP\")\n            .arg(\"producer1\")\n            .arg(\"msg1\")\n            .arg(\"*\")\n            .arg(\"field\")\n            .arg(\"value\")\n            .query_async(&mut con)\n            .await\n            .unwrap();\n        println!(\"XADD IDMP result: {}\", res5); // >>> 1726055713867-0\n\n        // Attempting to add the same message again with IDMP returns the original entry ID\n        let res6: String = redis::cmd(\"XADD\")\n            .arg(\"idmpstream\")\n            .arg(\"IDMP\")\n            .arg(\"producer1\")\n            .arg(\"msg1\")\n            .arg(\"*\")\n            .arg(\"field\")\n            .arg(\"different_value\")\n            .query_async(&mut con)\n            .await\n            .unwrap();\n        println!(\"XADD IDMP result: {}\", res6); // >>> 1726055713867-0 (deduplicated)\n\n        let res7: String = redis::cmd(\"XADD\")\n            .arg(\"idmpstream\")\n            .arg(\"IDMPAUTO\")\n            .arg(\"producer2\")\n            .arg(\"*\")\n            .arg(\"field\")\n            .arg(\"value\")\n            .query_async(&mut con)\n            .await\n            .unwrap();\n        println!(\"XADD IDMPAUTO result: {}\", res7); // >>> 1726055713867-1\n\n        // Auto-generated idempotent ID prevents duplicates for same producer+content\n        let res8: String = redis::cmd(\"XADD\")\n            .arg(\"idmpstream\")\n            .arg(\"IDMPAUTO\")\n            .arg(\"producer2\")\n            .arg(\"*\")\n            .arg(\"field\")\n            .arg(\"value\")\n            .query_async(&mut con)\n            .await\n            .unwrap();\n        println!(\"XADD IDMPAUTO result: {}\", res8); // >>> 1726055713867-1 (duplicate detected)\n\n        // Configure idempotent message processing settings\n        let res9: String = redis::cmd(\"XCFGSET\")\n            .arg(\"idmpstream\")\n            .arg(\"IDMP-DURATION\")\n            .arg(\"300\")\n            .arg(\"IDMP-MAXSIZE\")\n            .arg(\"1000\")\n            .query_async(&mut con)\n            .await\n            .unwrap();\n        println!(\"XCFGSET result: {}\", res9); // >>> OK",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "idempotent-message-processing-examples-ex14",
      "language": "rust",
      "code": "// Note: IDMP is a Redis 8.6 feature - using raw commands\n        let res5: String = redis::cmd(\"XADD\")\n            .arg(\"idmpstream\")\n            .arg(\"IDMP\")\n            .arg(\"producer1\")\n            .arg(\"msg1\")\n            .arg(\"*\")\n            .arg(\"field\")\n            .arg(\"value\")\n            .query(&mut con)\n            .unwrap();\n        println!(\"XADD IDMP result: {}\", res5); // >>> 1726055713867-0\n\n        // Attempting to add the same message again with IDMP returns the original entry ID\n        let res6: String = redis::cmd(\"XADD\")\n            .arg(\"idmpstream\")\n            .arg(\"IDMP\")\n            .arg(\"producer1\")\n            .arg(\"msg1\")\n            .arg(\"*\")\n            .arg(\"field\")\n            .arg(\"different_value\")\n            .query(&mut con)\n            .unwrap();\n        println!(\"XADD IDMP result: {}\", res6); // >>> 1726055713867-0 (deduplicated)\n\n        let res7: String = redis::cmd(\"XADD\")\n            .arg(\"idmpstream\")\n            .arg(\"IDMPAUTO\")\n            .arg(\"producer2\")\n            .arg(\"*\")\n            .arg(\"field\")\n            .arg(\"value\")\n            .query(&mut con)\n            .unwrap();\n        println!(\"XADD IDMPAUTO result: {}\", res7); // >>> 1726055713867-1\n\n        // Auto-generated idempotent ID prevents duplicates for same producer+content\n        let res8: String = redis::cmd(\"XADD\")\n            .arg(\"idmpstream\")\n            .arg(\"IDMPAUTO\")\n            .arg(\"producer2\")\n            .arg(\"*\")\n            .arg(\"field\")\n            .arg(\"value\")\n            .query(&mut con)\n            .unwrap();\n        println!(\"XADD IDMPAUTO result: {}\", res8); // >>> 1726055713867-1 (duplicate detected)\n\n        // Configure idempotent message processing settings\n        let res9: String = redis::cmd(\"XCFGSET\")\n            .arg(\"idmpstream\")\n            .arg(\"IDMP-DURATION\")\n            .arg(\"300\")\n            .arg(\"IDMP-MAXSIZE\")\n            .arg(\"1000\")\n            .query(&mut con)\n            .unwrap();\n        println!(\"XCFGSET result: {}\", res9); // >>> OK",
      "section_id": "idempotent-message-processing-examples"
    },
    {
      "id": "specifying-a-stream-id-as-an-argument-ex0",
      "language": "plaintext",
      "code": "> XADD mystream 1526919030474-55 message \"Hello,\"\n\"1526919030474-55\"\n> XADD mystream 1526919030474-* message \" World!\"\n\"1526919030474-56\"",
      "section_id": "specifying-a-stream-id-as-an-argument"
    }
  ]
}
