# How Buzz Implements Its Subscription System: A Deep Dive into the Relay Registry

> Discover how Buzz implements its subscription system using a thread-safe lock-free registry and DashMap indexes for efficient Nostr event fan-out to WebSocket connections.

- Repository: [Block Open Source/buzz](https://github.com/block/buzz)
- Tags: deep-dive
- Published: 2026-08-28

---

**Buzz implements its subscription system as a thread-safe, lock-free registry in [`crates/buzz-relay/src/subscription.rs`](https://github.com/block/buzz/blob/main/crates/buzz-relay/src/subscription.rs) that uses specialized DashMap indexes to achieve sub-linear fan-out of Nostr events to matching WebSocket connections.**

The subscription system is the core message routing engine of [block/buzz](https://github.com/block/buzz), a Nostr relay implementation written in Rust. It maintains every client-side `REQ` subscription in memory and determines precisely which WebSocket connections should receive each incoming event without scanning the entire connection pool. This architecture enables the relay to handle high-throughput workloads while respecting NIP-01 subscription semantics and strict scoping invariants.

## Core Data Structures and Identifiers

The registry centers on two primary identifiers defined at lines 11-14: `ConnId`, a UUID that uniquely identifies a WebSocket connection, and `SubId`, a client-provided string that identifies a specific subscription within that connection.

Every subscription operates within a defined **SubscriptionScope**, an enum at lines 18-25 that distinguishes between **Global** subscriptions (no channel restriction) and **Channels** subscriptions (limited to specific channel UUIDs). This scope determines which indexes the registry queries during event fan-out.

To enable O(1) look-ups, the system uses an `IndexKey` struct (lines 50-57) composed of a `channel_id: Uuid` and a `kind: Kind`. These keys populate multiple concurrent hash maps that index subscriptions by their filter constraints.

## Registry Architecture and Indexing Strategy

The `SubscriptionRegistry` struct (lines 84-100) contains six `DashMap` instances that store the subscription tree and its various indexes:

- `subs`: The authoritative store mapping `(ConnId, SubId)` to the subscription record
- `channel_kind_index`: Maps `(channel_id, kind)` to matching subscriptions
- `channel_wildcard_index`: Captures channel-scoped subscriptions with no kind constraint
- `global_kind_index` and `global_p_kind_index`: Handle global subscriptions by kind or by p-tag combinations
- `global_wildcard_index`: Catches global subscriptions with no specific constraints

This multi-map design avoids O(N) scans by pre-sorting subscriptions into granular buckets based on their filter parameters.

## Registering Subscriptions with NIP-01 Semantics

New subscriptions enter the registry through `register_scoped` or `register_channels_scoped` (lines 108-140). These methods implement NIP-01 replacement semantics: if a `SubId` already exists for a given `ConnId`, the old subscription is atomically removed before the new one is inserted.

The index population logic (lines 158-200) inspects each filter's constraints to determine optimal placement:

- **Channel-scoped filters** without a `kinds` constraint enter the `channel_wildcard_index`
- **Channel-scoped filters** with specific kinds create entries in `channel_kind_index` for each kind
- **Global filters** utilizing p-tag constraints use the specialized `global_p_kind_index` when possible
- **Remaining global filters** fall back to `global_kind_index` or `global_wildcard_index`

This classification ensures that `fan_out_scoped` can narrow candidate matches immediately without examining unrelated subscriptions.

## Event Fan-Out and Delivery

When an event arrives, the registry invokes `fan_out_scoped` (lines 780-886) to determine routing. The method first checks whether the event is channel-scoped or global, then walks only the relevant indexes to collect candidate `(ConnId, SubId)` pairs.

Candidates undergo final validation in `push_match` (lines 635-661), which re-checks the authoritative subscription record in the `subs` map. This guards against stale snapshots: because `DashMap` provides lock-free concurrent access, a subscription might be modified between index traversal and event delivery. The double-check ensures that **filters_match** (defined in [`crates/buzz-core/src/filter.rs`](https://github.com/block/buzz/blob/main/crates/buzz-core/src/filter.rs)) and scope constraints are satisfied before the event is enqueued.

The implementation guarantees strict scoping invariants at lines 887-892: global subscriptions never receive channel-scoped events, and channel subscriptions never receive global events, even if their filters would technically match.

## Subscription Lifecycle Management

Removal operations clean up both the primary store and secondary indexes. The `remove_subscription` method (lines 237-285) deletes a single subscription and invokes `remove_from_index` (lines 662-755) to purge its entries from all relevant indexes. For connection teardown, `remove_connection` wipes all subscriptions associated with a `ConnId` and adjusts the active-subscription gauge.

Both methods maintain consistency by using the same atomic operations available to the registration path, ensuring that removal does not block ongoing fan-out operations.

## Concurrency and Thread Safety

All registry state uses `DashMap`, a lock-free concurrent hash map that allows register, fan-out, and removal operations to run in parallel without mutex contention. The architecture treats index snapshots as merely "hints"—the authoritative check in `push_match` means stale candidate lists are harmless and never result in incorrect delivery.

The multithreaded test case at lines 538-605 verifies these guarantees under concurrent subscription replacement and high-volume event fan-out.

```rust
use buzz_relay::subscription::SubscriptionRegistry;
use nostr::{Filter, Kind};
use uuid::Uuid;

// Initialize the registry
let registry = SubscriptionRegistry::new();
let conn_id = Uuid::new_v4();
let channel_id = Uuid::new_v4();
let sub_id = "sub_001".to_string();

// Register a channel-scoped subscription for TextNote events
let filters = vec![Filter::new().kind(Kind::TextNote)];
registry.register_scoped(
    buzz_core::CommunityId::from_uuid(Uuid::nil()),
    conn_id,
    sub_id.clone(),
    filters,
    Some(channel_id),
);

// Simulate an incoming event
let event = buzz_core::StoredEvent::with_received_at(
    nostr::EventBuilder::new(Kind::TextNote, "hello world", [])
        .sign_with_keys(&nostr::Keys::generate())
        .unwrap(),
    chrono::Utc::now(),
    Some(channel_id),
    true,
);

// Retrieve matching connections
let matches = registry.fan_out_scoped(
    buzz_core::CommunityId::from_uuid(Uuid::nil()),
    &event
);
assert_eq!(matches, vec![(conn_id, sub_id.clone())]);

// Cleanup on disconnect
registry.remove_subscription(conn_id, &sub_id);

```

## Summary

- **Core Location**: The subscription system resides in [`crates/buzz-relay/src/subscription.rs`](https://github.com/block/buzz/blob/main/crates/buzz-relay/src/subscription.rs) as the `SubscriptionRegistry` struct.
- **Identifiers**: Uses `ConnId` (UUID) for connections and `SubId` (String) for client subscriptions, scoped via the `SubscriptionScope` enum.
- **Indexing Strategy**: Six separate `DashMap` indexes categorize subscriptions by `(channel, kind)`, `(community, kind, #p)`, or wildcard status to eliminate full-table scans.
- **Registration**: `register_scoped` implements NIP-01 replacement semantics and populates indexes based on filter constraints at lines 108-200.
- **Fan-Out**: `fan_out_scoped` queries scoped indexes and validates candidates via `push_match` to prevent stale data delivery (lines 635-886).
- **Concurrency**: Lock-free `DashMap` structures enable parallel registration, removal, and fan-out without blocking.

## Frequently Asked Questions

### How does Buzz handle concurrent subscription updates?

Buzz uses `DashMap` lock-free concurrent hash maps for all registry state, allowing registration, fan-out, and removal to execute in parallel. When a subscription is updated, the `register_scoped` method atomically replaces the old entry (per NIP-01 semantics), and the `push_match` validation step during fan-out filters out any stale candidates that might have been collected from index snapshots.

### What is the difference between channel-scoped and global subscriptions?

Channel-scoped subscriptions, defined by the `SubscriptionScope::Channels` variant, restrict event delivery to specific channel UUIDs and are indexed separately from global subscriptions. Global subscriptions (`SubscriptionScope::Global`) receive only non-channel events. The `fan_out_scoped` method enforces this boundary at lines 887-892, ensuring events never cross between these domains even if filter criteria overlap.

### Why does the system use multiple indexes instead of a single map?

Multiple indexes provide sub-linear lookup performance by pre-sorting subscriptions into buckets based on their filter constraints. Instead of scanning all subscriptions for every event, `fan_out_scoped` queries only the relevant index—such as `channel_kind_index` for a specific event kind—reducing lookup time from O(N) to O(1) relative to the subscription count.

### How are subscriptions cleaned up when a client disconnects?

The `remove_connection` method efficiently removes all subscriptions associated with a `ConnId` and purges their entries from every secondary index using `remove_from_index`. This bulk cleanup operation adjusts internal gauges and ensures no orphaned entries remain in the wildcard or kind-specific indexes.