Queue vs Topic — What Is the Difference?
Both Queue and Topic are messaging mechanisms used in microservices, but the main difference is who receives the message.
Queue: A message is processed by one consumer from a competing group.
Topic: A published message can be delivered to multiple independent subscribers.
1. What is a Queue?
A Queue is mainly used for point-to-point / work distribution communication.
Producer
│
│ Message
▼
┌─────────────┐
│ Queue │
└──────┬──────┘
│
▼
Consumer
Example:
Order Service
│
│ ProcessPayment
▼
Payment Queue
│
▼
Payment Service
The important idea is:
Each message should normally be processed once by one consumer instance.
2. Queue with Multiple Consumers
Suppose Payment Service has three instances:
┌──> Payment Service 1
│
Payment Queue ────┼──> Payment Service 2
│
└──> Payment Service 3
These are competing consumers.
If the queue contains:
Message 1
Message 2
Message 3
Message 4
Message 5
processing might look like:
Message 1 → Consumer 1
Message 2 → Consumer 2
Message 3 → Consumer 3
Message 4 → Consumer 1
Message 5 → Consumer 2
The key point is that Message 1 is not intentionally delivered to all three consumers.
One consumer processes it.
This allows horizontal scaling.
3. Why Do We Need a Queue?
A Queue is useful when there is one logical job that should be handled once.
Examples:
ProcessPayment
GenerateInvoice
ResizeImage
SendSMS
ProcessOrder
GenerateReport
For example:
Order Service
│
│ Payment Request
▼
┌─────────────────┐
│ Payment Queue │
│ │
│ Payment 1001 │
│ Payment 1002 │
│ Payment 1003 │
└────────┬────────┘
│
▼
Payment Service
You don't want three payment workers to independently charge the customer for the same queue message.
4. What Is a Topic?
A Topic is mainly used for Publish/Subscribe (Pub/Sub) communication.
Producer
│
│ Event
▼
┌─────────────┐
│ Topic │
└──────┬──────┘
│
┌───┼──────────┐
▼ ▼ ▼
Sub A Sub B Sub C
│ │ │
▼ ▼ ▼
Service Service Service
A B C
A message published to a topic can be delivered to multiple subscriptions.
5. Topic Example
Suppose Order Service creates an order and publishes:
OrderCreated
Several services need that information:
Inventory Service
Notification Service
Analytics Service
Loyalty Service
Using a topic:
Order Service
│
│ OrderCreated
▼
┌────────────────┐
│ Orders Topic │
└───────┬────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
Inventory Notification Analytics
Subscription Subscription Subscription
│ │ │
▼ ▼ ▼
Inventory Notification Analytics
Service Service Service
Each subscription receives its own logical copy of OrderCreated.
6. Why Does a Topic Need Subscriptions?
This is an important concept.
Consider an Azure Service Bus topic:
Orders Topic
The topic might have:
inventory-subscription
notification-subscription
analytics-subscription
Architecture:
Orders Topic
│
┌─────────────┼─────────────┐
▼ ▼ ▼
Inventory Notification Analytics
Subscription Subscription Subscription
│ │ │
▼ ▼ ▼
Inventory Notification Analytics
Service Service Service
The subscription behaves somewhat like an independent virtual queue for that subscriber.
Therefore, if one service is temporarily down:
Inventory Service → Running
Notification Service → DOWN
Analytics Service → Running
Inventory and Analytics can continue processing.
Messages intended for the Notification subscription can remain there, subject to retention/TTL configuration, until Notification can process them.
7. Main Difference
The easiest way to remember it:
Queue
Message
│
▼
Queue
│
┌─────┼─────┐
▼ ▼ ▼
C1 C2 C3
ONE processes it
Topic
Event
│
▼
Topic
│
┌───────┼───────┐
▼ ▼ ▼
Sub A Sub B Sub C
│ │ │
▼ ▼ ▼
A B C
ALL subscriptions
can receive it
8. Queue vs Topic Comparison
| Feature | Queue | Topic |
|---|---|---|
| Pattern | Point-to-point | Publish/Subscribe |
| Message receiver | One competing consumer | Multiple subscriptions |
| Main purpose | Work distribution | Event distribution |
| Multiple consumers | Compete for messages | Subscribers receive independently |
| Scaling | Competing consumers | Scale consumers within each subscription |
| Typical content | Commands/jobs | Events |
| Example | ProcessPayment |
OrderCreated |
| Service independence | Good | Very good for fan-out |
| Azure Service Bus | Queue | Topic + Subscriptions |
9. Practical Example
Consider an e-commerce application.
We have:
Order Service
Payment Service
Inventory Service
Notification Service
Analytics Service
There are two different requirements.
Requirement 1 — Process a Payment
Order Service needs Payment Service to process a payment.
Order Service
│
│ ProcessPayment
▼
Payment Queue
│
▼
Payment Service
This is naturally a Queue scenario.
Why?
Because:
ProcessPayment
should normally be handled by one payment-processing worker.
10. Requirement 2 — Announce Order Created
After an order is created:
OrderCreated
multiple services need to know.
Order Service
│
│ OrderCreated
▼
Orders Topic
│
├──> Inventory Subscription
│ ↓
│ Inventory Service
│
├──> Notification Subscription
│ ↓
│ Notification Service
│
└──> Analytics Subscription
↓
Analytics Service
This is naturally a Topic scenario.
Why?
Because several independent services need the same event.
11. Command vs Event Connection
This gives us a useful design guideline.
Queue often fits Commands
Commands ask something to happen:
ProcessPayment
SendEmail
GenerateInvoice
ReserveInventory
Example:
ProcessPayment
↓
Payment Queue
↓
Payment Service
Topic often fits Events
Events announce something that already happened:
OrderCreated
PaymentCompleted
CustomerRegistered
OrderCancelled
Example:
OrderCreated
↓
Orders Topic
├──> Inventory
├──> Notification
└──> Analytics
This isn't an absolute rule, but it's a very useful design principle.
12. Azure Service Bus Queue Example
Suppose we create:
Queue Name = payment-queue
Producer:
Order Service
Consumer:
Payment Service
Flow:
Order Service
│
│ ProcessPayment
▼
┌─────────────────────┐
│ Azure Service Bus │
│ │
│ payment-queue │
└──────────┬──────────┘
│
▼
Payment Service
13. Required NuGet Package
For ASP.NET Core:
dotnet add package Azure.Messaging.ServiceBus
Namespace:
using Azure.Messaging.ServiceBus;
14. appsettings.json
{
"AzureServiceBus": {
"ConnectionString": "<service-bus-connection-string>",
"PaymentQueue": "payment-queue",
"OrdersTopic": "orders-topic"
}
}
For production, don't normally store the real secret in source-controlled appsettings.json.
Prefer:
Managed Identity
Azure Key Vault
Environment Variables
15. Sending to a Queue
using Azure.Messaging.ServiceBus;
public class PaymentPublisher
{
private readonly ServiceBusClient _client;
public PaymentPublisher(ServiceBusClient client)
{
_client = client;
}
public async Task SendAsync()
{
ServiceBusSender sender =
_client.CreateSender("payment-queue");
var message = new ServiceBusMessage(
"""
{
"orderId": 1001,
"amount": 2500
}
""");
await sender.SendMessageAsync(message);
}
}
Flow:
PaymentPublisher
↓
payment-queue
↓
Payment Consumer
16. Queue Consumer
ServiceBusProcessor processor =
client.CreateProcessor("payment-queue");
processor.ProcessMessageAsync += async args =>
{
string body =
args.Message.Body.ToString();
Console.WriteLine(body);
// Process payment
await args.CompleteMessageAsync(
args.Message);
};
processor.ProcessErrorAsync += args =>
{
Console.WriteLine(
args.Exception.Message);
return Task.CompletedTask;
};
await processor.StartProcessingAsync();
If you run three instances:
Payment Service 1
Payment Service 2
Payment Service 3
they can compete for messages from:
payment-queue
17. Azure Service Bus Topic Example
Now suppose Order Service publishes:
OrderCreated
to:
orders-topic
Subscriptions:
inventory
notification
analytics
Architecture:
Order Service
│
▼
orders-topic
│
┌─────────────┼─────────────┐
▼ ▼ ▼
inventory notification analytics
│ │ │
▼ ▼ ▼
Inventory Notification Analytics
Service Service Service
18. Publishing to a Topic
The producer code is almost identical to sending to a queue.
The difference is the destination:
ServiceBusSender sender =
client.CreateSender("orders-topic");
var message = new ServiceBusMessage(
"""
{
"eventType": "OrderCreated",
"orderId": 1001,
"customerId": 501,
"amount": 2500
}
""");
await sender.SendMessageAsync(message);
The producer sends once:
Order Service
↓
orders-topic
Service Bus then makes the message available to matching subscriptions.
19. Topic Consumer
Inventory Service consumes:
Topic = orders-topic
Subscription = inventory
Example:
ServiceBusProcessor processor =
client.CreateProcessor(
"orders-topic",
"inventory");
processor.ProcessMessageAsync += async args =>
{
string body =
args.Message.Body.ToString();
Console.WriteLine(
$"Inventory received: {body}");
// Update inventory
await args.CompleteMessageAsync(
args.Message);
};
processor.ProcessErrorAsync += args =>
{
Console.WriteLine(
args.Exception.Message);
return Task.CompletedTask;
};
await processor.StartProcessingAsync();
Notification Service uses:
client.CreateProcessor(
"orders-topic",
"notification");
Analytics Service uses:
client.CreateProcessor(
"orders-topic",
"analytics");
Same topic:
orders-topic
Different subscriptions.
20. What Happens If One Topic Consumer Is Down?
Suppose:
Inventory → UP
Notification → DOWN
Analytics → UP
Order Service publishes:
OrderCreated
Conceptually:
Orders Topic
│
┌─────────────┼─────────────┐
▼ ▼ ▼
Inventory Notification Analytics
Subscription Subscription Subscription
│ │ │
▼ X ▼
Processed DOWN Processed
Notification's subscription can retain its message independently.
When Notification Service returns:
Notification Service
↓
Notification Subscription
↓
OrderCreated
↓
Send Email
This independent subscription state is one of the important benefits of topics.
21. Topic Subscription Filtering
A Topic becomes even more powerful when subscriptions use filters.
Suppose the topic contains:
OrderCreated
OrderCancelled
OrderShipped
Maybe Inventory wants:
OrderCreated
OrderCancelled
Notification wants:
OrderCreated
OrderShipped
OrderCancelled
Subscriptions can use broker-supported filtering rules so that each subscriber receives only relevant messages.
Conceptually:
Orders Topic
│
┌───────────────┴───────────────┐
▼ ▼
Inventory Subscription Notification Subscription
│ │
OrderCreated OrderCreated
OrderCancelled OrderCancelled
OrderShipped
22. Topic Is Not Simply "Many Consumers"
This is an important interview trap.
A Queue can also have many consumers.
For example:
┌──> Worker 1
Queue ──────────┼──> Worker 2
└──> Worker 3
But they compete.
One message:
Message 1001
goes to one worker.
With a Topic:
Topic
│
├──> Subscription A → Consumer A
├──> Subscription B → Consumer B
└──> Subscription C → Consumer C
the same published message can reach all three subscriptions.
Therefore:
Queue = many consumers can compete. Topic = many subscribers can independently receive.
23. Scaling a Topic Consumer
Suppose Inventory subscription receives huge traffic.
You can still run multiple Inventory Service instances:
Orders Topic
↓
Inventory Subscription
│
├──> Inventory Instance 1
├──> Inventory Instance 2
└──> Inventory Instance 3
These three instances compete within the Inventory subscription.
At the same time:
Notification Subscription
│
├──> Notification Instance 1
└──> Notification Instance 2
So you get both:
Topic
↓
Multiple independent subscriptions
↓
Multiple competing consumers per subscription
This is a very important production concept.
24. Failure Handling
Both queues and topic subscriptions need failure handling.
Message
↓
Consumer
↓
Processing fails
↓
Redelivery
↓
Still failing
↓
Dead-Letter Queue
For Azure Service Bus, each queue/subscription has dead-letter capabilities.
Common reasons include:
Invalid message
Consumer exception
Schema mismatch
Maximum delivery count exceeded
Business processing failure
25. Idempotency
Even with a queue or topic, don't assume a business operation can never be attempted twice.
For example:
MessageId = ABC123
Consumer processes it successfully, but the acknowledgement fails.
The broker may redeliver it.
Therefore:
if (await AlreadyProcessed(messageId))
{
return;
}
await ProcessMessage();
await MarkAsProcessed(messageId);
This is particularly important for:
Payment
Inventory reduction
Invoice generation
Loyalty points
26. Queue vs Topic in RabbitMQ
RabbitMQ terminology is slightly different.
RabbitMQ commonly uses:
Producer
↓
Exchange
↓
Queue
↓
Consumer
For fan-out:
Exchange
│
┌───────────┼───────────┐
▼ ▼ ▼
Queue A Queue B Queue C
│ │ │
▼ ▼ ▼
Consumer A Consumer B Consumer C
RabbitMQ does not use Azure Service Bus's exact Topic + Subscription abstraction.
RabbitMQ uses exchanges, bindings, routing keys, and queues to implement similar messaging patterns.
27. What About Kafka?
Kafka's terminology is different again.
Kafka uses:
Producer
↓
Topic
↓
Partitions
↓
Consumer Groups
For example:
orders Topic
│
┌──────────┴──────────┐
▼ ▼
Inventory Group Analytics Group
│ │
Consumers Consumers
Each consumer group can independently process the same event stream.
So don't assume:
Azure Service Bus Topic
=
Kafka Topic
They share the word Topic, but their underlying architecture and delivery/retention models are different.
28. Advantages of Queue
- Simple point-to-point processing
- Good for commands/jobs
- Easy worker scaling through competing consumers
- Buffers traffic spikes
- Consumer can process at its own speed
- Supports asynchronous processing
- Good for background work
Typical examples:
ProcessPayment
SendEmail
GenerateInvoice
ResizeImage
GeneratePDF
29. Disadvantages of Queue
A single queue is not ideal when many independent systems all need their own copy of a message.
Suppose:
OrderCreated
must reach:
Inventory
Notification
Analytics
If all three directly compete on the same queue:
Order Queue
├──> Inventory
├──> Notification
└──> Analytics
only one may receive a particular message.
That's incorrect if all three must react.
A pub/sub design is more appropriate.
30. Advantages of Topic
- Multiple independent subscribers
- Excellent for Event-Driven Architecture
- Easy to add new subscribers
- Subscribers are isolated from each other
- Supports fan-out
- Subscription filtering may be available
- Each subscriber can scale independently
Example:
CustomerRegistered
│
▼
Customer Topic
│
├──> Welcome Email
├──> Loyalty
├──> Analytics
└──> CRM Integration
31. Disadvantages of Topic
Topics introduce more architectural complexity:
Topic
Subscriptions
Filters
Independent retries
Independent DLQs
Multiple consumers
Monitoring
Schema management
Also, one published event may produce substantial downstream processing because many services can react to it.
Poorly designed event chains can become difficult to trace.
32. When Should I Use Queue?
Use a queue when the requirement sounds like:
Someone needs to perform this job once.
Examples:
Process this payment.
Generate this invoice.
Resize this image.
Send this SMS.
Generate this report.
Architecture:
Command
↓
Queue
↓
One processing worker
33. When Should I Use Topic?
Use a topic/pub-sub mechanism when the requirement sounds like:
This happened. Anyone interested can react.
Examples:
OrderCreated
PaymentCompleted
CustomerRegistered
OrderCancelled
ProductUpdated
Architecture:
Event
↓
Topic
├──> Subscriber A
├──> Subscriber B
└──> Subscriber C
34. Real-World Architecture Using Both
A well-designed microservice system often uses both Queue and Topic.
For example:
Client
│
▼
Order Service
│
│ OrderCreated
▼
Orders Topic
│
┌─────────────┼─────────────┐
▼ ▼ ▼
Inventory Notification Analytics
│
│ ProcessPayment
▼
Payment Queue
│
▼
Payment Service
Here:
Topic
OrderCreated
is a business event multiple services care about.
Queue
ProcessPayment
represents work that one payment-processing consumer should perform.
35. Easy Memory Trick
Remember:
QUEUE
↓
"Who will do this work?"
TOPIC
↓
"Who wants to know this happened?"
Or:
QUEUE
Command → One logical handler
TOPIC
Event → Many independent subscribers
This distinction is excellent for interviews.
36. Key Points
- A Queue is commonly used for point-to-point/work-queue messaging.
- A Topic is commonly used for publish/subscribe.
- Queue consumers can be multiple, but they compete for messages.
- Topic subscriptions independently receive published messages.
- Queue is often appropriate for commands/jobs.
- Topic is often appropriate for events.
ProcessPaymentis a good queue example.OrderCreatedis a good topic example.- In Azure Service Bus, a topic uses subscriptions.
- Each subscription can have its own consumers and failure handling.
- Multiple consumer instances can compete inside one subscription.
- RabbitMQ achieves similar pub/sub behavior using exchanges + bindings + queues.
- Kafka uses topics + partitions + consumer groups, which is a different architecture.
- Queue and Topic can and often should coexist in the same microservice architecture.
37. Interview Questions and Answers
Q1. What is the main difference between Queue and Topic?
Answer:
A Queue is primarily used when a message should be processed by one consumer from a competing group.
A Topic is used when the same published message needs to be delivered to multiple independent subscribers.
Q2. Can a Queue have multiple consumers?
Answer:
Yes.
Multiple consumers can listen to the same queue, but they normally act as competing consumers.
Queue
├──> Consumer 1
├──> Consumer 2
└──> Consumer 3
Each message is handled by one consumer instance.
Q3. Can a Topic have multiple consumers?
Answer:
Yes, through multiple subscriptions.
Topic
├──> Subscription A → Consumer A
├──> Subscription B → Consumer B
└──> Subscription C → Consumer C
Each subscription can independently receive the published message.
Q4. When would you use a Queue?
Answer:
Use a Queue for work that should normally be processed once by one logical handler.
Examples:
ProcessPayment
GenerateInvoice
SendSMS
ResizeImage
Q5. When would you use a Topic?
Answer:
Use a Topic when multiple independent services need to react to the same event.
For example:
OrderCreated
might be consumed by Inventory, Notification and Analytics services.
Q6. Why are subscriptions needed with a Topic?
Answer:
Subscriptions provide independent message streams for different consumers. This allows each service to process the same published event independently and maintain its own processing state.
Q7. What happens if one Topic subscriber is down?
Answer:
Other subscriptions can continue processing. The unavailable subscriber's subscription can retain its messages according to broker configuration until the service returns or the messages expire/dead-letter.
Q8. Is Queue always one consumer?
Answer:
No.
A Queue can have multiple consumer instances, but they compete for messages.
The important point is:
One message → one consumer from the competing group.
Q9. Queue or Topic for ProcessPayment?
Answer:
A Queue is typically appropriate because ProcessPayment is a command/job intended for one logical payment processor.
ProcessPayment
↓
Payment Queue
↓
Payment Service
Q10. Queue or Topic for OrderCreated?
Answer:
A Topic/pub-sub model is typically appropriate when several services need to react independently.
OrderCreated
↓
Orders Topic
├──> Inventory
├──> Notification
└──> Analytics
Q11. Is an Azure Service Bus Topic the same as a Kafka Topic?
Answer:
No.
Azure Service Bus Topics use subscriptions for enterprise pub/sub messaging.
Kafka Topics are partitioned durable event logs consumed using offsets and consumer groups.
They share similar terminology but have different architectures and semantics.
Interview-Friendly Final Answer
A Queue is mainly used for point-to-point or work-queue communication, where multiple consumers may compete but each message is normally processed by one consumer instance. A Topic is used for publish/subscribe communication, where the same published message can be delivered to multiple independent subscriptions. For example,
ProcessPaymentis typically suited to a queue because one payment worker should handle it, whileOrderCreatedis suited to a topic because Inventory, Notification, Analytics, and other services may all need to react to the same event. In Azure Service Bus, Topics use subscriptions; in RabbitMQ similar fan-out is implemented using exchanges and queues; Kafka uses topics, partitions, and consumer groups with a different event-log model.