What it does
Dataverse offers roughly six ways to move data in or out — the Web API and SDK, dataflows, virtual tables, Link to Fabric and Synapse Link, the event framework (webhooks, Service Bus, plug-ins), and the connector ecosystem including dual-write. Picking between them is a question about direction, latency and volume, not about which technology is newest.
Key facts
- The Web API is OData v4 over HTTPS with batch support and change tracking, and it's the only route that gives you full CRUD with the platform's business logic applied. It's subject to service protection limits.
- Bulk messages (
CreateMultiple,UpdateMultiple,DeleteMultiple) are the documented way to get throughput within those limits rather than around them. - Dataflows are the scheduled, transform-and-load option for inbound data. Power Query on the front, Dataverse tables on the back, no code.
- Virtual tables read from the source at query time and store nothing, so there's no synchronisation and no analytics path — no change tracking means no Synapse Link over them.
- Link to Fabric and Azure Synapse Link are the outbound analytics routes. Low-latency sync for Link to Fabric reached GA in June 2026, which materially changed how fresh the analytical copy can be.
- The event framework — webhooks, Azure Service Bus, and plug-ins on the pipeline — is the push route. It's how you tell another system something happened without that system polling you.
- Dual-write is Microsoft's tightly coupled bidirectional integration between finance and operations apps and Dataverse. Changes on either side write to the other.
- Change tracking plus the Web API is the standard pattern for an external system pulling deltas without a full extract.
When to use / skip
Start with three questions and the answer usually falls out: which direction, how fresh does it need to be, and how much data.
Inbound and scheduled, moderate volume, someone non-technical maintaining it — dataflow. Inbound and transactional, needs the business logic to run — Web API with bulk messages. Outbound and event-driven — the event framework, with Service Bus rather than a webhook once you care about retry and ordering. Outbound and analytical — Link to Fabric, not a nightly export, and not a report pointed straight at Dataverse. Read-only reference data that must stay in the source system — virtual tables, with the latency and security caveats. Finance and operations in the picture — dual-write, because rebuilding what it does is a project in itself.
The pattern to argue against is the one clients arrive with: a Power Automate flow on a schedule pulling a few thousand rows, per table, per hour. It's easy to build, it's owned by whoever built it, it hits service protection limits at exactly the wrong moment, and there's no delta logic so it re-reads everything. Where the volume, retry semantics or ownership point at a real integration platform, say so at design time. That conversation goes much worse after the first production incident.
Also worth saying plainly: analytics is not integration. A steady stream of requests asking "can we copy Dataverse into SQL for reporting" is usually a Fabric question wearing an integration costume.
Configuration decisions
- Direction and who owns the trigger — does Dataverse push, or does the other system pull?
- Latency requirement stated in numbers. "Real time" from a business stakeholder almost always means "within a few minutes", and that changes the answer entirely.
- Volume now and in three years, checked against service protection limits rather than hoped past them.
- Whether Dataverse business logic must run on the inbound path. If it must, the write goes through the API, not around it.
- Where retry, dead-lettering and error visibility live. This is the design element that separates an integration from a script, and it's usually the one nobody specified.
- Who operates it — a business team or a platform team. That answer settles Power Automate versus Logic Apps or Azure Functions more reliably than any feature comparison.
Gotchas
- Service protection limits are per user, per server, per five minutes. An integration running as a single service account is much easier to throttle than teams expect, and the failure mode is HTTP 429 mid-run.
- Change tracking has to be enabled per table, and it isn't retrospective. Turn it on before you need the deltas, not when the first sync fails.
- Bypassing custom logic on an integration write is supported and documented, but it means plug-ins and flows don't fire. Migration teams use it and then wonder why downstream data is missing.
- Dual-write is tightly coupled by design. When one side is down or a mapping is wrong, the other side feels it immediately — that's the trade for the consistency it gives you.
- Virtual tables put someone else's uptime inside your form load. It's an integration decision that presents as a data model decision.
- Rows deleted by elastic table TTL after they've synchronised to a lake stay in the lake. Your operational store and your analytical copy diverge silently.
Consultant notes
- Make the client state the latency requirement as a number in the first workshop. More integration designs are wrong because of an unexamined "real time" than for any other reason.
- Draw the failure path, not just the happy path. What happens when the target is down for four hours is the design question; what happens when it works is trivial.
- Where a business team has built a scheduled flow that's become production-critical, treat migration as a rebuild with a head start and budget it honestly.
- Keep analytics out of the operational integration design. Link to Fabric with low-latency sync now covers a lot of what people used to build custom pipelines for.
Worth revisiting as low-latency Fabric sync matures — it's already removed the case for several custom extract patterns