Every plugin step is registered as either synchronous or asynchronous, and this choice has real consequences for both user experience and what’s technically possible at that stage.

Synchronous

Runs immediately, inside the same transaction, blocking the user’s operation until it completes. Pre-validation and Pre-operation stages are always synchronous — there’s no async option for them, because they need to potentially affect the data before it saves. Post-operation can be either sync or async.

Asynchronous

Queued and processed shortly after the triggering transaction has already committed, by the Dataverse async service — the user doesn’t wait for it. Only available at Post-operation. Good for anything that doesn’t need to block the user: sending notifications, calling a slow external API, or doing non-critical follow-up processing.

The trade-off to actually weigh. Synchronous Post-operation guarantees the user sees the result of your logic immediately and that any failure in your plugin blocks the whole save (useful if your logic is a hard requirement). Asynchronous means a faster save experience for the user, but your logic runs moments later and its failure won’t block anything — the original record saves successfully regardless. If a requirement genuinely needs “this must happen before we consider the save successful,” it has to be synchronous; everything else is a candidate for async.

Monitoring async plugins

Failed or stuck async plugin executions show up in the System Jobs area, which is the first place to check when “my async plugin doesn’t seem to be running” — it may be running and failing silently from the user’s perspective rather than not running at all.