{
  "schema_version": 2,
  "id": "develop/tools/insight/insight-stream-consumer",
  "title": "Manage streams and consumer groups in Redis Insight",
  "url": "https://redis.io/docs/latest/develop/tools/insight/insight-stream-consumer/",
  "summary": "Learn how to manage streams and consumer groups in Redis Insight",
  "aliases": [
    "/develop/connect/insight/tutorials/insight-stream-consumer",
    "/develop/tools/insight/tutorials/insight-stream-consumer"
  ],
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-09-29T16:29:37+01:00",
  "page_type": "content",
  "content_hash": "5cab90d7874a2f7b155316ed9b8902490dec575bb92f3d1436630c1005ab0781",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "A _stream_ is an append-only log file. \nWhen you add data to it, you cannot change it. \nThat may seem like a disadvantage; however, a stream serves as a log or single source of truth. \nIt can also be used as a buffer between processes that work at different speeds and do not need to know about each other. \nFor more conceptual information about streams, see [Redis Streams](https://redis.io/docs/latest/develop/data-types/streams). \n\nIn this topic, you will learn how to add and work with streams as well as consumer groups in Redis Insight.\n\nHere's a stream that models temperature and humidity sensors. Processes interacting with the stream perform one of two roles: _consumer_ and _producer_. \nThe point of a stream is that it's not going to end, so you cannot capture whole datasets and do some processing on them. \n \nIn this stream, sensors are considered _producers_, which broadcast data. \nA _consumer_ reads from the stream and does some work on it. \nFor example, if the temperature is above a certain threshold, it puts a message out to turn on the air conditioner in that unit or notify the maintenance.\n\n![A stream that models temperature and humidity sensors.](https://redis.io/docs/latest/images/ri/stream.png)\n\nIt is possible to have multiple consumers doing different jobs, one measuring humidity, and another taking temperature measurements over periods of time. \nRedis stores a copy of the entire dataset in memory, which is a finite resource.\nTo avoid runaway data, streams can be trimmed when you add something to them. \nWhen adding to a stream with [`XADD`](https://redis.io/docs/latest/commands/xadd), you can optionally specify that the stream should be trimmed to a specific or approximate number of the newest entries, or to only include entries whose ID is higher than the ID specified.\nYou can also manage the storage required for streaming data using key expiry.  For example, by writing each day's data to its own stream in Redis and expiring each stream's key after a period of time, say a week.\nAn ID can be any number, but each new entry in the stream must have an ID whose value is higher than the last ID added to the stream."
    },
    {
      "id": "adding-new-entries",
      "title": "Adding new entries",
      "role": "content",
      "text": "Use [`XADD`](https://redis.io/docs/latest/commands/xadd) with `*` for the ID to have Redis automatically generate a new ID for you consisting of a millisecond precision timestamp, a dash and a sequence number.  For example `1656416957625-0`.  Then supply the field names and values to store in the new stream entry.\n\nThere are a couple of ways of retrieving things. You can retrieve entries by time range or you could ask for everything that's happened since a timestamp or ID that you specify. Using a single command you can ask for anything from 10:30 until 11:15 am on a given day."
    },
    {
      "id": "consumer-groups",
      "title": "Consumer groups",
      "role": "content",
      "text": "A more realistic use case would be a system with many temperature sensors whose data Redis puts in a stream, records the time they arrive, and orders them. \n\n![A stream that models temperature and humidity sensors.](https://redis.io/docs/latest/images/ri/consumer.png)\n\nOn the right side we have two consumers that read the stream. One of them is alerting if the temperature is over a certain number and texting the maintenance crew that they need to do something, and the other is a data warehouse that is taking the data and putting it into a database. \n\nThey run independently of each other. \nUp in the right, we have another sort of task. \nLet's assume that alerting and data warehouse are really fast. \nYou get a message whether the temperature is larger than a specific value, which might take a millisecond. \nAnd alerting can keep up with the data flow. \nOne way you can scale consumers is _consumer groups_, which allows multiple instances of the same consumer or same code to work as a team to process the stream."
    },
    {
      "id": "managing-streams-in-redis-insight",
      "title": "Managing streams in Redis Insight",
      "role": "content",
      "text": "You can add a stream in Redis Insight in two ways: create a new stream or add to an existing stream.\n\nTo create a stream, start by selecting the key type (stream). \nYou cannot set time to live (TTL) because it cannot be put on a message in a stream; it can only be done on a Redis key. Name the stream _mystream_. \nThen, set the *Entry ID* to `*` to default to timestamp. \nIf you have your own ID generation strategy, enter the next ID from your sequence. Remember that the ID must be higher than the ID of any other entry in the stream.\n \nThen, enter fields and values using + to add more than one (for example, name and location). \nNow you have a stream that appears in the **Streams** view and you can continue adding fields and values to it.\n\nRedis Insight runs read commands for you so you can see the stream entries in the **Streams** view. \nAnd the **Consumer Groups** view shows each consumers in a given consumer group and the last time Redis allocated a message, what the ID of it was and how many times that process has happened, and whether a consumer has you have told Redis that you are finished working with that task using the [`XACK`](https://redis.io/docs/latest/commands/xack) command."
    },
    {
      "id": "monitor-temperature-and-humidity-from-sensors-in-redis-insight",
      "title": "Monitor temperature and humidity from sensors in Redis Insight",
      "role": "content",
      "text": "This example shows how to bring an existing stream into Redis Insight and work with it."
    },
    {
      "id": "setup",
      "title": "Setup",
      "role": "setup",
      "text": "1. Install [Redis Insight](https://redis.com/redis-enterprise/redis-insight/?_ga=2.48624486.1318387955.1655817244-1963545967.1655260674#insight-form).\n2. Download and install [Node.js](https://nodejs.org/en/download/) (LTS version).\n3. Install [Redis](https://redis.io/docs/latest/operate/oss_and_stack/install). In Docker, check that Redis is running locally on the default port 6379 (with no password set). \n4. Clone the [code repository](https://github.com/redis-developer/introducing-redis-talk) for this example. \nSee the [README](https://github.com/redis-developer/introducing-redis-talk/tree/main/streams) for more information about this example and installation tips.\n5. On your command-line, navigate to the folder containing the code repository and install the Node.js package manager (npm). \n\n \n npm install"
    },
    {
      "id": "run-the-producer",
      "title": "Run the producer",
      "role": "content",
      "text": "To start the producer, which will add a new entry to the stream every few seconds, enter:\n\n\nnpm run producer\n\n> streams@1.0.0 producer\n> node producer.js\n\nStarting producer...\nAdding reading for location: 62, temperature: 40.3, humidity: 36.5\nAdded as 1632771056648-0\nAdding reading for location: 96, temperature: 15.4, humidity: 70\nAdded as 1632771059039-0\n...\n\n\nThe producer runs indefinitely. \nSelect `Ctrl+C` to stop it. \nYou can start multiple instances of the producer if you want to add entries to the stream faster."
    },
    {
      "id": "run-the-consumer",
      "title": "Run the consumer",
      "role": "content",
      "text": "To start the consumer, which reads from the stream every few seconds, enter:\n\n\nnpm run consumer\n\n> streams@1.0.0 consumer\n> node consumer.js\n\nStarting consumer...\nResuming from ID 1632744741693-0\nReading stream...\nReceived entry 1632771056648-0:\n[ 'location', '62', 'temp', '40.3', 'humidity', '36.5' ]\nFinished working with entry 1632771056648-0\nReading stream...\nReceived entry 1632771059039-0:\n[ 'location', '96', 'temp', '15.4', 'humidity', '70' ]\n\n\nThe consumer stores the last entry ID that it read in a Redis string at the key `consumer:lastid`. It uses this string to pick up from where it left off after it is restarted. Try this out by stopping it with `Ctrl+C` and restarting it.\n\nOnce the consumer has processed every entry in the stream, it will wait indefinitely for instances of the producer to add more:\n\n\nReading stream...\nNo new entries since entry 1632771060229-0.\nReading stream...\nNo new entries since entry 1632771060229-0.\nReading stream...\n\n\nStop it using `Ctrl+C`."
    },
    {
      "id": "run-a-consumer-group",
      "title": "Run a consumer group",
      "role": "content",
      "text": "A consumer group consists of multiple consumer instances working together. Redis manages allocation of entries read from the stream to members of a consumer group. A consumer in a group will receive a subset of the entries, with the group as a whole receiving all of them. When working in a consumer group, a consumer process must acknowledge receipt/processing of each entry.\n\nUsing multiple terminal windows, start three instances of the consumer group consumer, giving each a unique name:\n\n\nnpm run consumergroup consumer1\n\n> streams@1.0.0 consumergroup\n> node consumer_group.js -- \"consumer1\"\n\nStarting consumer consumer1...\nConsumer group temphumidity_consumers exists, not created.\nReading stream...\nReceived entry 1632771059039-0:\n[ 'location', '96', 'temp', '15.4', 'humidity', '70' ]\nAcknowledged processing of entry 1632771059039-0.\nReading stream...\n\n\nIn a second terminal:\n\n\nnpm run consumergroup consumer2\n\n\nAnd in a third:\n\n\nnpm run consumergroup consumer3\n\n\nThe consumers will run indefinitely, waiting for new messages to be added to the stream by a producer instance when they have collectively consumed the entire stream. \nNote that in this model, each consumer instance does not receive all of the entries from the stream, but the three members of the group each receive a subset."
    },
    {
      "id": "view-the-stream-in-redis-insight",
      "title": "View the stream in Redis Insight",
      "role": "content",
      "text": "1. Launch Redis Insight.\n2. Select `localhost:6379`\n3. Select **STREAM**. Optionally, select full screen from the upper right corner to expand the view.\n\n![The Streams view in Redis Insight.](https://redis.io/docs/latest/images/ri/ri-streams-cg.png)\n\nYou can now toggle between **Stream** and **Consumer Groups** views to see your data. \nAs mentioned earlier in this topic, a stream is an append-only log so you can't modify the contents of an entry, but you can delete an entire entry. \nA case when that's useful is in the event of a so-called _poison-pill message_ that can cause consumers to crash. You can physically remove such messages in the **Streams** view or use the [`XDEL`](https://redis.io/docs/latest/commands/xdel) command at the command-line interface (CLI).\n\nYou can continue interacting with your stream at the CLI. For example, to get the current length of a stream, use the [`XLEN`](https://redis.io/docs/latest/commands/xlen) command:\n\n\nXLEN ingest:temphumidity\n\n\nUse streams for auditing and processing events in banking, gaming, supply chain, IoT, social media, and so on."
    },
    {
      "id": "related-topics",
      "title": "Related topics",
      "role": "related",
      "text": "- [Redis Streams](https://redis.io/docs/latest/develop/data-types/streams)\n- [Introducing Redis Streams with Redis Insight, node.js, and Python](https://www.youtube.com/watch?v=q2UOkQmIo9Q) (video)"
    }
  ],
  "examples": []
}
