What's the ceiling on bulk duplicate detection?
The standard response to discovering post-migration duplicates is to run a bulk duplicate detection job: find what got through, merge it, and clean up.
The bulk detection job in Dataverse caps at 5,000 records.
On any mid-market migration, that ceiling is hit before you've touched most of the dataset. You end up running the job in batches, tracking what's been processed, and managing a cleanup operation that keeps expanding, because new records keep arriving through active integrations while you work through the backlog.
This isn't a detection strategy. It's a cleanup operation with a fixed size limit, running against a dataset that isn't standing still.
Why does this happen on every project?
The pattern here isn't bad luck or a misconfigured environment. It's structural.
Native duplicate detection was built for one entry point: the Dynamics 365 UI. Every other way a record reaches Dataverse, the Web API, bulk imports, integration syncs, automated flows, is architecturally separate, and each one bypasses detection by default unless someone explicitly builds around it.
On a typical Dynamics 365 project, the number of entry points grows with the implementation. The legacy CRM migration is one. The ERP integration is another. The marketing platform sync is a third. Each requires its own configuration or workaround to enforce detection, and each is a potential gap.
Go-live week is when all of those entry points activate at once, with real data volume, under time pressure. It's the worst moment to discover that native detection only covered one of them.
Why adding more rules doesn't fix it
More duplicate detection rules don't close this gap. The rules work fine; the problem is that they don't run on the entry points that matter most during go-live.
The fixes consultants typically reach for, setting the SuppressDuplicateDetection: false header on Web API calls (see how Web API inserts bypass D365 duplicate detection by default), writing plugins on the Create message, running post-load cleanup scripts, each address one entry point at a time. On a project with four active integrations, that's four separate fixes to maintain, each scoped to a specific connector or entity, each rebuilt on the next project.
Closing the gap structurally means running duplicate prevention inside Dataverse itself, at the platform level, regardless of how a record arrived, covering standard and custom tables, working across every entry point, without per-integration configuration.