DEV_NET_CORE
GET_STARTED
AzureMessaging and event-driven Azure integration

Choosing queues vs topics vs event notifications

Overview

Choosing between queues, topics, and event notifications is an architecture decision about intent, ownership, delivery semantics, and failure handling.

Use a queue when one logical worker group must process each item. Use a topic when multiple independent subscriber groups need durable copies of the same message. Use an event notification service such as Azure Event Grid when a publisher announces that something happened and subscribers may react independently.

For interviews, the strongest answers do not start with product names. They start with questions:

  • Is this a command, event, or telemetry stream?
  • Does one consumer need to do required work, or can zero or many consumers react?
  • Is the payload high-value business data or a lightweight notification?
  • Is durable buffering required?
  • Is fan-out required?
  • Are retries, duplicate detection, transactions, sessions, or DLQs required?
  • Does the consumer need push delivery or pull-based work processing?
  • What happens when the consumer is down?

The right answer is often a combination: Event Grid for notification and Service Bus for durable processing.

Core Concepts

Message Intent Comes First

Before choosing an Azure service, classify the communication:

IntentMeaningTypical Azure fit
CommandDo this workService Bus queue
Business messageDeliver high-value payload to a consumerService Bus queue or topic
Discrete event notificationSomething happenedEvent Grid
Fan-out to durable subscriber groupsMultiple services need their own copyService Bus topic
Telemetry streamMany events over time for analyticsEvent Hubs
Simple storage-backed queueBasic decoupling with lower feature needsAzure Queue Storage

This page focuses on Service Bus queues, Service Bus topics, and Event Grid notifications.

Queue

A queue is for work distribution. One message is processed by one consumer from a competing consumer group.

Choose a queue when:

  • The producer wants work to be done.
  • Only one logical worker should process each message.
  • Workers need pull-based processing.
  • Load leveling is important.
  • The consumer might be offline.
  • DLQ handling is required.
  • Processing may need retries or lock renewal.

Example:

Code
API -> Service Bus queue -> Worker pool -> SQL / external system

Topic and Subscription

A topic is for durable publish-subscribe messaging. A producer sends once, and Service Bus copies the message into matching subscriptions.

Choose a topic when:

  • Several independent services need a copy.
  • Each subscriber needs its own backlog.
  • Each subscriber needs its own retry and DLQ behavior.
  • Filtering by message properties is useful.
  • Consumers process at different speeds.
  • Subscriber deployment schedules are independent.

Example:

Code
Order service -> Service Bus topic
                 -> Billing subscription
                 -> Fulfillment subscription
                 -> Notifications subscription

Event Notification

An event notification says that something happened. The publisher does not require a specific subscriber to complete a business transaction.

Choose Event Grid when:

  • You need to react to Azure service events.
  • You want serverless event routing.
  • Subscribers can independently react.
  • Push delivery to handlers is useful.
  • Filtering by event type, subject, or fields is enough.
  • The event is lightweight and points to authoritative state.

Example:

Code
Blob created -> Event Grid -> Azure Function

Command Versus Event

A command is a request. An event is a fact.

Code
GenerateInvoice       command
InvoiceGenerated      event
ReserveInventory      command
InventoryReserved     event
SendWelcomeEmail      command
UserRegistered        event

If the sender expects a specific action to happen, think queue. If the sender announces a fact and does not know who cares, think event notification or topic depending on durability requirements.

Queue Versus Topic

Use a queue for one logical consumer group. Use a topic for many logical consumer groups.

The common mistake is using one queue for multiple unrelated consumers. If three systems all need every order message, one queue is wrong because competing consumers divide messages. Use a topic with three subscriptions.

Another mistake is using a topic when there is only one logical worker. That adds management overhead without fan-out value.

Topic Versus Event Grid

Both support fan-out, but they optimize for different things.

NeedService Bus topicEvent Grid
Durable work backlog per subscriberStrong fitUsually route to queue
Broker transactionsSupported in Service Bus scopeNot the purpose
Sessions and ordering by keySupportedNo ordering guarantee
Duplicate detectionSupportedSubscriber handles duplicates
Azure resource notificationsPossible but not primaryStrong fit
Push to serverless handlersPossible through integrationsStrong fit
Lightweight event routingGood when durable subscriber backlog mattersStrong fit

Use Event Grid when the event is a notification. Use Service Bus topics when each subscriber needs durable queue-like processing.

Event Grid Plus Service Bus

Combining services is common:

Code
Azure Storage -> Event Grid -> Service Bus queue -> Worker

This pattern works well when:

  • The source naturally emits Event Grid events.
  • The handler needs durable buffering.
  • Processing can be slow or fail repeatedly.
  • DLQ tooling is important.
  • Workers should scale with backlog.

Event Grid detects and routes the event. Service Bus owns work processing.

Pull Versus Push

Service Bus is typically pull-based. Consumers receive messages when they are ready. This fits worker pools, backpressure, private consumers, and durable processing.

Event Grid push delivery calls the subscriber when events happen. This fits reactive serverless workflows, webhooks, and notifications.

Event Grid namespace topics can also support pull delivery, but the interview-level distinction remains useful: queues are for controlled work consumption; event notifications are for reacting to state changes.

Durable Backlog

Ask whether each consumer needs a durable backlog.

If yes:

  • Use a Service Bus queue for one consumer group.
  • Use a Service Bus topic subscription for each independent group.
  • Or route Event Grid to Service Bus if the source event comes from Event Grid.

If no:

  • Event Grid may be enough for lightweight notification.

Durable backlog matters when downtime, replay, and independent recovery are important.

Delivery Guarantees

All these systems require duplicate-tolerant consumers, but their semantics differ.

Service Bus provides brokered message handling with peek-lock, settlement, DLQ, sessions, duplicate detection, and transactions within Service Bus.

Event Grid provides at least once event delivery, filtering, retry, and optional dead-lettering. It does not guarantee ordering and is not designed around command processing.

The application still owns idempotency.

Ordering Requirements

If strict per-aggregate ordering is required, Service Bus sessions are often the best Azure messaging fit.

Event Grid does not guarantee ordering. A subscriber should treat events as notifications and re-read authoritative state when order matters.

If you need high-throughput ordered streams by partition for analytics, that points toward Event Hubs rather than queues, topics, or basic notifications.

Payload Size and Claim Check

Message brokers are not file stores. For large payloads:

  1. Store the data in Blob Storage.
  2. Send a small message or event containing a pointer.
  3. Include checksum, content type, length, and version metadata.
  4. Authorize the consumer before reading the blob.

This is the claim-check pattern.

Failure Handling

Queues and subscriptions are strong when failure handling needs to be explicit:

  • Message lock.
  • Delivery count.
  • Abandon.
  • Complete.
  • Dead-letter.
  • Replay.
  • Backlog monitoring.

Event Grid is strong when the main goal is event routing. For important handlers, configure dead-lettering or route into Service Bus for more operational control.

Cost and Operational Complexity

Do not overbuild messaging.

Questions to ask:

  • Is there really more than one subscriber?
  • Does the subscriber need its own backlog?
  • Are sessions, transactions, or duplicate detection required?
  • Will operations monitor DLQs?
  • Can a simpler direct call or scheduled job work?
  • Is this a notification or required work?

The simplest correct option is usually best. The wrong simple option becomes expensive later; the wrong complex option becomes expensive immediately.

Decision Checklist

Use this checklist:

Code
One worker group must process each item?
  Use Service Bus queue.

Multiple independent worker groups need each message?
  Use Service Bus topic with one subscription per group.

Azure resource or application state-change notification?
  Use Event Grid.

Event notification triggers slow or high-value work?
  Event Grid -> Service Bus queue or topic.

Need per-key ordering?
  Use Service Bus sessions.

Need analytics over high-volume streams?
  Consider Event Hubs.

Need only simple storage-backed background work?
  Consider Azure Queue Storage if advanced broker features are unnecessary.

Common Mistakes

  • Choosing Event Grid for required command processing.
  • Using one queue for multiple independent subscribers.
  • Using topics when there is no fan-out.
  • Assuming Event Grid ordering.
  • Ignoring duplicate delivery.
  • Sending large payloads through the broker.
  • Creating one subscription shared by unrelated services.
  • Forgetting each Service Bus subscription needs DLQ monitoring.
  • Using filters as a substitute for authorization.
  • Choosing by product familiarity instead of message intent.

Best Practices

  • Model intent before selecting the service.
  • Use queues for commands and work items.
  • Use topics when subscribers need independent durable copies.
  • Use Event Grid for event notifications and Azure service events.
  • Combine Event Grid and Service Bus when notification triggers durable work.
  • Make all consumers idempotent.
  • Keep payloads small and versioned.
  • Use correlation IDs across asynchronous boundaries.
  • Monitor backlog, age, retries, and dead-letter paths.
  • Document the reason for the chosen messaging pattern.

Interview Practice

PreviousStorage accounts, containers, blobs, virtual folders, metadata, and access tiersNext UpDuplicate detection, retries, and poison-message handling