A new architect joins the platform team and asks why one integration goes through Service Bus and another through Event Grid for what looks like the same job. The honest answer is that the choices were made by different people at different times and nobody documented the decision. The Azure integration toolkit is rich enough that any pattern can be made to work; the discipline is picking on purpose.
Service Bus
Reliable message queue for Dataverse events. Plug-ins publish to Service Bus; downstream consumers process async. Handles retry, dead-lettering, high volume. The key feature is exactly-once delivery semantics with sessions, which protects financial transactions from duplicate processing.
Use Service Bus when:
- Order matters within a partition key
- A duplicate message would cause a financial event
- Volume above 100 messages per second sustained
- The consumer needs to scale independently
The dead-letter queue is non-optional. Wire monitoring on it from day one or you will discover six months in that 4 percent of your messages have been silently dropping.
Event Grid
Pub/sub for event-driven architectures. Dataverse integrates natively. Cheaper than Service Bus for at-least-once, fire-and-forget scenarios. Event Grid is built for fan-out: one event, many subscribers, each receiving a copy.
Use Event Grid when:
- Multiple downstream systems care about the same event
- Order is not critical
- Consumers can tolerate occasional duplicates
- Cost matters at scale
The pricing is per million events, dramatically cheaper than Service Bus, and the latency is single-digit milliseconds when the consumer is a webhook in the same region.
Logic Apps
Azure’s counterpart to Power Automate — more capable, IT-owned. Complex B2B integrations live here. Shared expertise with Power Automate translates. Logic Apps handle the long-running, branched, retry-heavy workflows that Power Automate either cannot do or does expensively.
{
"definition": {
"$schema": "https://schema.management.azure.com/...",
"triggers": {
"When_a_record_is_created": {
"type": "ApiConnection",
"inputs": { "host": { "connection": "@parameters('$connections')['commondataservice']" } }
}
},
"actions": { "Validate_with_external": { "type": "Http" } }
}
}
The trade-off is governance overhead. Logic Apps live in a resource group with their own permissions; the citizen-developer who built the original Power Automate cannot maintain them.
Azure Functions
Serverless code for custom logic. Webhook targets for Dataverse. Custom connectors back to Power Automate. Cheap, scales automatically. Functions are the right answer when you need a few hundred lines of C# or TypeScript that does not justify a hosted service.
module.exports = async function (context, req) {
const event = req.body;
if (event.eventType !== "create") return;
const enriched = await enrich(event.entity);
await context.bindings.outputQueue.add(JSON.stringify(enriched));
};
Cold start is a real consideration. For latency-sensitive paths, use the Premium plan or pre-warm with a timer trigger.
When to Use Which
Power Automate for citizen-dev workflows. Logic Apps for IT-owned integration. Service Bus for durable queuing. Event Grid for routing events. Functions for compute. The decision matrix should be visible on a single page and reviewed quarterly as your patterns mature.
Citizen flow, low volume -> Power Automate
IT-owned, complex branching -> Logic Apps
Reliable queue, financial -> Service Bus
Fan-out events, low cost -> Event Grid
Custom code, lightweight -> Azure Functions
Auth and Connection Hygiene
Every integration needs an identity. Use managed identities where Azure-to-Azure, app registrations where Dataverse-to-Azure. Rotate secrets through Key Vault references rather than baking them into connection strings. Audit the secret expiration schedule monthly.
Observability
App Insights ties the chain together. Correlate the Dataverse plugin trace, the Service Bus message ID, the Function execution, and the downstream system response with a shared correlation header. Without correlation, debugging a multi-hop integration is guesswork.
What to do this week
Build the decision matrix on a wiki page, audit your existing integrations against it, and flag the ones that picked the wrong tool. Wire dead-letter alerts on every Service Bus subscription and confirm App Insights correlation works end to end on at least one path.