Dataverse plug-ins vs Power Automate for integrations: when to use which
By Emil Björk · Microsoft business apps consultant, Gothenburg
The decision between a C# plug-in and a Power Automate flow for integration logic in Dataverse — transactions, latency, throughput, ownership, and the cases where each is clearly wrong.
Every Dataverse project reaches the moment where something needs to happen when a record changes, and someone has to decide whether that something is a plug-in or a flow. Both can call external systems, both can update Dataverse, and both have partisans. The decision is not about skill or taste. It is about where the logic needs to run relative to the database transaction, how fast it must be, how much of it there is, and who will own it in three years.
The one difference that decides most cases
A plug-in registered synchronously runs inside the Dataverse transaction. If it throws, the user's save fails and nothing is written. A Power Automate flow runs after the transaction has committed, on its own schedule, with no ability to stop the save. That single fact sorts a surprising amount of integration logic.
If the external system must agree before the record is allowed to exist (a credit check before an order is created, a tax engine validation before an invoice is saved, an address validation before an account is committed), it is a synchronous plug-in. Nothing else can veto the save. See the plug-in execution pipeline for what runs when.
If the external system just needs to hear about the change (notify a shipping system, push a contact to a marketing tool, log to a warehouse), it is a flow, or an asynchronous plug-in, or better still an event on a queue. Blocking the user's save while a marketing API answers is a design error, however it is implemented.
When plug-ins win
- Veto logic as above.
- Latency-sensitive updates that the user expects to see immediately on the same form, such as a calculated field derived from an external rate.
- High volume. Thousands of record changes an hour will exhaust Power Automate's run and action limits and cost real money per run. A plug-in costs nothing per execution.
- Complex logic that is painful to express in a visual designer: recursion, heavy string handling, anything with more than a handful of branches.
- Impersonation and elevated operations that need to run as a specific user or bypass a user's permissions in a controlled way; see impersonation in plug-ins.
When Power Automate wins
- Fire-and-forget notifications to external systems where a delay of seconds to minutes is fine.
- Connector-heavy work. If the job is "put a row in SharePoint, send a Teams message, and create a ticket in ServiceNow", the connectors exist and the flow is done in an hour. The equivalent plug-in involves three authentication schemes and three SDKs.
- Approval and human-in-the-loop processes. Plug-ins cannot wait for a person.
- Scheduled work on a cadence rather than on an event. Plug-ins do not have timers.
- Ownership by makers. If the team that will maintain this is functional rather than developer, a flow they can read beats a plug-in they cannot.
The trap in the middle
Asynchronous plug-ins occupy the space between the two: code, but off-transaction, executed by the async service with retries. They are the right choice for post-commit logic that is too heavy or too frequent for flows, and the wrong choice when what you actually want is a durable queue, because the async service is not one. For anything that crosses a system boundary and must not be lost, the honest pattern is plug-in writes to a Service Bus queue or an outbox table, and a consumer does the integration; see the outbox pattern with Service Bus.
The other trap is calling an external HTTP endpoint from a synchronous plug-in "just this once". The two-minute execution limit, the sandbox restrictions, and the fact that a slow third party now slows every user save mean this should be a last resort with a tight timeout, not a habit.
Low-code plug-ins
Dataverse also offers low-code plug-ins written in Power Fx, which run in the transaction like C# plug-ins but are authored by makers. They cover simple validation and calculation well and are not yet a serious integration tool; the external-call story is through connectors and is limited. Treat them as a third option for the light end of the plug-in use cases, not as a replacement for either.
Cost and licensing
Flows consume Power Platform request limits and, depending on licensing, per-flow or per-user entitlements. Plug-ins consume Dataverse API request allowances but no per-run charge. At low volume the difference is invisible; at high volume flows become the expensive option and the throttled one.
Testability and ALM
Plug-ins have unit tests, source control, and a build pipeline, if the team sets them up, and are deployed in solutions like anything else. Flows live in solutions too, can be exported and imported, but testing is largely manual and version history is thin. A regulated environment that needs auditable change control tends to lean plug-in for anything critical. See solution import and export pipelines.
A working rule
Inside the transaction, or high volume, or complex: plug-in. After the transaction, connector-shaped, human-involved, or maker-owned: flow. Crossing a system boundary with data that must not be lost: neither directly; queue it. If two people on a project disagree, the disagreement is almost always because they have not agreed which of those buckets the requirement is in.
Stability verdict
Both tools are mature and neither is going anywhere. The unstable part is the boundary: teams that build integrations as flows because it was quick, then hit limits, then rewrite as plug-ins, then find they wanted a queue. Decide the bucket first. For the underlying mechanics, see Dataverse plug-ins explained and Power Automate connectors for Dynamics 365.
Further reading
Related guides
- Custom PCF controls vs embedded canvas apps in model-driven formsTwo ways to put custom UI on a Dynamics 365 form — a Power Apps component framework control or an embedded canvas app — and how to choose based on data access, performance, maintenance, and who builds it.
- Integrating Dynamics 365 with Zapier and Make: when to use them instead of Power AutomateWhere Zapier and Make (formerly Integromat) fit next to Power Automate for Dynamics 365 — the honest cases for each, the governance problems, and how to keep a small team's automations from becoming shadow IT.
- Anti-corruption layers for Dynamics 365 integrationsHow anti-corruption layers protect Dynamics 365 from external system model leakage — translation patterns, when to apply ACL, and the maintenance discipline.
- API Gateway patterns for Dynamics 365How API gateways enhance Dynamics 365 integration architecture — Azure API Management, security, rate limiting, transformation, and the patterns for managed API surfaces.
- CQRS pattern for Dynamics 365How CQRS (Command Query Responsibility Segregation) applies to Dynamics 365 architectures — write vs read separation, projection patterns, and when CQRS helps vs hurts.
Spot something wrong or want a topic covered? Send a correction or a topic request — both are welcome.