Azure Service BusMessaging

What it is. Azure Service Bus is a fully managed enterprise message broker: it hosts queues for point-to-point delivery and topics with subscriptions for publish-subscribe fan-out. Applications and services exchange messages through it instead of calling each other directly, which decouples producers from consumers and lets each side scale, fail and deploy on its own.

Architecture Diagram

End-to-end architectural topology of Azure Service Bus, demonstrating the namespace isolation boundary, supported ingress protocols, point-to-point Queues (with duplicate detection, sessions, and Dead-Letter Queue), publish-subscribe Topics with Subscription filtering rules, competing consumer scaling, and the complete Peek-Lock message settlement lifecycle.

AZURE SERVICE BUS — ENTERPRISE MESSAGING ARCHITECTURE Fully Managed Enterprise Broker • AMQP 1.0 / HTTPS • Entra ID & SAS PRODUCERS (Senders) 🌐 Web Applications ASP.NET Core / Node.js Sends: Orders, Checkouts ⚙️ Microservices Java / Spring / .NET / Go Commands & Batch jobs ⚡ Event Publishers Azure Functions / SaaS Emits: Business Events 🔌 Integration APIs Partners / Webhooks REST / HTTPS Ingress 🔑 Security & Protocol • AMQP 1.0 (Port 5671 TLS) • HTTPS / REST (Port 443) • Entra ID RBAC / SAS Tokens ☁️ AZURE SERVICE BUS NAMESPACE <namespace>.servicebus.windows.net STANDARD / PREMIUM 🛡️ Perimeter: Private Endpoint (VNet) • TLS 1.2/1.3 • IP Filtering • Availability Zones & Geo-DR PATTERN 1: QUEUE — POINT-TO-POINT (Competing Consumers 1:1) Temporal Decoupling • Load Leveling 📦 Queue: orders-queue Msg 3 Msg 2 Msg 1 FIFO Out ✔ Dup Detection 🔒 Sessions (FIFO) ⏱️ Peek-Lock ☠️ Dead-Letter Queue (DLQ): orders-queue/$DeadLetterQueue Automatic redirection when: • DeliveryCount > MaxDeliveryCount (10 retries exceeded — poison message) • Message Time-To-Live (TTL) Expired or consumer explicitly dead-letters Poison / Expired 🔄 Peek-Lock Protocol 1. Receiver requests message & lock 2. Message invisible to other workers 3. Worker processes workload 4. Settle: Complete / Abandon / DLQ PATTERN 2: TOPIC & SUBSCRIPTIONS — PUBLISH-SUBSCRIBE (1:N Fan-Out) Independent Copies • Content-Based Routing 📣 Topic events-topic Single publication entry point for all event types. 1 msg → N subs SQL: Type='Invoice' Correlation: Env='Prod' TrueFilter (1=1 All) 📅 Sub: sub-billing Virtual Queue • Private DLQ sub-entity 🚚 Sub: sub-logistics Virtual Queue • Private DLQ sub-entity 🔍 Sub: sub-audit-lake Virtual Queue • Receives 100% of events CONSUMERS (Receivers) 👥 Competing Workers Pool Horizontally scaled instances ⚙️ Worker Instance 1 (Active) ⚙️ Worker Instance 2 (Active) ✔ Exactly 1 worker gets 1 msg ⚖️ Peek-Lock Settlement Receiver must explicitly settle: ✓ CompleteAsync() → Deletes msg ↺ AbandonAsync() → Retries (+1) ☠ DeadLetterAsync() → To DLQ ⏸ DeferAsync() → By Seq Number 💳 Billing Service Invoices & Stripe payment capture ⚡ Azure Functions (Shipping) Event-driven serverless trigger 📊 Analytics & Compliance Data Lake ingestion & cold storage 📈 Azure Monitor & App Insights • Metrics: Active/DeadLetter Msgs • Diagnostic Logs & Tracing • Auto-scale on Queue Length 🗺️ ARCHITECTURE HIGHLIGHTS & GUARANTEES: Decoupling: Senders & receivers operate asynchronously; zero direct dependencies. At-Least-Once Delivery: Guaranteed via Peek-Lock settlement & auto-retries. Poison Safety: Automatic isolation in DLQ prevents processing bottlenecks.
Figure 1: High-level architectural topology of Azure Service Bus Namespace, Entities (Queues, Topics, Subscriptions, DLQ), Security Boundary, and Consumer Settlement Loop.

Core concepts

Namespace
Deployment and billing container that gives you a unique host name (<namespace>.servicebus.windows.net); all queues and topics live inside it.
Queue
Point-to-point destination: each message is delivered to a single competing consumer. Multiple readers can be attached; the broker hands each message to only one of them.
Topic and subscription
Publish-subscribe destination: a topic accepts messages and each subscription receives its own copy, so several downstream systems can react to the same publication independently.
Filters and actions
Subscriptions can carry SQL or correlation filters so they only receive a subset of the messages; actions can annotate the message properties on the way in.
Sessions
Messages that share a SessionId are handled in order by a single receiver, which gives ordered processing for a related stream of work without locking the whole queue.
Peek-lock and settlement
Receivers take a message under a lock and then complete, abandon, defer or dead-letter it. Abandoning returns the message to the queue and increments its delivery count.
Dead-letter queue
Each queue and subscription has a secondary sub-queue where messages land when they expire or exceed the maximum delivery count — the place to inspect poison messages instead of losing them.
Duplicate detection
The broker discards a message whose MessageId was already seen inside a configurable detection window, which makes retries from the sender safe.
Scheduled messages and deferral
A message can be enqueued with a future enqueue time, or deferred and later retrieved by sequence number — useful for time-based workflows and out-of-order handling.
Auto-forwarding and transactions
Entities can chain into each other (a queue forwarding to a topic, for example), and send/receive operations can be grouped in a transaction that commits or rolls back as a unit.

Service tiers

Tier Entities Typical use
Basic Queues only Cheap queueing for development, tests and simple one-way work; no topics, no duplicate detection.
Standard Queues and topics General production messaging with the full feature set (sessions, dead-lettering, filters, duplicate detection) on shared infrastructure.
Premium Queues and topics Dedicated resources for predictable latency and throughput, isolation through private networking, and the largest message sizes.

Feature availability changes over time — check the current tier matrix before sizing a production namespace.

Step-by-Step Configuration & Usage Guide (with Screenshots)

A complete, screenshot-driven walkthrough for configuring and using Azure Service Bus from scratch: provisioning namespaces, setting up queues with dead-lettering and deduplication, configuring pub/sub topics with SQL filtering, establishing security credentials, testing with Service Bus Explorer, and implementing production-ready .NET 8 producers and consumers.

# Phase Action Summary Key Focus
1 Create Namespace Provision namespace in Azure Portal with Standard/Premium tier. DNS host, region, tier
2 Verify Dashboard Inspect deployment completion, Essentials bar, and throughput metrics. Endpoint validation
3 Configure Queue Create orders-queue with duplicate detection, lock duration, and DLQ. Point-to-point, max deliveries
4 Create Topic & Subscriptions Create events-topic and subscriptions with SQL/correlation rules. 1:N Fan-out, content routing
5 Configure Security Grant Entra ID RBAC roles (Data Sender/Receiver) or generate SAS policy keys. Zero-trust authentication
6 Service Bus Explorer Send JSON test payloads and peek/settle messages in the browser. In-portal validation
7 Programmatic .NET Code Build C# producer (batch send) and processor with peek-lock completion loop. Complete/Abandon/DLQ
8 Monitoring & DLQ Alerts Configure Azure Monitor metrics and set automated alerts on DLQ spikes. Poison message observation
1

Create Azure Service Bus Namespace in Portal

The namespace is the root management, billing, and DNS container (<namespace>.servicebus.windows.net) that houses all your queues and topics.

  1. Navigate to the Azure Portal and sign in with your administrator account.
  2. In the top global search bar, type Service Bus and select Service Bus under Services. Alternatively, click + Create a resource → Integration → Service Bus.
  3. Click + Create to open the Create namespace provisioning wizard.
  4. Under Project Details, select your active Subscription and pick or create a target Resource group (e.g. rg-messaging-prod).
  5. Under Instance Details:
    • Namespace name: Enter a globally unique name (e.g. sb-ecommerce-prod). A green checkmark confirms availability.
    • Location: Choose your target Azure region (e.g. East US) close to your client workloads.
    • Pricing tier: Choose Standard for production publish-subscribe topics, queues, sessions, and deduplication. (Select Premium if you require private link isolation and dedicated messaging units).
  6. Click Review + create, verify the validation passed, and click Create.
Microsoft Azure 🔍 Search resources, services, and docs (G+/) ⚙️ 🔔 ❓ admin@company.com Home > Service Bus > Create namespace Basics Networking Tags Review + create Project Details Subscription * Azure subscription 1 (Pay-As-You-Go) Resource Group * rg-messaging-prod Create new Instance Details Namespace Name * sb-ecommerce-prod .servicebus.windows.net ✓ Location * East US Pricing tier * Standard (Includes Topics, Queues & Variable Throughput) ℹ️ Standard Tier SLA: Supports Queues, Topics, Subscriptions, Sessions, and Transactions up to 256 KB message payload. Review + create Next : Networking >
Screenshot 1: Azure Portal — Create Service Bus Namespace wizard (Basics tab) with parameters and tier selection.
Pro-tip: Always choose Standard tier or higher for production. The Basic tier does not support Topics, Subscriptions, Sessions, Transactions, or Duplicate Detection.
2

Verify Provisioning & Explore Namespace Dashboard

Once Azure Resource Manager completes deployment, access the namespace overview to inspect endpoint addresses, resource status, and operational telemetry.

  1. When the notification banner confirms “Your deployment is complete”, click Go to resource.
  2. Inspect the Essentials top card:
    • Status: Ensure it shows Active.
    • Host name: Note your primary DNS endpoint (e.g. sb-ecommerce-prod.servicebus.windows.net).
    • Resource group: rg-messaging-prod.
  3. Examine the left navigation pane: identify Entities (Queues and Topics) and Settings (Shared access policies, Networking).
  4. Review the built-in real-time charts in the Overview page displaying Incoming Messages and Outgoing Messages.
Microsoft Azure 🔍 Search resources, services, and docs (G+/) ⚙️ 🔔 ❓ admin@company.com Home > Resource groups > rg-messaging-prod > sb-ecommerce-prod ➕ Queue ➕ Topic ↻ Refresh 🗑️ Delete 🔌 Export template sb-ecommerce-prod Service Bus Namespace 📊 Overview 📋 Activity log 🔐 Access control (IAM) 🔑 Shared access policies 🌐 Networking ENTITIES 📦 Queues 📣 Topics MONITORING 📈 Metrics 🔔 Alerts 📃 Diagnostic settings Resource group (change) rg-messaging-prod Status ● Active Location East US Pricing tier Standard Host name sb-ecommerce-prod.servicebus.windows.net Subscription ID a8c17b44-9381-4e78-9e12-32b01e3381a4 📈 Incoming Messages (Last 1 hour) 1.2K 22:00 • 22:15 • 22:30 • 22:45 📈 Outgoing & Successful Deliveries 1.2K Settled via CompleteAsync()
Screenshot 2: Azure Portal — Service Bus Namespace dashboard showing Essentials, side navigation, and message throughput telemetry.
3

Create and Configure a Point-to-Point Queue

Queues implement point-to-point decoupling where multiple workers can read from the queue, but each message is exclusively delivered to and processed by a single competing consumer.

  1. In the left sidebar under Entities, click Queues, then click + Queue on the command bar.
  2. In the Add queue side blade, configure the following core parameters:
    • Name: orders-queue.
    • Max queue size: 1 GB (or up to 80 GB in Premium).
    • Max delivery count: 10. After 10 failed/abandoned delivery attempts, the message is automatically sequestered in the Dead-Letter Queue (DLQ).
    • Message time to live (TTL): 14 Days.
    • Lock duration: 30 Seconds (time a consumer has to process and settle before the lock expires).
  3. Select the advanced feature flags:
    • Check Enable duplicate detection with a 10 minutes detection window (broker discards duplicate MessageIds).
    • Check Enable dead lettering on message expiration so expired orders are never silently lost.
    • (Optional) Check Enable sessions if strict FIFO per SessionId is required.
  4. Click Create at the bottom of the blade.
Microsoft Azure 🔍 Search resources, services, and docs (G+/) ⚙️ 🔔 ❓ admin@company.com sb-ecommerce-prod > Queues > + Add queue Queues No queues provisioned in this namespace yet. Add queue ✕ Name * orders-queue Max queue size * 1 GB Max delivery count * 10 Message time to live 14 Days Lock duration 30 Seconds ✓ Enable duplicate detection (10 mins window) ✓ Enable dead lettering on message expiration Enable sessions (FIFO ordering by SessionId) Create Cancel
Screenshot 3: Azure Portal — Add Queue side panel with Max Delivery Count, Duplicate Detection, and Dead-Lettering configuration.
Lock Duration Guideline: Set the lock duration to at least 2× to 3× your average processing time. If workers occasionally run long, use RenewMessageLockAsync() in code rather than setting an excessively long default lock duration.
4

Create a Topic with Filtered Subscriptions (Pub/Sub)

Topics provide 1:N publish-subscribe fan-out: publishers send to a single topic, and each attached subscription receives an independent copy according to configurable rule filters.

  1. In the left sidebar under Entities, click Topics, then click + Topic. Enter name events-topic and click Create.
  2. Click on the newly created events-topic to open its blade, then click + Subscription.
  3. In the Add subscription blade, configure subscription sub-billing:
    • Subscription name: sub-billing.
    • Max delivery count: 10.
  4. Open the subscription’s Filters & actions tab:
    • Add a SQL Filter: sys.Label = 'OrderPlaced' AND Amount >= 100.00.
    • Add an optional Rule Action: SET RoutedBy = 'EnterpriseBus'; to annotate message headers before queuing.
  5. Repeat the process to add other independent subscriptions (e.g. sub-shipping with correlation filter or sub-audit with TrueFilter 1=1).
Microsoft Azure 🔍 Search resources, services, and docs (G+/) ⚙️ 🔔 ❓ admin@company.com sb-ecommerce-prod > Topics > events-topic > Subscriptions > sub-billing Topic: events-topic > Subscription: sub-billing 📋 Subscription Properties Max Delivery Count: 10 Message Lock Duration: 30 Seconds Default Message TTL: 14 Days Dead Lettering on Filter Errors: Enabled ⚙️ Subscription Rule & Filter Editor Rule Name: BillingInvoiceFilter Filter Type: SQL Filter sys.Label = 'OrderPlaced' AND Amount >= 100.00 -- Routes only high-value orders to this subscription Rule Action (Property Mutation): SET RoutedBy = 'EnterpriseBus'; Save Rule
Screenshot 4: Azure Portal — Topic Subscription Filter editor showing SQL Filter rule expression and routing action.
5

Configure Access Security: Microsoft Entra ID & SAS

Grant client applications permission to send or receive messages securely using either passwordless RBAC (recommended) or Shared Access Signature (SAS) connection strings.

  1. Option A — Microsoft Entra ID (Recommended for Production & Cloud Apps):
    • Go to Access control (IAM) → + Add → Add role assignment.
    • For producers, assign the Azure Service Bus Data Sender role to your App Service, Azure Function, or User Managed Identity.
    • For consumers, assign the Azure Service Bus Data Receiver role.
  2. Option B — Shared Access Policies (SAS Connection Strings):
    • In the left sidebar under Settings, click Shared access policies.
    • Click + Add, specify name SendListenPolicy, check Send and Listen (avoid checking Manage unless granting administrative privileges), then click Create.
    • Click the policy to open its drawer and copy the Primary Connection String (starts with Endpoint=sb://...).
Microsoft Azure 🔍 Search resources, services, and docs (G+/) ⚙️ 🔔 ❓ admin@company.com sb-ecommerce-prod > Shared access policies > SendListenPolicy Shared access policy: SendListenPolicy Configured Claims: Manage ✓ Send ✓ Listen Primary Key w9K8s2mZ98Lx41QyT.......................................= 📋 Copy Primary Connection String (Standard .NET SDK / Clients) Endpoint=sb://sb-ecommerce-prod.servicebus.windows.net/;SharedAccessKeyName=SendListenPolicy;SharedAccessKey=w9K8s2...= 📋 Copy 🛡️ Zero-Trust Recommendation: Microsoft Entra ID (Passwordless) Instead of connection strings, grant the managed identity role: • Azure Service Bus Data Sender • Azure Service Bus Data Receiver
Screenshot 5: Azure Portal — Shared Access Policy configuration blade and Primary Connection String retrieval.
Zero-Trust Security: Avoid storing connection strings in source code or configuration files. When running on Azure (App Services, AKS, Container Apps), use DefaultAzureCredential with Managed Identities.
6

Test and Settle Messages via Service Bus Explorer

The Azure Portal embeds Service Bus Explorer, a powerful tool for publishing test payloads, peeking at queue depth, and testing settlement without writing code.

  1. Navigate to Entities → Queues → click on orders-queue.
  2. In the queue’s left menu, select Service Bus Explorer.
  3. Send a Test Message:
    • Select the Send messages sub-tab.
    • Set Content Type to application/json.
    • Paste sample JSON payload in the message body:
      {
        "orderId": "ORD-2026-904",
        "customer": "Fabrikam Retail",
        "amount": 250.00,
        "status": "APPROVED"
      }
    • Under Custom Properties, add key sys.Label with value Priority.
    • Click Send. A green notification confirms successful ingress.
  4. Peek and Settle Messages:
    • Switch to the Peek from start tab to view the active message queue without removing messages.
    • Inspect Message ID msg-9041, Sequence Number, Enqueued Time, and Delivery Count.
    • Click into the message to inspect headers and simulate Dead-lettering or settlement.
Microsoft Azure 🔍 Search resources, services, and docs (G+/) ⚙️ 🔔 ❓ admin@company.com sb-ecommerce-prod > Queues > orders-queue > Service Bus Explorer 📤 Send messages 👁️ Peek from start (Active: 3) ☠️ Peek dead-letter queue (DLQ: 0) 📝 Compose & Send Message Content-Type: application/json Message Body: { "orderId": "ORD-2026-904", "customer": "Fabrikam Retail", "amount": 250.00, "status": "APPROVED" } Custom Props: sys.Label = 'Priority' ➤ Send 👁️ Active Messages in Queue Seq # Message ID Delivery # Enqueued Time Actions 101 msg-9041 1 22:30:15 UTC Settle DLQ Message 101 Payload Inspection: { "orderId": "ORD-2026-904", "customer": "Fabrikam Retail", "amount": 250.00 } Lock Token: 4b8e21f9-01ae-4882-9382... State: Active • Expires in 13d 23h
Screenshot 6: Azure Portal — Service Bus Explorer showing Message Composer, Peek Grid, and Payload Inspector.
7

Programmatic Implementation: C# .NET Producer & Consumer

Implement a production-grade publisher and asynchronous message processor using the official Azure.Messaging.ServiceBus SDK with the complete Peek-Lock settlement lifecycle.

  1. Install official client and identity packages in your .NET project:
    dotnet add package Azure.Messaging.ServiceBus
    dotnet add package Azure.Identity
  2. Sender (Producer): Creates a batch of messages and sends them atomically:
    using Azure.Identity;
    using Azure.Messaging.ServiceBus;
    
    // Authenticate via Microsoft Entra ID (or connection string)
    await using var client = new ServiceBusClient(
        "sb-ecommerce-prod.servicebus.windows.net", 
        new DefaultAzureCredential());
    
    ServiceBusSender sender = client.CreateSender("orders-queue");
    
    // Build message batch for optimal AMQP throughput
    using ServiceBusMessageBatch batch = await sender.CreateMessageBatchAsync();
    var order = new ServiceBusMessage("payload-json-bytes")
    {
        ContentType = "application/json",
        MessageId = "msg-9041",       // Enables duplicate detection
        Subject = "OrderPlaced"       // Used for subscription filter routing
    };
    
    if (batch.TryAddMessage(order))
    {
        await sender.SendMessagesAsync(batch);
        Console.WriteLine("[PRODUCER] Sent message batch successfully.");
    }
  3. Processor (Consumer) with Peek-Lock Settlement:
    ServiceBusProcessor processor = client.CreateProcessor("orders-queue", new ServiceBusProcessorOptions
    {
        ReceiveMode = ServiceBusReceiveMode.PeekLock, // Message stays locked until settled
        MaxConcurrentCalls = 4,                       // Concurrent competing worker threads
        AutoCompleteMessages = false                  // Explicit settlement control
    });
    
    processor.ProcessMessageAsync += async args =>
    {
        string payload = args.Message.Body.ToString();
        Console.WriteLine($"[CONSUMER] Received order: {payload}");
    
        try
        {
            // 1. Execute business logic
            await ProcessOrderAsync(payload);
    
            // 2. Success: Complete and delete from queue
            await args.CompleteMessageAsync(args.Message);
            Console.WriteLine("[ACK] Message completed successfully.");
        }
        catch (TransientNetworkException)
        {
            // 3. Transient failure: Release lock for retry (+1 delivery count)
            await args.AbandonMessageAsync(args.Message);
        }
        catch (InvalidOrderDataException ex)
        {
            // 4. Poison message: Move directly to Dead-Letter Queue with error reason
            await args.DeadLetterMessageAsync(args.Message, "InvalidOrderPayload", ex.Message);
        }
    };
    
    processor.ProcessErrorAsync += args =>
    {
        Console.WriteLine($"[ERROR] {args.Exception.Message}");
        return Task.CompletedTask;
    };
    
    await processor.StartProcessingAsync();
    Console.WriteLine("Worker listening for orders. Press [Enter] to exit.");
    Console.ReadLine();
    await processor.StopProcessingAsync();
OrderWorker.cs — ServiceBusProcessor Execution (.NET 8) // C# Programmatic Consumer using Azure.Messaging.ServiceBus await using var processor = client.CreateProcessor("orders-queue"); processor.ProcessMessageAsync += async args => { string body = args.Message.Body.ToString(); Console.WriteLine($"[WORKER] Order: {body}"); try { // Process order business logic... await ProcessOrderAsync(body); // 1. Settle: Complete (ACK) await args.CompleteMessageAsync(args.Message); } catch (TransientException) { // 2. Transient error: Abandon (Retry +1) await args.AbandonMessageAsync(args.Message); } catch (PoisonDataException ex) { // 3. Unrecoverable: Move to DLQ await args.DeadLetterMessageAsync(args.Message, "InvalidData", ex.Message); } }; TERMINAL: bash — dotnet run $ dotnet run --project OrderWorker [14:30:00 INFO] Authenticated via DefaultAzureCredential (Entra ID). [14:30:01 INFO] ServiceBusProcessor listening on: orders-queue [14:30:05 PRODUCER] → Sent OrderBatch (3 messages) to Service Bus. [14:30:06 WORKER] ← Message Received (LockToken: 4b8e21f9...) Payload: {"orderId": "ORD-2026-904", "amount": 250.00} [14:30:07 SETTLE] ✔ Order ORD-2026-904 processed successfully. [14:30:07 ACK] CompleteMessageAsync() executed. Msg deleted. [14:30:08 WORKER] ← Message Received (LockToken: 9c12a81f...) Payload: {"orderId": "ORD-2026-905", "amount": 115.50} [14:30:09 ACK] CompleteMessageAsync() executed. Msg deleted. ● Processing stream healthy. Active queue depth: 0 messages.
Screenshot 7: Visual Studio Code — Live execution of C# producer sending order batches and background processor settling messages via Peek-Lock.
8

Monitor Queue Depth & Configure Dead-Letter Alerts

Operational excellence in Service Bus requires observing active queue depth, latency, and setting proactive alerts whenever poison messages arrive in the Dead-Letter Queue.

  1. In the namespace left sidebar under Monitoring, select Metrics.
  2. Add the key operational metrics:
    • Incoming Messages (Sum): Ingress message rate from senders.
    • Outgoing Messages (Sum): Consumption and settlement rate by workers.
    • Dead-lettered Messages (Average): Messages quarantined in the DLQ.
  3. Create a Poison Message Alert Rule:
    • Click + New alert rule on the metrics toolbar.
    • Signal: Dead-lettered Messages.
    • Threshold: Set Greater than 0 over a 5-minute aggregation window.
    • Action Group: Assign your DevOps PagerDuty / Email on-call group.
    • Severity: Sev 2 (Warning) or Sev 1 (Error).
  4. Save the alert rule to ensure operational teams are notified immediately when a poison message arrives for manual root-cause inspection.
Microsoft Azure 🔍 Search resources, services, and docs (G+/) ⚙️ 🔔 ❓ admin@company.com sb-ecommerce-prod > Monitoring > Metrics Metrics: sb-ecommerce-prod Time range: Last 4 hours • Granularity: 5 minutes Metric 1: Incoming Messages (Sum) Metric 2: Outgoing Messages (Sum) Metric 3: Dead-lettered Messages (Avg) 2 Poison Msgs 20:00 • 21:00 • 22:00 • 23:00 ⚠️ Azure Monitor Alert Rule Triggered — Severity: 2 (Warning) Condition: 'Average Dead-lettered Messages > 0' on queue: orders-queue Action Group: DevOps-PagerDuty & Email • Status: Fired at 22:35 UTC • Poison inspection recommended.
Screenshot 8: Azure Portal — Azure Monitor Metrics chart and automated Dead-Letter Queue trigger alert notification.

When to use it

Not the same as its neighbours. Event Grid delivers reactive events to handlers and does not queue them; Event Hubs ingests telemetry streams for high-throughput analytics; Storage Queues offer a simpler, cheaper queue without topics, sessions or ordering. Service Bus is the choice when you need brokered messaging with those guarantees.

Related in this knowledge base