[object Object]

Where you put logic in Dynamics 365 determines its latency, testability, and who gets paged at 2am when it breaks. The “use Power Automate for everything” school is wrong, and so is the “plugins for everything” school.

Plugins: synchronous integrity

Plugins run inside the Dataverse transaction. Use them when you need an action to either complete fully or roll back, when you need to throw InvalidPluginExecutionException to block a save, or when latency must stay under 200ms. They are also the only place you can reliably mutate the Target before the database write in the PreOperation stage.

public void Execute(IServiceProvider sp) {
    var ctx = (IPluginExecutionContext)sp.GetService(typeof(IPluginExecutionContext));
    var target = (Entity)ctx.InputParameters["Target"];
    if (!target.Contains("revenue")) target["revenue"] = new Money(0m);
}

The cost: deployment friction, no easy retries, and the 2-minute sandbox timeout.

Power Automate: asynchronous orchestration

Use Flow for cross-system orchestration, scheduled jobs, approvals, and anything that calls external APIs with retry semantics. Flow is brilliant at “when X happens, eventually do Y across three systems.” It is terrible at “block this save if condition Z.” A Dataverse trigger has 5-15 second tail latency that will surprise users expecting instant feedback.

The cost: per-flow API call limits, harder version control, and debugging via run history instead of breakpoints.

JS Web Resources: UX and form logic

Use JS only for things that must happen on the client form: showing a notification, hiding a tab, calculating a display-only value, calling Xrm.WebApi for a lookup filter. Never put validation here that also needs to fire on bulk import or API write. Client-side rules are bypassable by design.

The decision tree

  1. Must it block the save with a transaction rollback? -> Plugin.
  2. Must it call an external system with retries and approvals? -> Power Automate.
  3. Is it pure form UX (show/hide, notify, lookup filter)? -> JS web resource.
  4. Does it need to fire on import + API + UI? -> Plugin or real-time workflow.
  5. Is it a calculated display field? -> Formula column. Skip code entirely.

What to do this week

List every Power Automate flow with a Dataverse trigger that updates the same row. Each one is a candidate to migrate to a plugin or formula column for sub-second response and lower API consumption.

[object Object]
Share