Azure Service Bus: One topic, many subscriptions

TL;DR: A single Azure Service Bus topic can be a reasonable starting point for one-to-many messaging. The topic receives published messages, and subscriptions provide separate delivery views for consumers. As the number of subscriptions, filters, and messages grows, the shared topic can become a place where routing work and storage pressure meet. Splitting event streams across topics may help, but adding entities alone does not accelerate a system.

This post is part of a short series on Azure Service Bus topology under load. The first post introduces the topic, subscription, and filter model. The series then looks at filter count, subscription fan-out, topic depth, blast radius, and migration strategy. This one focuses on what happens when many subscriptions and rules meet on one shared topic.

Architectures often start with a simple topology because simple is easier to explain, secure, and operate. One topic for all published events has that appeal. Publishers send to one place. Subscribers attach rules to one place. Infrastructure-as-code templates stay compact.

The simplicity is real, but it comes with a trade-off. When one topic carries many event types, subscriptions, and filters, it becomes the shared work center for the pub/sub path. That may be fine at low volume. At higher volume, the shared center can become the bottleneck.

How to think about a shared topic

Azure Service Bus hides the implementation of its topics and subscriptions. For design purposes, a publisher sends a message to a topic, and a subscription is an independent delivery view that an application or service can consume. When one published message reaches several subscriptions, that is the fan-out.

This simplified model helps explain symptoms under load. Subscriptions add fan-out work, rules add broker-side routing, and forwarding moves messages between entities such as topics, subscriptions, and queues. Microsoft Learn’s performance guidance calls out all three because they consume compute and can decrease expected throughput.

Compare the same workload on the same budget

When I want to compare Azure Service Bus topologies, I prefer tests that keep the resource budget fixed. Give each topology one Premium Messaging Unit (MU), the dedicated compute and memory allocation in the Premium tier. Push a stable event stream through it. Watch the same measurements: CPU, memory, throttling, incoming rate, outgoing rate, and topic depth.

These scenarios use the same open-source test harness described in the first post. Its publisher generates messages at a configured rate; its subscriber setup creates the candidate topology; and the Helm values configure event ranges and subscriber groups. The harness can initialize SQL-filter, correlation-filter, MassTransit, and topic-per-concrete-type-style scenarios. The charts are Azure Monitor observations from those runs, so the numbers apply to those configurations.

This test asks how efficiently each topology uses the Messaging Unit. It compares the broker work created by each topology for the same application-level behavior. It does not try to find the maximum throughput of each one.

This distinction matters. A topology that needs more resources to reach the target rate may still be the right choice, but it has a different cost profile. A topology that reaches the same delivery behavior with lower CPU and stable topic depth leaves more headroom for growth and failure recovery.

Watch topic depth

CPU and memory are easy to watch. Topic depth shows whether delivery is keeping up. I use “topic depth” as shorthand for the topic message count metric. If the depth keeps growing under a steady incoming rate, internal delivery work is falling behind. The producer may still see successful sends, but messages are accumulating in the pub/sub path.

Stable topic depth is a better success criterion than “the test did not throw.” A topology can avoid throttling while messages continue to pile up. Once the topic quota is full, publishing stops.

In the load tests that shaped this post, some filtered topologies kept sending and receiving without obvious failures, but topic depth drifted upward as the number of subscription rules increased. Nothing had broken yet. The growing depth exposed a cost that successful API calls did not.

Why more topics can help

Azure Service Bus documentation notes that using more queues or topics primarily means more entities to manage, and from a scalability perspective, there may not be much difference for many workloads because Service Bus already spreads load across multiple logs internally. That is useful general guidance. Workload-specific testing still matters when comparing one topic with many subscriptions and filters against several narrower topics that require less routing work.

For high-throughput pub/sub, splitting events across topics changes how the broker processes messages. Each topic carries a narrower stream instead of every event type and subscription rule. Subscriptions become more focused, filters can often disappear, and topic depth is easier to interpret because the entity name identifies the event stream that is backing up.

In one fixed-resource topic-per-event-type test, outgoing messages stayed steady while CPU and memory remained bounded and throttled requests stayed at zero.

Microsoft’s performance guidance also notes that a topic with many subscriptions can have low overall throughput when messages are routed to all of them. Each message is received many times, and messages in a topic and its subscriptions share the same store. A shared topic can still be the right choice, but fan-out and storage work belong in the design discussion.

More entities are not automatically better. A shared topic and several focused topics create different broker workloads. Splitting can help when routing and fan-out work concentrated on one topic is the bottleneck.

The operational trade-off

More topics are not free from an operational perspective. They need names, permissions, templates, deployment automation, monitoring, and cleanup. A topology that performs better but cannot be deployed safely is not better in practice.

Entity count can also influence what cost efficiency means. A Premium namespace is billed by Messaging Unit, and Azure Service Bus allows 1,000 combined queues and topics per Messaging Unit. A topology approaching that threshold may need another Messaging Unit to create more entities, even when the current workload does not otherwise need more compute or memory. A partitioned namespace can be configured with up to 64 Messaging Units across four partitions, although Azure also documents a separate namespace limit of 16,000 combined queues and topics.

That can make a denser topology, or a mixture of shared and focused topics, a reasonable choice. It saves entity headroom, but it does not create runtime capacity. Consolidating event streams can also concentrate filters, fan-out, storage, and backlog risk on the remaining topics. A topology that fits the entity budget can still need another Messaging Unit because it exhausts CPU or memory first.

A shared topic can also be useful on purpose. One pattern I like is using shared topics to colocate multiple tenants, environments, or bounded workloads in the same Premium namespace while still giving each one a clear pub/sub boundary. In that model, the shared topic is not a default catch-all for the whole system. It is an intentional isolation boundary inside a larger namespace.

Choose based on the workload. A small system may reasonably use fewer entities. A high-throughput system with many subscribers may benefit from distributing the pub/sub work across topics per event type.

Topology choiceWhat it optimizesWhat to watch
Shared topicFewer entities and simpler initial deploymentSubscription count, subscription rule count, topic depth, and CPU
Topic per event typeFocused routing, clearer observability, and less filter workEntity count, naming, permissions, and deployment automation

Choose based on the workload

A topic affects runtime behavior as well as deployment. Topics, subscriptions, filters, forwarding, and Messaging Units determine where the broker spends CPU, memory, and storage.

If I were reviewing a high-throughput Azure Service Bus pub/sub system today, I would ask for three numbers early: subscriptions per topic, subscription rules per subscription, and topic depth under steady load. Together, they show whether the simple topology still fits the workload.

Further reading:

Common questions

Before splitting a topic-heavy topology, I would start with these questions.

Does Azure Service Bus require topic-per-event-type?

No. Azure Service Bus supports several valid topology shapes. Topic-per-event-type is one option that can fit high-throughput pub/sub systems where filter and subscription work dominate.

Should I split every topic immediately?

No. Measure first. If topic depth stays flat, CPU has headroom, and operational simplicity matters more, the existing topology may be fine.

What should I remember?

A topic is a place where the broker does work, not a passive folder for messages.

About the author

Daniel Marbach

Add comment

Recent Posts