Core Concepts

Understanding Event Grid's building blocks is essential before you create your first subscription. This guide covers every core concept — topics, subscriptions, events, handlers, schemas, delivery guarantees, retries, and dead-lettering.

Architecture Diagram

┌─────────────────────────────────────────────────────────────────────┐
│                         Azure Event Grid                            │
│                                                                     │
│  ┌───────────┐       ┌──────────────┐       ┌─────────────────┐     │
│  │  TOPICS   │       │SUBSCRIPTIONS │       │ EVENT HANDLERS  │     │
│  │           │       │  (filters)   │       │                 │     │
│  │ System    │──────▶│ Sub A ───────│──────▶│ Azure Function  │     │
│  │ Topics    │       │              │       │                 │     │
│  │           │──────▶│ Sub B ───────│──────▶│ Logic App       │     │
│  │ Custom    │       │              │       │                 │     │
│  │ Topics    │──────▶│ Sub C ───────│──────▶│ Webhook / Queue │     │
│  └───────────┘       └──────────────┘       └─────────────────┘     │
│                              │                                      │
│                              ▼                                      │
│                     ┌──────────────┐                                │
│                     │ Dead-Letter  │                                │
│                     │  Storage     │                                │
│                     └──────────────┘                                │
└─────────────────────────────────────────────────────────────────────┘

Topics

A topic is an endpoint where event sources send events. Think of it as a channel or category that groups related events together.

Topic TypeCreated ByExample
System TopicAzure automatically (when you subscribe to a service's events)Blob Storage events, Key Vault events
Custom TopicYou, the developerYour application's domain events
Partner TopicThird-party SaaS providersAuth0, SAP, Datadog events
# Create a custom topic
az eventgrid topic create \
  --name my-app-events \
  --resource-group my-rg \
  --location eastus

# Get the endpoint URL for publishing events
az eventgrid topic show \
  --name my-app-events \
  --resource-group my-rg \
  --query "endpoint" --output tsv

# Get the access key for authentication
az eventgrid topic key list \
  --name my-app-events \
  --resource-group my-rg \
  --query "key1" --output tsv

Event Subscriptions

A subscription tells Event Grid: "Send events matching these criteria to this handler." Each topic can have multiple subscriptions, enabling fan-out.

Subscriptions define:

  • Which events to receive (via filters on event type, subject, or data fields)
  • Where to send them (the handler endpoint)
  • How to handle failures (retry policy, dead-letter destination)
# Create a subscription that sends blob events to a Function
az eventgrid event-subscription create \
  --name blob-to-function \
  --source-resource-id "/subscriptions/{sub-id}/resourceGroups/my-rg/providers/Microsoft.Storage/storageAccounts/mystorageacct" \
  --endpoint "https://my-func.azurewebsites.net/api/ProcessBlob" \
  --endpoint-type webhook \
  --included-event-types Microsoft.Storage.BlobCreated

Events (Structure)

Every event in Event Grid is a JSON object with a standard envelope:

{
  "id": "b2d1e4a0-3c7f-4e8b-9a1d-5f6e7c8d9a0b",
  "topic": "/subscriptions/{sub-id}/resourceGroups/my-rg/providers/Microsoft.Storage/storageAccounts/mystorageacct",
  "subject": "/blobServices/default/containers/images/blobs/photo.jpg",
  "eventType": "Microsoft.Storage.BlobCreated",
  "eventTime": "2024-01-15T10:30:00.1234567Z",
  "data": {
    "api": "PutBlob",
    "contentType": "image/jpeg",
    "contentLength": 524288,
    "url": "https://mystorageacct.blob.core.windows.net/images/photo.jpg"
  },
  "dataVersion": "1",
  "metadataVersion": "1"
}
FieldPurpose
idUnique identifier for deduplication
topicFull resource path of the event source
subjectPublisher-defined path for filtering (e.g., blob path)
eventTypeType of event (used for filtering)
eventTimeUTC timestamp when the event was generated
dataEvent-specific payload (varies by source)
dataVersionSchema version of the data object
metadataVersionSchema version of the envelope (always "1")

Event Handlers

An event handler is any endpoint that receives events. Event Grid supports these handler types:

HandlerUse CaseNotes
Azure FunctionsServerless compute, most common handlerNative integration, auto-scales
Logic AppsWorkflow orchestration, no-codeBuilt-in Event Grid connector
WebhooksAny HTTP endpoint (your API, third-party)Must pass validation handshake
Storage QueuesBuffering events for batch processingEvents stored as queue messages
Service Bus Queues/TopicsEnterprise messaging integrationOrdered processing downstream
Event HubsHigh-throughput forwarding to streaming pipelineBridge to analytics
Hybrid ConnectionsDeliver to on-premises endpointsVia Azure Relay

Event Schema Options

Event Grid supports two schemas:

SchemaStandardBest For
Event Grid SchemaAzure-nativeAzure-only workloads, simplest setup
CloudEvents 1.0CNCF open standardMulti-cloud, portability, interoperability

You choose the schema when creating a topic or subscription. System topics always emit Event Grid schema, but you can configure subscriptions to receive CloudEvents format.

Delivery Guarantees (At-Least-Once)

Event Grid provides at-least-once delivery:

  • Every event is delivered at least one time to each matching subscription
  • In rare cases (network issues, retries), an event may be delivered more than once
  • Your handler should be idempotent — processing the same event twice must produce the same result

Use the id field to detect and deduplicate repeated deliveries.

Retry Policy

When delivery fails (HTTP status 4xx or 5xx), Event Grid retries with exponential backoff:

SettingDefaultConfigurable Range
Max delivery attempts301–30
Event time-to-live (TTL)1440 minutes (24 hours)1–1440 minutes
# Create subscription with custom retry policy
az eventgrid event-subscription create \
  --name my-sub \
  --source-resource-id "/subscriptions/{sub-id}/resourceGroups/my-rg/providers/Microsoft.Storage/storageAccounts/myacct" \
  --endpoint "https://my-api.azurewebsites.net/api/events" \
  --max-delivery-attempts 10 \
  --event-ttl 120

Retry schedule: 10 seconds, 30 seconds, 1 minute, 5 minutes, 10 minutes, 30 minutes, 1 hour — then hourly until TTL expires or max attempts reached.

Dead-Lettering Basics

When Event Grid exhausts all retries, undelivered events go to a dead-letter destination (an Azure Blob Storage container you specify). This prevents event loss.

# Create subscription with dead-lettering enabled
az eventgrid event-subscription create \
  --name my-sub \
  --source-resource-id "/subscriptions/{sub-id}/resourceGroups/my-rg/providers/Microsoft.Storage/storageAccounts/myacct" \
  --endpoint "https://my-api.azurewebsites.net/api/events" \
  --deadletter-endpoint "/subscriptions/{sub-id}/resourceGroups/my-rg/providers/Microsoft.Storage/storageAccounts/dlqacct/blobServices/default/containers/deadletters"

Dead-lettered events include the original event plus a deadLetterReason (e.g., MaxDeliveryAttemptsExceeded or Unmatched).

Common Mistakes

  • Non-idempotent handlers — Since delivery is at-least-once, your handler must safely process duplicates. Use the event id for deduplication
  • Ignoring dead-letter setup — Without dead-lettering, failed events are silently dropped after retries expire
  • Setting TTL too low — If your handler has planned downtime, a short TTL means events are lost
  • Confusing topics and subscriptions — Topics are where events arrive; subscriptions define where they go next

Key Takeaways

  • Topics are event channels (system, custom, or partner)
  • Subscriptions route events from topics to handlers with optional filtering
  • Events follow a standard JSON structure with envelope + data payload
  • Handlers include Functions, Logic Apps, webhooks, queues, and more
  • Delivery is at-least-once — design idempotent handlers
  • Retry uses exponential backoff up to 30 attempts over 24 hours
  • Dead-lettering captures undeliverable events in Blob Storage for later analysis
  • Choose Event Grid schema for simplicity or CloudEvents for portability