Event Grid vs Event Hubs — Choosing the Right Event Service
Overview
Azure provides multiple event services, and choosing the right one is crucial for your architecture. Event Grid is designed for event routing and pub/sub patterns - think notifications and reactions. Event Hubs is built for high-throughput streaming - think telemetry and analytics. Understanding the differences helps you build efficient, cost-effective solutions.
What You'll Learn
- Core differences between Event Grid and Event Hubs
- When to use each service
- Performance and scaling characteristics
- Real-world scenario recommendations
Quick Comparison
| Feature | Event Grid | Event Hubs |
|---|---|---|
| Primary Use | Event routing, pub/sub | Event streaming, telemetry |
| Delivery Model | Push (webhook, queue) | Pull (consumer groups) |
| Throughput | Thousands/sec | Millions/sec |
| Event Size | Up to 1MB | Up to 1MB |
| Ordering | Per event | Per partition |
| Retention | 24 hours default | 1-7 days |
| Pricing | Per operation | Per throughput unit |
| Filtering | Subject, type, data | Partition keys |
When to Use Event Grid
Use Cases
┌─────────────────────────────────────────────────────────────────┐
│ EVENT GRID USE CASES │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ✓ React to resource changes (VM created, blob uploaded) │
│ ✓ Application events (order placed, user registered) │
│ ✓ System events (Azure service health, alerts) │
│ ✓ Pub/Sub with multiple subscribers │
│ ✓ Simple one-way notifications │
│ ✓ Low latency (sub-second) delivery │
│ │
└─────────────────────────────────────────────────────────────────┘
Example: React to Blob Created
// Subscribe to blob created events
await EventGridClient.EventSubscriptions.CreateOrUpdateAsync(
resourceGroupName: "my-rg",
namespaceName: "my-namespace",
eventSubscriptionName: "blob-processor",
eventSubscription: new EventSubscription
{
Destination = new WebHookEventSubscriptionDestination
{
EndpointUrl = "https://myfunction.azurewebsites.net/api/BlobTrigger"
},
Filter = new EventSubscriptionFilter
{
SubjectBeginsWith = "/blobServices/default/containers/uploads/",
EventType = new[] { "Microsoft.Storage.BlobCreated" }
}
});
Example: Order Processing Workflow
{
"id": "order-12345",
"eventType": "OrderPlaced",
"subject": "orders/new",
"data": {
"orderId": "12345",
"customerId": "cust-001",
"total": 99.99,
"items": ["item1", "item2"]
},
"eventTime": "2024-05-01T10:00:00Z"
}
When to Use Event Hubs
Use Cases
┌─────────────────────────────────────────────────────────────────┐
│ EVENT HUBS USE CASES │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ✓ High-volume telemetry (IoT, logs, metrics) │
│ ✓ Click-stream analytics │
│ ✓ Audit logs and compliance │
│ ✓ Transaction processing │
│ ✓ Big data pipelines (Spark, Data Lake) │
│ ✓ Millions of events per second │
│ │
└─────────────────────────────────────────────────────────────────┘
Example: IoT Telemetry Ingestion
var connectionString = "Endpoint=sb://my-namespace.servicebus.windows.net/;SharedAccessKeyName=...";
var eventHubClient = EventHubClient.CreateFromConnectionString(connectionString);
// Send telemetry from IoT device
var eventData = new EventData(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(new
{
deviceId = "device-001",
temperature = 23.5,
humidity = 65,
timestamp = DateTime.UtcNow
})));
await eventHubClient.SendAsync(eventData);
Example: Processing with Consumer Group
var consumer = new EventProcessorClient(
storageConnectionString,
"checkpoint-container",
"my-event-hub",
"my-consumer-group");
await processor.StartProcessingAsync();
async Task ProcessEventBatchAsync(ProcessEventArgs args)
{
foreach (var evt in args.Events)
{
var telemetry = JsonSerializer.Deserialize<Telemetry>(evt.Body.ToArray());
await ProcessTelemetryAsync(telemetry);
}
await args.UpdateCheckpointAsync();
}
Real-Time Scenarios
Scenario 1: Order Processing (Event Grid)
// Order placed event triggers multiple reactions
{
"eventType": "OrderPlaced",
"subject": "orders/12345",
"data": { "orderId": "12345", "total": 150.00 }
}
↓ Triggers:
├── Send confirmation email (Logic App)
├── Update inventory (Azure Function)
├── Notify fulfillment team (Teams)
└── Update analytics dashboard
Why Event Grid: Multiple subscribers, event routing, low latency
Scenario 2: IoT Data Pipeline (Event Hubs)
IoT Devices (thousands)
│
▼
┌───────────────────┐
│ Event Hubs │ ← Millions of events/sec
│ (throughput) │
└────────┬──────────┘
│
▼ (Consumer Groups)
┌────────┴──────────┐ ┌──────────────┐ ┌─────────────┐
│ Real-time alerts │ │ Data Lake │ │ Batch ML │
│ (Azure Function) │ │ (Storage) │ │ (Spark) │
└───────────────────┘ └──────────────┘ └─────────────┘
Why Event Hubs: High throughput, consumer groups, partition support
Scenario 3: File Processing Pipeline
// File uploaded triggers processing (Event Grid)
{
"eventType": "Microsoft.Storage.BlobCreated",
"subject": "/blobServices/default/containers/data/blobs/sales.csv",
"data": { "url": "https://.../sales.csv" }
}
// Azure Function processes the file
public async Task Run([EventGridTrigger] EventGridEvent eventGridEvent)
{
var blobUrl = eventGridEvent.Data["url"].ToString();
// Read and process
var data = await ReadCsvAsync(blobUrl);
var summary = ProcessData(data);
// Publish summary event (Event Grid)
await eventGridPublisher.PublishAsync(new EventGridEvent
{
EventType = "DataProcessingComplete",
Subject = $"processing/{eventGridEvent.Id}",
Data = summary
});
}
Scenario 4: Hybrid: Both Services
Use both together for comprehensive event handling:
┌─────────────────────────────────────────────────────────────────┐
│ HYBRID PATTERN │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Event Hubs (Ingestion) │
│ ├── Captures ALL raw events (high throughput) │
│ └── Long-term storage in Data Lake │
│ │
│ Event Grid (Reactive) │
│ ├── Triggers immediate actions (notifications, validation) │
│ └── Routes to downstream services │
│ │
└─────────────────────────────────────────────────────────────────┘
Decision Guide
┌─────────────────────────────────────────────────────────────────┐
│ DECISION FLOWCHART │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Is it high-volume streaming? │
│ YES → Event Hubs │
│ NO ↓ │
│ Need multiple consumers with different processing? │
│ YES → Event Hubs (consumer groups) │
│ NO ↓ │
│ Is it simple event routing to handlers? │
│ YES → Event Grid │
│ NO ↓ │
│ Need push-based delivery (webhooks)? │
│ YES → Event Grid │
│ NO ↓ │
│ Is it pub/sub with filtering? │
│ YES → Event Grid │
│ NO ↓ │
│ Default: Event Grid (simpler) │
│ │
└─────────────────────────────────────────────────────────────────┘
Pricing Comparison
| Operation | Event Grid | Event Hubs |
|---|---|---|
| Publish | $0.50/1M events | Included in TU |
| Delivery | $0.50/1M events | Included in TU |
| Webhook | $0.10/1M calls | N/A |
| Storage | N/A | $0.02/GB/month |
Summary
- Event Grid - Event routing, pub/sub, reactive workflows
- Event Hubs - High-throughput streaming, analytics, telemetry
- Use both together for comprehensive event handling
- Choose based on throughput needs and delivery model