Dynamics 365 CE is rarely the only system in an organisation's Microsoft estate. Getting the integration approach right early, rather than bolting on point-to-point connections as needs arise, is usually what separates a CRM that stays reliable for years from one that becomes fragile and hard to change. Here are the patterns we reach for most often.
When an action needs to happen as part of the same transaction, such as validating data before a record saves or calculating a field synchronously, a Dynamics 365 plugin is usually the right tool. Keep plugins focused on logic that genuinely needs to be synchronous; anything that can wait a few seconds is a better fit for the next pattern.
For most integration work, such as syncing a new case to an external system, sending a notification, or updating a related record in another app, an asynchronous flow triggered off a Dataverse event is more maintainable than plugin code, and easier for a wider team to support. See our note on choosing between Power Automate and Azure Logic Apps for how we decide which of the two to use.
When multiple downstream systems need to react to the same Dynamics 365 event, or volume is high enough that flow-per-integration becomes unwieldy, we look at an event-driven approach, using Dataverse webhooks or Service Bus, so Dynamics 365 publishes an event once and each consumer subscribes independently, rather than Dynamics 365 needing to know about every downstream system directly.
Not every integration needs to copy data into Dataverse. Where it's practical, reading data live from the source system (virtualisation) avoids sync issues and stale data; where performance, offline access or cross-entity relationships in Dynamics 365 require it, we duplicate data and build a clear, owned sync process rather than letting an ad-hoc one grow undocumented.
Integrations fail. The difference between a minor blip and a data-quality incident is whether the integration was built to handle retries safely (idempotency), surface failures somewhere a human will see them, and recover without manual data clean-up. We treat this as a first-class part of the design, not an afterthought added after the first production failure.