Domain 3 β€” Module 3 of 6 50%
19 of 27 overall
Domain 3: Connect to and consume Azure services Free ⏱ ~12 min read

Azure Event Grid: Filters, Custom Events, Retries

The push-based event routing service for AI integration. CloudEvents, custom topics, system topics, advanced filters, and the retry policies that protect downstream subscribers.

What Event Grid is β€” and isn’t

Simple explanation

Event Grid is an event routing service. Many publishers send small JSON events; Event Grid pushes each event to one or more subscribers based on filters. Subscribers can be Functions, Logic Apps, webhooks, Service Bus queues, Storage queues, even Container Apps.

It’s NOT a message broker like Service Bus. Event Grid is push-based, optimised for small (≀1 MB) event metadata, and excellent for β€œreact to a state change”. Service Bus is pull-based, durable, and excellent for β€œprocess this work in order”.

For AI workloads, Event Grid is great when an Azure resource emits an event you want to react to β€” Storage blob created, Cosmos DB doc updated, Container Registry image pushed, custom event from your app.

CloudEvents schema

{
  "specversion": "1.0",
  "id": "evt-7f3...",
  "source": "/subscriptions/<sub>/resourceGroups/roo-prod/providers/Microsoft.Storage/storageAccounts/rooblobs",
  "type": "Microsoft.Storage.BlobCreated",
  "time": "2026-05-08T03:14:15Z",
  "subject": "/blobServices/default/containers/uploads/blobs/img-789.jpg",
  "datacontenttype": "application/json",
  "data": {
    "url": "https://rooblobs.blob.core.windows.net/uploads/img-789.jpg",
    "contentType": "image/jpeg",
    "contentLength": 482910
  }
}

The five envelope fields used by filters: id, source, type, subject, time. Plus data for the resource-specific payload.

Filter dimensions β€” pick once, narrow forever

Combine subject + type filters first. Reach for advanced filters when you need to look inside data.
FeatureSubject filterEvent type filterAdvanced filter (data fields)
Filters onBegins with / ends with on the `subject` fieldExact match against allow-listed event typesAny field including `data.*` β€” equals, in, contains, range
PerformanceFast β€” broker-side path filterFastSlightly higher per-match cost
Use forStorage events scoped to a container or prefixSubscribing only to specific event typesFiltering by content (e.g., contentType='image/jpeg')
# Subscribe to only blob-created events for a specific container, only JPEGs
az eventgrid event-subscription create \
  --name jpeg-uploads \
  --source-resource-id $STORAGE_RESOURCE_ID \
  --endpoint $FUNCTION_APP_URL \
  --included-event-types Microsoft.Storage.BlobCreated \
  --subject-begins-with "/blobServices/default/containers/uploads/blobs/" \
  --advanced-filter data.contentType StringContains "image/jpeg"

Custom topics β€” your app emits events

# Publishing a custom event from your app
from azure.eventgrid import EventGridPublisherClient, CloudEvent
from azure.identity import DefaultAzureCredential

client = EventGridPublisherClient(
    "https://roo-events.<region>-1.eventgrid.azure.net/api/events",
    DefaultAzureCredential(),
)

event = CloudEvent(
    type="com.roorobotics.shipment.scanned",
    source="/warehouses/auckland",
    data={"shipment_id": "S-7012", "weight_kg": 42.3},
    subject="warehouse/auckland/shipment/S-7012",
)
client.send(event)

Subscribers register against your custom topic and choose endpoints β€” Functions, webhooks, Service Bus, Container Apps, Logic Apps.

Delivery semantics β€” and what to do about retries

Event Grid delivers each event to each subscriber at least once. If a delivery fails (timeout, 5xx, or non-2xx), Event Grid retries with exponential back-off:

PhaseSchedule (default)
Initial retries10 s, 30 s, 1 min, 5 min, 10 min, 30 min, 1 hour, 3 hours, 6 hours, 12 hours, 24 hours
Total retry windowUp to 24 hours (configurable, max 24 h)
After max retriesDrops the event, OR routes to a configured dead-letter Storage destination
# Set a custom retry policy + dead-letter destination
az eventgrid event-subscription update \
  --name jpeg-uploads \
  --source-resource-id $STORAGE_RESOURCE_ID \
  --max-delivery-attempts 5 \
  --event-ttl 60 \
  --deadletter-endpoint $STORAGE_DLQ_URL

Dead-lettering writes the failed event as a JSON blob to your specified Storage container. Most production subscribers configure dead-lettering β€” the alternative is silent data loss after retries exhaust.

Exam tip: 'events stop arriving' β€” check the subscription, not the publisher

When events stop appearing at a subscriber, the most common causes (in order):

  1. The subscription’s filter changed and now matches nothing
  2. The subscriber endpoint returns non-2xx and Event Grid is in back-off
  3. The subscriber endpoint is unreachable (DNS, network)
  4. The publisher actually stopped emitting

Check the subscription first β€” Event Grid metrics (delivered, failed, dead-lettered) show all of (1)-(3) clearly.

Idempotency β€” the at-least-once consequence

Because Event Grid retries, your subscriber will see duplicate events sometimes. Make handlers idempotent:

# Pattern: use the event's `id` to deduplicate
async def handle_event(event: CloudEvent):
    event_id = event.id
    if await already_processed(event_id):
        return  # safe re-delivery β€” skip
    await process(event)
    await mark_processed(event_id)

Common dedup stores: Cosmos DB (partition by something stable, document id = event id), Redis (SET NX with TTL), PostgreSQL (UNIQUE constraint on event_id).

Endpoints β€” where can events be delivered?

EndpointNotes
Webhook (HTTPS)Anywhere β€” Container Apps, App Service, your data-centre. Must respond 200 within 30 s
Azure FunctionsNative trigger β€” EventGridTrigger binding
Logic AppsNative trigger
Service Bus queue / topicPush events into a Service Bus destination for durable processing
Storage queueSimple, cheap, lightweight
Event HubsHigh-throughput buffering
Hybrid ConnectionsReach back-end services through hybrid connections without exposing them publicly

Two patterns recur in AI workloads:

  1. Event Grid β†’ Service Bus β†’ Container Apps: Event Grid handles the routing/filtering, Service Bus provides durability + DLQ, Container Apps + KEDA scales the workers
  2. Event Grid β†’ Function App: simple event-driven serverless, fine for low-volume reactive work

Event Grid Namespace topics + MQTT

Event Grid Namespaces add:

  • Pull-style subscribers (HTTP long-poll instead of push) for back-end services that don’t expose endpoints
  • MQTT broker for IoT-style scenarios where devices publish/subscribe with MQTT v3.1.1 / v5

This isn’t core to AI-200 but recognise the keywords if they appear in a question.

Key terms

Question

What's the difference between Event Grid and Service Bus?

Click or press Enter to reveal answer

Answer

Event Grid is push-based, optimised for routing small events (≀1 MB) to many subscribers with broker-side filtering. Service Bus is pull-based, durable, ordered messaging for back-end work assignment. They're complementary β€” common pattern is Event Grid β†’ Service Bus β†’ worker.

Click to flip back

Question

What's the CloudEvents schema?

Click or press Enter to reveal answer

Answer

A CNCF-standard envelope for events: `specversion`, `id`, `source`, `type`, `subject`, `time`, `datacontenttype`, `data`. Event Grid speaks both CloudEvents v1.0 and a legacy native schema. Use CloudEvents for new development.

Click to flip back

Question

What does Event Grid's at-least-once delivery mean for your code?

Click or press Enter to reveal answer

Answer

Subscribers may receive duplicate events. Handlers must be idempotent β€” use the event's `id` to deduplicate before processing, or design downstream actions to be safe to repeat.

Click to flip back

Question

What is dead-lettering in Event Grid?

Click or press Enter to reveal answer

Answer

When delivery fails for too long (max retry window or attempts exhausted), Event Grid can write the failed event as a JSON blob to a configured Storage container instead of dropping it silently. Always configure dead-letter for important subscriptions.

Click to flip back

Question

What's the difference between subject filter and advanced filter?

Click or press Enter to reveal answer

Answer

Subject filter β€” fast prefix/suffix match on the `subject` field. Advanced filter β€” match on any field including `data.*` with equals, in, contains, ranges. Use subject + type filters first for performance; reach for advanced when you must inspect content.

Click to flip back

Knowledge check

Knowledge Check

Mira wants a Container App to react when a new image lands in a specific Storage container. Multiple Storage events fire for various containers, but only `uploads/` matters and only for JPEGs. Which Event Grid configuration fits?

Knowledge Check

Theo's webhook subscriber returns 503s during a deployment. Events from the previous hour are critical. What should be true of the subscription?

Knowledge Check

Lin notices the subscriber occasionally processes the same event twice. What's the right fix?