# Consumer Group (/sdks/rust/how-to/events/consumer-group)



## Overview [#overview]

A **consumer group** turns Events pub/sub from a broadcast into a work queue. By default every subscriber on a channel gets every event — fine for notifications, but wasteful when you want a pool of workers to split a stream of tasks so each one is handled exactly once. Reach for a consumer group whenever you're scaling out event processing and duplicate work isn't just wasteful but actively wrong (double-charging a customer, double-sending an alert).

It works by naming a group when you subscribe: every subscriber that passes the same `group` argument to `subscribe_to_events` joins that group, and the broker round-robins each event to exactly one member instead of fanning it out to all of them. Passing an empty string reverts to normal fan-out, so the same call can flip between the two delivery models with one argument.

**Gotchas:** consumer groups are scoped per channel — subscribing to the same group on a different channel does not share load balancing across channels. A group with zero active subscribers behaves like no subscribers at all; events aren't queued for a group that's temporarily empty the way they are for durable queue messages. And because delivery is round-robin rather than content-aware, you can't route specific events to specific workers within a group — if you need that, partition by channel instead.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* Rust SDK installed (`cargo add kubemq`)

## Code [#code]

```rust title="main.rs"
use kubemq::prelude::*;
use kubemq::EventBuilder;
use std::time::Duration;

#[tokio::main]
async fn main() -> kubemq::Result<()> {
    let client = KubemqClient::builder()
        .host("localhost")
        .port(50000)
        .build()
        .await?;

    let channel = "rust-events.consumer-group";
    let group = "my-consumer-group";

    let sub1 = client
        .subscribe_to_events(
            channel,
            group,
            |event| {
                Box::pin(async move {
                    println!(
                        "Consumer-1 received: id={}, body={}",
                        event.id,
                        String::from_utf8_lossy(&event.body)
                    );
                })
            },
            None,
        )
        .await?;

    let sub2 = client
        .subscribe_to_events(
            channel,
            group,
            |event| {
                Box::pin(async move {
                    println!(
                        "Consumer-2 received: id={}, body={}",
                        event.id,
                        String::from_utf8_lossy(&event.body)
                    );
                })
            },
            None,
        )
        .await?;

    tokio::time::sleep(Duration::from_millis(500)).await;

    for i in 0..10 {
        let event = EventBuilder::new()
            .channel(channel)
            .body(format!("message-{}", i).into_bytes())
            .build();
        client.send_event(event).await?;
    }

    println!("Sent 10 events to group '{}'", group);
    tokio::time::sleep(Duration::from_secs(2)).await;

    sub1.unsubscribe().await;
    sub2.unsubscribe().await;
    client.close().await?;
    Ok(())
}
```

## How It Works [#how-it-works]

* Both subscribers pass the same `group` name, so each event is delivered to exactly one consumer.
* The server distributes events round-robin across group members.
* Review timeouts, channel names, and client IDs before running against shared environments.
* Run the program while the server from the prerequisites is available.

## Related [#related]

* [Events overview](/learn/events)
* [Rust SDK Reference](/sdks/rust/reference/events)
* [Multiple Subscribers](/sdks/rust/how-to/events/multiple-subscribers)
