⚡ Azure Data Streaming

Azure Event Hubs
Complete Guide

From beginner to architecture level — partitions, consumer groups, Capture, Kafka protocol, Schema Registry, Function Apps, Stream Analytics, security, monitoring, geo-DR, and every real-time streaming pattern you need.

Beginner → Architecture21 SectionsMillions Events/secKafka CompatibleSDK + REST Examples

01What Is Azure Event Hubs?

Azure Event Hubs is a fully managed, real-time data ingestion service capable of receiving and processing millions of events per second. It acts as the "front door" for an event pipeline — a highly scalable publish-subscribe system for streaming telemetry, logs, clickstreams, IoT data, and any high-throughput event stream. It is not a queue; it is a log.

📡
Massive Ingestion
Ingest millions of events per second from any source — devices, apps, services, external systems
🗂️
Partitioned Log
Events are appended to ordered, immutable partition logs — consumers read at their own pace
Kafka Compatible
Drop-in replacement for Apache Kafka — existing Kafka apps work with zero code changes
💾
Capture to Storage
Automatically archive all events to Blob Storage or Data Lake in Avro / Parquet format
🔁
Replay
Events retained up to 90 days — any consumer can replay the full event stream independently
⚖️
Auto-Inflate
Automatically scale throughput units up when needed — no manual intervention required

02Core Concepts & Terminology

Understanding Event Hubs terminology is essential for designing efficient streaming architectures. These concepts map directly to how data flows through partitions, how consumers track progress, and how you scale throughput for real-time workloads.

TermDefinition
NamespaceContainer for Event Hubs. Unique DNS: <namespace>.servicebus.windows.net
Event HubA named stream within a namespace — analogous to a Kafka topic
PartitionOrdered, immutable sequence of events within an Event Hub. Events are distributed across partitions.
EventThe data unit — a byte array payload plus metadata (properties, offset, sequence number, timestamp)
ProducerAny client that publishes events to an Event Hub
ConsumerAny client that reads events from a partition
Consumer GroupA logical view of the entire Event Hub. Each consumer group tracks its own offsets independently.
OffsetPosition of an event within a partition. Consumers checkpoint their offset to resume after restart.
Sequence NumberMonotonically increasing integer per partition — uniquely identifies event position
Throughput Unit (TU)Standard tier capacity unit: 1 MB/s ingress, 2 MB/s egress per TU
Processing Unit (PU)Premium tier capacity unit — more powerful than a TU
CheckpointConsumer saves its current offset so it can resume from that position after restart
EventProcessorClientSDK client that handles partition distribution, checkpointing, and load balancing automatically

03Tiers — Basic / Standard / Premium / Dedicated

Choosing the right tier determines your throughput ceiling, retention limits, and network isolation capabilities. Each tier is designed for a different stage of your streaming journey — from development prototyping to enterprise-grade production workloads requiring dedicated infrastructure and compliance guarantees.

FeatureBasicStandardPremiumDedicated
Consumer Groups1 (default)Up to 20Up to 100Unlimited
Brokered Connections1001,00010,000Unlimited
Message Retention1 dayUp to 7 daysUp to 90 daysUp to 90 days
Capture✗ No✓ Yes✓ Yes✓ Yes
Schema Registry✗ No✓ Yes✓ Yes✓ Yes
Kafka Protocol✗ No✓ Yes✓ Yes✓ Yes
VNet / Private Endpoints✗ No✗ No✓ Yes✓ Yes
Dynamic Partition Scale✗ No✗ No✓ Yes✓ Yes
Availability Zones✗ No✓ Yes✓ Yes✓ Yes
Max TUs / PUs20 TUs40 TUs16 PUsCustom CUs
Pricing modelPer TU/hrPer TU/hrPer PU/hrPer CU/hr
Which Tier to Choose?Use Basic for dev/test only. Use Standard for most production streaming workloads. Use Premiumwhen you need VNet isolation, longer retention (>7d), or dynamic partition scaling. Use Dedicated for compliance, highest throughput, or complete tenant isolation.

04Partitions & Throughput Units

Partitions are the core scalability unit. Each partition is an ordered, append-only log. Events are distributed across partitions — either round-robin (no key) or by partition key(same key always goes to the same partition, enabling ordering per entity).

ConceptDetail
Default partitions4 (configurable at namespace creation — cannot be changed later on Standard)
Max partitions (Standard)32
Max partitions (Premium/Dedicated)2,000 (dynamically scalable on Premium)
Partition keyString hashed to select a partition — guarantees ordering per key
Round-robin (no key)Events distributed across all partitions — max throughput, no ordering
1 TU capacity1 MB/s or 1,000 events/s ingress; 2 MB/s egress per TU
Auto-inflateStandard/Premium: automatically scale TUs up (not down) when throttled

Partition Key Usage

csharp
// Events with same partition key → same partition → ordered
var eventData = new EventData(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(telemetry)))
{
    Properties =
    {
        ["DeviceId"] = "sensor-42",
        ["Region"]   = "EU-West"
    }
};

// Send with partition key — all events from same device go to same partition
await producerClient.SendAsync(
    new[] { eventData },
    new SendEventOptions { PartitionKey = "sensor-42" });
⚠️
Partition Count is ImmutableOn Standard tier, partition count cannot be changed after namespace creation. Choose carefully — too few partitions limits parallelism. Premium supports dynamic scaling.

05Sending & Receiving Events

Producing and consuming events is the fundamental interaction with Event Hubs. The SDK provides batching for efficient ingress and the EventProcessorClient for scalable, fault-tolerant consumption with automatic partition balancing and checkpointing across consumer instances.

Send Events — .NET SDK

csharp
var connectionString = "Endpoint=sb://<namespace>.servicebus.windows.net/;...";
var eventHubName = "telemetry";

await using var producerClient = new EventHubProducerClient(connectionString, eventHubName);

// Create a batch (respects size limits automatically)
using EventDataBatch eventBatch = await producerClient.CreateBatchAsync();

for (int i = 0; i < 100; i++)
{
    var payload = JsonSerializer.Serialize(new { deviceId = "d1", temp = 22.5 + i, ts = DateTime.UtcNow });
    var eventData = new EventData(Encoding.UTF8.GetBytes(payload));
    eventData.Properties["EventType"] = "TemperatureReading";

    if (!eventBatch.TryAdd(eventData))
    {
        // Batch full — send current and start new
        await producerClient.SendAsync(eventBatch);
    }
}

await producerClient.SendAsync(eventBatch);

Receive Events with EventProcessorClient (Recommended)

csharp
var storageClient = new BlobContainerClient(storageConnStr, "checkpoints");
var processorClient = new EventProcessorClient(
    storageClient,
    "$Default",          // consumer group
    connectionString,
    eventHubName);

processorClient.ProcessEventAsync += async args =>
{
    string body = args.Data.EventBody.ToString();
    Console.WriteLine($"Partition {args.Partition.PartitionId}: {body}");
    Console.WriteLine($"Offset: {args.Data.Offset}, SeqNo: {args.Data.SequenceNumber}");

    // Checkpoint every N events or on a timer
    await args.UpdateCheckpointAsync();
};

processorClient.ProcessErrorAsync += args =>
{
    Console.WriteLine($"Error on partition {args.PartitionId}: {args.Exception}");
    return Task.CompletedTask;
};

await processorClient.StartProcessingAsync();
Console.ReadKey();
await processorClient.StopProcessingAsync();

Send Events — Python SDK

python
from azure.eventhub import EventHubProducerClient, EventData
import json

producer = EventHubProducerClient.from_connection_string(
    conn_str="Endpoint=sb://...",
    eventhub_name="telemetry"
)

with producer:
    event_data_batch = producer.create_batch(partition_key="sensor-42")
    for i in range(100):
        payload = json.dumps({"deviceId": "sensor-42", "temp": 22.5 + i})
        event_data_batch.add(EventData(payload))
    producer.send_batch(event_data_batch)

Event Properties Reference

PropertyTypeDescription
EventBodybyte[]The raw event payload — your data
OffsetlongPosition in partition stream — unique within partition
SequenceNumberlongMonotonically increasing number per partition
EnqueuedTimeDateTimeOffsetUTC timestamp when event was accepted by Event Hubs
PartitionKeystringKey used to route event to partition (read-only on receive)
PropertiesIDictionaryUser-defined application properties (key/value metadata)
SystemPropertiesIDictionarySystem-set metadata (IoT Hub routing data, etc.)
ContentTypestringMIME type of the payload (e.g. application/json)
CorrelationIdstringCorrelation identifier for distributed tracing
MessageIdstringDeduplication identifier (Kafka interop)

06Consumer Groups

A consumer group is an independent view of the entire Event Hub stream. Each consumer group has its own offset pointers per partition — meaning multiple downstream systems can each read the full event stream independently without interfering with each other.

ScenarioConsumer Groups Needed
Stream Analytics job (analytics)analytics-cg
Azure Function (real-time processing)processor-cg
Archival service (cold path)archive-cg
ML model inferenceml-inference-cg
Debugging / replaydebug-cg
⚠️
One Reader Per Partition Per Consumer GroupAt any point, only ONE active reader should own each partition within a consumer group.EventProcessorClient handles this automatically with distributed leasing. Multiple readers in the same consumer group reading the same partition will cause duplicate processing.

Create Consumer Group via CLI

bash
az eventhubs eventhub consumer-group create \
  --resource-group myRG \
  --namespace-name myNamespace \
  --eventhub-name telemetry \
  --name analytics-cg

07Event Hubs Capture

Capture automatically archives all incoming events to Azure Blob Storage or Azure Data Lake Storage Gen2 in Avro format (Parquet also supported). This enables both real-time stream processing AND batch analytics on the same data — the classic Lambda architecture hot/cold path.

ConfigurationDescriptionDefault
Window SizeTime window before writing a file5 minutes
Window Size (bytes)Size threshold before writing a file300 MB
Naming formatPath template for captured files{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}
FormatAvro (default) or ParquetAvro
Skip empty archivesDon't write files if no events in windowOff

Enable Capture via ARM / Bicep

bicep
resource eventHub 'Microsoft.EventHub/namespaces/eventhubs@2022-01-01-preview' = {
  name: '${namespaceName}/${eventHubName}'
  properties: {
    partitionCount: 4
    messageRetentionInDays: 7
    captureDescription: {
      enabled: true
      encoding: 'Avro'
      intervalInSeconds: 300
      sizeLimitInBytes: 314572800
      skipEmptyArchives: true
      destination: {
        name: 'EventHubArchive.AzureBlockBlob'
        properties: {
          storageAccountResourceId: storageAccount.id
          blobContainer: 'eventhub-archive'
          archiveNameFormat: '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}'
        }
      }
    }
  }
}
💡
Read Captured Avro FilesUse Azure Synapse Analytics, Databricks, or theApache.Avro NuGet package to deserialize captured files. Event Hubs Capture files include a schema header and event body records.

08Schema Registry

The Event Hubs Schema Registry is a centralized repository for managing event schemas (Avro, JSON Schema, Protobuf). Producers register schemas; consumers validate incoming events against registered schemas — ensuring schema governance across producers and consumers without out-of-band coordination.

FeatureDescription
Schema GroupsLogical container for related schemas with a compatibility mode
Compatibility ModesNone, Backward, Forward, Full — controls what schema changes are allowed
Schema VersioningEach schema registration gets a unique version — old consumers still work
Supported FormatsAvro, JSON Schema, Protobuf (preview)
Cached on clientSchemas are cached locally — no registry lookup on every event

Send with Avro Schema Validation

csharp
var schemaRegistryClient = new SchemaRegistryClient(
    "<namespace>.servicebus.windows.net",
    new DefaultAzureCredential());

var serializer = new SchemaRegistryAvroSerializer(
    schemaRegistryClient,
    schemaGroupName: "my-schema-group",
    new SchemaRegistryAvroSerializerOptions { AutoRegisterSchemas = true });

var order = new Order { OrderId = "123", Amount = 99.99 };
var eventData = await serializer.SerializeAsync<EventData, Order>(order);

await producerClient.SendAsync(new[] { eventData });

09Kafka Protocol Support

Event Hubs Standard and above expose a Kafka-compatible endpoint on port 9093. Existing Kafka producers and consumers can point at Event Hubs with minimal config changes — no code changes required for most workloads.

Kafka Producer Config (Java)

properties
bootstrap.servers=<namespace>.servicebus.windows.net:9093
security.protocol=SASL_SSL
sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
    username="$ConnectionString" \
    password="Endpoint=sb://<namespace>.servicebus.windows.net/;SharedAccessKeyName=...";

# Event Hub name = Kafka topic name
key.serializer=org.apache.kafka.common.serialization.StringSerializer
value.serializer=org.apache.kafka.common.serialization.StringSerializer
Kafka ConceptEvent Hubs Equivalent
BrokerEvent Hubs namespace endpoint
TopicEvent Hub
PartitionPartition
Consumer GroupConsumer Group
OffsetOffset
Topic RetentionMessage retention (1–90 days)
Replication FactorManaged internally — not user-configurable
__consumer_offsetsManaged internally by Event Hubs
Unsupported Kafka FeaturesEvent Hubs does not support Kafka Streams, Kafka Connect (use Azure alternatives), compacted topics, or transactions. Check the compatibility matrix in Microsoft docs before migrating complex Kafka workloads.

10Security & Authentication

Securing your Event Hubs namespace is critical since it often carries sensitive telemetry and business data at high volume. Prefer Managed Identity with Entra ID RBAC over connection strings — this eliminates secret rotation overhead and reduces the blast radius of credential leaks in real-time streaming pipelines.

MethodTypeRecommended?
Connection String / SASShared Access Signature⚠️ Dev/test only
SAS Policy (scoped)Shared key scoped to namespace/hub✓ Acceptable
Managed IdentityEntra ID token✅ Recommended
Service PrincipalEntra ID token✅ Recommended

Managed Identity — Zero Secrets

csharp
// Uses DefaultAzureCredential — works with Managed Identity, VS, CLI
var credential = new DefaultAzureCredential();
var producerClient = new EventHubProducerClient(
    "<namespace>.servicebus.windows.net",
    "telemetry",
    credential);

var processorClient = new EventProcessorClient(
    checkpointStore,
    "$Default",
    "<namespace>.servicebus.windows.net",
    "telemetry",
    credential);

RBAC Roles

RolePermissions
Azure Event Hubs Data OwnerFull access — send, receive, manage
Azure Event Hubs Data SenderSend (produce) events only
Azure Event Hubs Data ReceiverReceive (consume) events only
Schema Registry ContributorRead and write schemas
Schema Registry ReaderRead schemas only
bash
# Assign Sender role to a Managed Identity
az role assignment create \
  --assignee <principal-id> \
  --role "Azure Event Hubs Data Sender" \
  --scope /subscriptions/<sub>/resourceGroups/<rg>/providers/\
Microsoft.EventHub/namespaces/<namespace>/eventhubs/<eventhub>

11Network Security & VNet

Network isolation ensures your streaming data never traverses the public internet. For production workloads handling sensitive real-time data, use Private Endpoints to route traffic exclusively through your VNet — this is especially important for compliance-driven architectures where data exfiltration risks must be minimized.

FeatureBasicStandardPremiumDedicated
IP Filtering✓ Yes✓ Yes✓ Yes✓ Yes
VNet Service Endpoints✗ No✓ Yes✓ Yes✓ Yes
Private Endpoints✗ No✗ No✓ Yes✓ Yes
Disable Public Network Access✗ No✗ No✓ Yes✓ Yes

Private Endpoint via CLI

bash
# Create private endpoint for Event Hubs namespace
az network private-endpoint create \
  --name myEventHubPrivateEndpoint \
  --resource-group myRG \
  --vnet-name myVNet \
  --subnet mySubnet \
  --private-connection-resource-id /subscriptions/<sub>/resourceGroups/<rg>/providers/\
Microsoft.EventHub/namespaces/<namespace> \
  --group-ids namespace \
  --connection-name myPrivateEndpointConnection

# Create Private DNS Zone for resolution
az network private-dns zone create \
  --resource-group myRG \
  --name privatelink.servicebus.windows.net

12Logic Apps Integration

Logic Apps provides a low-code way to react to Event Hub events and orchestrate downstream workflows. Use it for moderate-volume scenarios where you need to fan out events to multiple SaaS connectors, transform payloads, or trigger approval workflows — all without writing custom consumer code.

Action / TriggerDirectionDescription
When events are available in Event HubTriggerPoll Event Hub on an interval; fire when events exist
Send eventActionPublish an event to an Event Hub from a workflow
Get events (batch)ActionRetrieve a batch of events for bulk processing

Event Hub Trigger in Logic App (JSON)

json
{
  "triggers": {
    "When_events_are_available_in_Event_Hub": {
      "type": "ApiConnection",
      "inputs": {
        "host": {
          "connection": {
            "name": "@parameters('$connections')['eventhubs']['connectionId']"
          }
        },
        "method": "get",
        "path": "/@{encodeURIComponent('telemetry')}/events/batch/head",
        "queries": {
          "consumerGroupName": "logicapps-cg",
          "contentType": "application/json",
          "maximumEventsCount": 50
        }
      },
      "recurrence": { "frequency": "Second", "interval": 30 }
    }
  }
}
💡
Logic Apps vs Functions for Event HubsFor high-throughput event processing, prefer Azure Functions with EventHubTrigger — it scales automatically per partition. Use Logic Apps for lower-volume orchestration workflows that need to react to events and call many downstream services.

13Function Apps Integration

Azure Functions is the most common compute layer for Event Hubs processing. The EventHubTrigger automatically scales function instances per partition, handles checkpointing, and supports batch processing — making it ideal for high-throughput real-time event transformation, enrichment, and routing.

Event Hub Trigger

csharp
[FunctionName("ProcessTelemetry")]
public static async Task Run(
    [EventHubTrigger(
        "telemetry",
        Connection = "EventHubConnection",
        ConsumerGroup = "processor-cg")]
    EventData[] events,
    PartitionContext partitionContext,
    ILogger log)
{
    log.LogInformation($"Partition: {partitionContext.PartitionId}, Count: {events.Length}");

    foreach (EventData eventData in events)
    {
        string messageBody = Encoding.UTF8.GetString(eventData.Body.Array,
            eventData.Body.Offset, eventData.Body.Count);
        var telemetry = JsonSerializer.Deserialize<TelemetryEvent>(messageBody);

        log.LogInformation($"Device: {telemetry.DeviceId}, Temp: {telemetry.Temperature}");
        await ProcessTelemetryAsync(telemetry);
    }
}

Output Binding — Send to Event Hub

csharp
[FunctionName("ForwardToEventHub")]
[return: EventHub("output-hub", Connection = "EventHubConnection")]
public static string Run(
    [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req,
    ILogger log)
{
    string body = new StreamReader(req.Body).ReadToEnd();
    return body; // Sent directly to output-hub
}

// Multiple events output
[FunctionName("BatchForward")]
public static async Task Run(
    [EventHubTrigger("input-hub", Connection = "EventHubConnection")] EventData[] events,
    [EventHub("output-hub", Connection = "EventHubConnection")] IAsyncCollector<string> outputEvents)
{
    foreach (var e in events)
    {
        var enriched = EnrichEvent(e.Body.ToString());
        await outputEvents.AddAsync(enriched);
    }
}

host.json — Tuning Event Hub Trigger

json
{
  "version": "2.0",
  "extensions": {
    "eventHubs": {
      "batchCheckpointFrequency": 5,
      "eventProcessorOptions": {
        "maxBatchSize": 256,
        "prefetchCount": 512
      },
      "initialOffsetOptions": {
        "type": "fromStart"
      }
    }
  }
}
host.json SettingDescriptionDefault
maxBatchSizeMax events per function invocation10
prefetchCountEvents pre-fetched from partition into local buffer300
batchCheckpointFrequencyCheckpoint every N batches1
initialOffsetOptions.typefromStart, fromEnd, fromEnqueuedTimefromStart

14Stream Analytics Integration

Azure Stream Analytics uses Event Hubs as its primary streaming input. Define SQL-like queries to filter, aggregate, join, and transform streams in real time — with outputs to SQL, Cosmos DB, Blob Storage, Power BI, Service Bus, and more.

sql
-- Real-time aggregation: avg temperature per device per 5-minute tumbling window
SELECT
    DeviceId,
    AVG(Temperature)    AS AvgTemp,
    MAX(Temperature)    AS MaxTemp,
    MIN(Temperature)    AS MinTemp,
    COUNT(*)            AS EventCount,
    System.Timestamp()  AS WindowEnd
INTO [sql-output]
FROM [eventhub-input] TIMESTAMP BY EnqueuedTime
GROUP BY
    DeviceId,
    TumblingWindow(minute, 5)

-- Alert when temperature exceeds threshold
SELECT
    DeviceId,
    Temperature,
    System.Timestamp() AS AlertTime
INTO [servicebus-alerts]
FROM [eventhub-input] TIMESTAMP BY EnqueuedTime
WHERE Temperature > 85.0
Window TypeDescriptionUse Case
TumblingFixed-size, non-overlapping windowsRegular aggregation (every 5 min)
HoppingFixed-size, overlapping windowsMoving average (5-min window, 1-min hop)
SlidingFires whenever an event enters or leaves the windowContinuous metric tracking
SessionGroups events by activity gapsUser session analytics
SnapshotGroups events with the same timestampBatch processing

15Event Hubs vs Service Bus

Event Hubs and Service Bus solve different messaging problems. Event Hubs is a high-throughput streaming log optimized for telemetry ingestion and replay, while Service Bus is a transactional message broker for reliable command/task processing. Choose based on whether you need stream replay and massive scale, or guaranteed delivery with dead-lettering and sessions.

DimensionEvent HubsService Bus
Primary purposeHigh-throughput event ingestion & streamingReliable enterprise message brokering
Messaging modelPartitioned log — consumers pull at own paceQueue / Topic — competitive or pub-sub
Message deletionAfter retention period (not on consume)On successful completion
OrderingPer partition (with partition key)FIFO with sessions
Max throughputMillions events/sec~1 million messages/sec (Premium)
Max message size1 MB (Standard), 1 MB (Premium)256 KB (Standard), 100 MB (Premium)
Dead-Letter Queue✗ No✓ Yes
Message TTL / expiry✓ Yes✓ Yes
Transactions✗ No✓ Yes
Replay events✓ Yes✗ No
Consumer groups✓ YesVia topic subscriptions
Kafka compatible✓ Yes✗ No
Use whenTelemetry, logs, clickstreams, IoT dataOrder processing, workflows, task queues

16Event Hubs vs Event Grid

Event Hubs and Event Grid are complementary services often used together. Event Hubs excels at ingesting continuous high-volume data streams with replay capability, while Event Grid is a reactive eventing fabric that pushes discrete state-change notifications to subscribers. Use Event Hubs when you need ordered, replayable streams and Event Grid when you need instant push-based reactions to Azure resource events.

DimensionEvent HubsEvent Grid
PurposeIngest & stream high-volume telemetry dataReact to discrete events across Azure services
ThroughputMillions events/sec (streaming)~10M events/sec (eventing)
Event sizeUp to 1 MBUp to 1 MB
Retention1–90 days (time-based)24 hours (retry), then dead-letter
Pull vs PushPull (consumers read at own pace)Push (Event Grid delivers to handlers)
OrderingPer-partition orderingNo ordering guarantee
Replay✓ Yes✗ No
Fan-out to multiple consumersVia consumer groupsVia subscriptions to same topic
Use whenIoT telemetry, logs, stream processing pipelinesReacting to blob created, resource changes, custom events
💡
Using All Three TogetherA common pattern: IoT devices → Event Hubs (ingest millions/sec) → Stream Analytics (real-time processing) → alerts to Service Bus (reliable delivery) + Event Grid (trigger downstream workflows reactively).

17Monitoring & Diagnostics

Proactive monitoring is essential for real-time streaming systems where data loss or processing delays have immediate business impact. Track throttling, consumer lag, and error rates to detect issues before they cascade — and use KQL queries in Log Analytics to build dashboards and automated alerts for your Event Hubs namespace.

MetricDescriptionAlert Condition
Incoming MessagesEvents published per intervalSignificant drop = producer issue
Outgoing MessagesEvents consumed per intervalDrop = consumer lag issue
Incoming BytesData volume ingressApproaching TU limit
Outgoing BytesData volume egressApproaching TU limit
Throttled RequestsRequests exceeding TU quota> 0 — add TUs or enable auto-inflate
Captured MessagesEvents written by CaptureMonitor against Incoming
Consumer Lag (preview)How far behind each consumer group isGrowing lag = slow consumer
Server ErrorsInternal Event Hubs errors> 0 — alert immediately

KQL — Throttled Requests in Last Hour

kql
AzureMetrics
| where ResourceType == "MICROSOFT.EVENTHUB/NAMESPACES"
| where MetricName == "ThrottledRequests"
| where TimeGenerated > ago(1h)
| summarize TotalThrottled = sum(Total) by bin(TimeGenerated, 5m), Resource
| where TotalThrottled > 0
| order by TimeGenerated desc

KQL — Consumer Group Lag

kql
AzureDiagnostics
| where ResourceType == "EVENTHUBS"
| where Category == "ArchiveLogs"
| project TimeGenerated, EventHubName_s, PartitionId_s,
          OffsetSequenceNumber_d, LastSequenceNumber_d
| extend Lag = LastSequenceNumber_d - OffsetSequenceNumber_d
| where Lag > 10000
| order by Lag desc

18Geo-DR & High Availability

FeatureDescriptionTier
Geo-Disaster Recovery (Metadata)Replicate namespace config to secondary region; manual failover via alias. Messages NOT replicated.Standard+
Availability Zones3-zone redundancy within a region — automatic, no config neededStandard+
Geo-Replication (Preview)Full event replication across regions in near real-timePremium
Zone Redundant NamespacesNamespace resilient to single AZ failureStandard+
⚠️
Geo-DR Does Not Replicate MessagesStandard Geo-DR replicates only namespace metadata (Event Hub configs, consumer groups, policies). In a failover scenario, events not yet processed from the primary region are lost. Use Geo-Replication (Premium) or design producers to dual-write for full message HA.

Configure Geo-DR Alias via CLI

bash
# Pair primary and secondary namespaces
az eventhubs georecovery-alias create \
  --resource-group myRG \
  --namespace-name myPrimaryNamespace \
  --alias myGeoAlias \
  --partner-namespace /subscriptions/<sub>/resourceGroups/<rg>/providers/\
Microsoft.EventHub/namespaces/mySecondaryNamespace

# Producers/consumers always use the alias endpoint:
# myGeoAlias.servicebus.windows.net

# Initiate failover (irreversible — use with care)
az eventhubs georecovery-alias fail-over \
  --resource-group myRG \
  --namespace-name mySecondaryNamespace \
  --alias myGeoAlias

19Architecture Patterns

Event Hubs sits at the center of most Azure real-time architectures. These proven patterns show how to combine Event Hubs with downstream compute and storage services to build end-to-end streaming solutions — from IoT telemetry pipelines to clickstream analytics and Kafka migration strategies.

🌡️
IoT Telemetry Pipeline
Millions of devices → Event Hubs → Stream Analytics (anomaly detection) + Capture (cold storage) + Function Apps (alerts)
🔥
Hot / Cold Path (Lambda)
Event Hubs fans out to Stream Analytics (real-time hot path) and Capture → Databricks (batch cold path)
📊
Clickstream Analytics
Web/app events → Event Hubs → Stream Analytics → Cosmos DB (live dashboards) + Synapse (historical reports)
🔄
Log Aggregation
Multiple microservices emit structured logs → Event Hubs → Function App → Log Analytics Workspace
🤖
ML Feature Store
Raw events → Event Hubs → Databricks streaming → Feature Store → model serving in real time
🌉
Kafka Migration
Existing Kafka producers point to Event Hubs Kafka endpoint — zero-code migration with managed infrastructure

20Pricing Overview

Event Hubs pricing is based on throughput units (or processing units for Premium), ingress event count, and optional features like Capture and extended retention. Understanding the cost model helps you right-size your streaming infrastructure — over-provisioning TUs wastes budget while under-provisioning causes throttling and data loss.

Standard Tier

ResourcePrice (approx)
Throughput Unit (per hour)~$0.015/TU/hr (~$11/TU/month)
Ingress events (per million)~$0.028
Capture (per hour per TU)~$0.028
Extended retention (per GB/month)~$0.012

Premium Tier

ResourcePrice (approx)
Processing Unit 1 (PU1)~$730/month
Processing Unit 2 (PU2)~$1,460/month
CaptureIncluded
Schema RegistryIncluded
💰
Cost OptimizationEnable Auto-inflate on Standard to avoid throttling without over-provisioning TUs. Use Capture skip empty archives to avoid paying for empty Avro files. Monitor consumer lag — a slow consumer doesn't reduce your bill but may force longer (and costlier) retention.

21Quick Reference Cheat Sheet

Keep this cheat sheet handy for connection string formats, SDK patterns, and service limits. These are the most frequently referenced values when building and debugging Event Hubs streaming applications in production.

Connection Strings & Endpoints
text
# Namespace endpoint (AMQP)
sb://<namespace>.servicebus.windows.net

# Kafka-compatible endpoint
<namespace>.servicebus.windows.net:9093

# Connection string format
Endpoint=sb://<namespace>.servicebus.windows.net/;
SharedAccessKeyName=<policy>;SharedAccessKey=<key>;
EntityPath=<eventhub-name>

# Managed Identity endpoint
https://<namespace>.servicebus.windows.net
Key SDK Calls (.NET)
csharp
// Produce
var producer = new EventHubProducerClient(namespace, hubName, credential);
using var batch = await producer.CreateBatchAsync();
batch.TryAdd(new EventData(Encoding.UTF8.GetBytes("payload")));
await producer.SendAsync(batch);

// Send with partition key
await producer.SendAsync(events, new SendEventOptions { PartitionKey = "device-1" });

// Send to specific partition
await producer.SendAsync(events, new SendEventOptions { PartitionId = "0" });

// Consume (recommended)
var processor = new EventProcessorClient(checkpointStore, "$Default", namespace, hubName, credential);
processor.ProcessEventAsync += async args => { ...; await args.UpdateCheckpointAsync(); };
await processor.StartProcessingAsync();

// Peek partition info
var props = await producer.GetEventHubPropertiesAsync();
var partProps = await producer.GetPartitionPropertiesAsync("0");
LimitStandardPremiumDedicated
Max namespaces per subscriptionUnlimitedUnlimitedUnlimited
Max Event Hubs per namespace101001,000
Max partitions per Event Hub322,000 (dynamic)2,000
Max consumer groups per Event Hub20100Unlimited
Max message size1 MB1 MB1 MB
Max retention7 days90 days90 days
Max TU / PU40 TU16 PUCustom
Throughput per TU1 MB/s in, 2 MB/s outN/AN/A