IS LIVE
Book a Demo
All Posts
· Laine · 10 min read

Salesforce Duplicate Management Rules That Actually Fit

Salesforce duplicate management rules go quiet on the paths duplicates actually arrive through. Here's what to build instead — without hiring a developer.

SalesforceSentinelCRMAIRevOpsData Quality
Sentinel cover graphic: Salesforce Duplicate Management Rules That Actually Fit

Salesforce duplicate management rules are not broken. They are scoped — and almost nobody is told where the scope ends. They fire reliably when a rep types a name into a form, which is the one path your duplicates mostly do not arrive through. They stay silent on imports, on API writes, on lead conversion, on undelete, on manual merges. So you turn the feature on, you watch it catch a handful of hand-typed contacts, you assume the org is protected, and eighteen months later somebody runs a count and finds four thousand accounts that should be nine hundred.

The fix is not a better matching rule. It is accepting that your deduplication policy is a business rule with exceptions, and Salesforce’s rule engine can only express “these fields look similar.” Everything past that, you build.

Where your duplicates actually come from

Ask an admin where the duplicates in their org came from and you get a real answer fast, because everyone knows: the list import from the conference. The marketing automation sync that creates a lead when someone fills out a form with a work email one week and a personal email the next. The integration that writes an account from the billing system. The lead conversion that spawns a second contact because the match didn’t fire. The rep who couldn’t find a record in global search, so they made a new one.

Look at that list against what Salesforce documents. Its own help page on duplicate rules is explicit that the rules don’t run when “records are added using the data import tools,” when “records are added or edited using Salesforce APIs,” when “leads are converted to accounts or contacts, and Use Apex Lead Convert isn’t enabled,” when “records are restored with the Undelete button,” or when “records are manually merged.” In each of those cases the setting is overridden and no alert reaches anyone.

That is not a bug. It is a deliberate performance and bulk-safety decision, and it is defensible. But it means the feature covers the narrowest path and skips the four widest ones. If you turned duplicate rules on and stopped there, you did not deduplicate your org. You put a smoke detector in the one room where nobody cooks.

Five rules is a ceiling, and your policy is bigger

The second wall you hit is a counting problem. Salesforce allows up to five active duplicate rules per object. Each duplicate rule can hold up to three matching rules, and across all of them you get up to five active matching rules per object — with a further cap of 25 active matching rules and 100 total across the org. There are field-level constraints on top: only one lookup relationship field per matching rule, fuzzy matching methods that support only Latin characters, and a documented behavior where mixing fuzzy and exact methods inside a single rule means “duplicates aren’t detected.”

Now write down your actual policy. Mine, when I’ve helped teams write it out, always looks something like this:

Two accounts are the same company if the domains match, unless one is a franchise location, in which case they’re separate. Two contacts are the same person if the email matches, or if the name matches and the phone matches, unless one is a former employee at a new company, in which case the contact moves rather than merges. Leads from the partner portal never merge into anything automatically because the attribution matters. Anything created in the last 48 hours by the billing integration is authoritative and wins the merge.

Count the clauses. That is not five rules. It is not even shaped like rules — it has conditions that reference record age, source system, and relationships to other objects, and it specifies which record survives, which the matching engine has no opinion about at all. You cannot compress it into the ceiling, and every attempt to try produces a rule so loose it flags real distinct records, or so tight it catches nothing.

”Looks alike” is not the same as “is the same”

This is the part that trips up good admins, and it is worth stating plainly: matching is a similarity problem and deduplication is a truth problem, and they are not the same problem.

A matching rule can tell you that Acme Corp and ACME Corporation score as similar. It cannot tell you that they are two divisions with separate contracts, which is a fact that lives in an opportunity record and a renewal date rather than in the name string. It can tell you two contacts share an email. It cannot tell you that the shared email is an info@ alias used by four people at a small business.

So the honest goal isn’t a rule that never gets it wrong. It’s a system where the judgment calls happen once, get recorded, and don’t come back. When a human decides that these two accounts are genuinely separate, that decision needs to survive — stamped on the records so the next scan, the next import, and the next rep don’t re-litigate it. Salesforce’s native model has no place to put that decision. Duplicate record sets record what was flagged, not what was ruled on.

Catch the record where it lands, not where it’s typed

Once you accept that the native rules skip the API and import paths, the shape of the real fix becomes obvious: the check has to run on write, on every path, in your own code.

Concretely, what gets built is a service the org calls whenever a record is created or updated — from a trigger, from the integration itself, from a scheduled sweep over records that arrived while nobody was looking. It does three things the native engine won’t:

It normalizes before it compares. Strip the Inc, the LLC, the trailing punctuation. Reduce email to its domain when you’re matching companies. Strip formatting from phone numbers. Most “fuzzy matching didn’t work” complaints are really normalization problems, and normalization is deterministic code, not a similarity score.

It applies your clauses, in your order. Source system, record age, franchise flag, partner attribution — all the conditions your policy actually has, evaluated in the sequence your business agreed on, with the winning record chosen explicitly rather than by whichever the merge dialog listed first.

It writes down what it decided and why. A field on the record saying which rule fired, what it matched against, and whether a human confirmed or overruled it. Nobody asks for this field. Everybody needs it the first time someone says “why did these two get merged” — the same argument that makes an assignment-reason field worth building into round robin lead assignment, and for the same reason.

Then the exceptions become data instead of code. A “confirmed distinct” flag on a pair means the sweep skips it forever. A merge-precedence value per source system means the next integration you add is a record edit, not a redeploy.

The merge is the harder half

Finding duplicates is the part that gets all the attention, and it is the easy part. Merging them is where orgs actually get hurt, because a merge is destructive and the losing record takes things with it.

Before you merge anything at scale, you need answers to a specific set of questions: what happens to the activity history on the losing record, to its open opportunities, to the campaign member records, to the custom lookups that point at it from objects Salesforce’s merge doesn’t touch, to the external IDs your integrations use to find it again tomorrow. That last one is the classic disaster — you merge cleanly, the org looks great, and then the billing sync starts erroring or, worse, silently recreates the record it can no longer find.

None of that is exotic work. It’s a re-parenting pass, an external-ID reconciliation, and a merge log, run in a sandbox against a real data volume first. It’s just work nobody scopes, because “clean up our duplicates” sounds like a one-afternoon task and turns out to be a project — which is the same reason bulk record cleanup without a data loader marathon stays on the backlog for years.

And it’s worth saying the unglamorous thing: run it as a report first. Have the thing find and score the duplicates and write the merge plan without executing it, and read the top hundred by hand. You will find at least one clause in your policy that you got wrong, and you would rather find it in a spreadsheet than in the audit trail of four thousand merged accounts.

Why this never got built

Everything above is maybe a week of work for someone who knows the org. It has never been technically hard. It has been unbuyable — too small to justify a statement of work, too specific for a managed package, too consequential to hand to whoever has spare capacity. So it sits behind the same wall as every other four-hour build in the CRM tasks nobody should still be paying a developer for, and the org keeps filling up.

That wall is what changes when your AI can develop directly against your org. Sentinel gives an AI you already use the hands to work in Salesforce — read the data, write the Apex, deploy through the sandbox — so a policy like the one above stops being a purchase and becomes a conversation. You describe the clauses, the AI builds the service and the sweep, you read the report, you adjust the clauses.

To be straight about what that does and doesn’t get you: it does not stop you from deploying a bad merge rule. Describe your policy carelessly and you will get a careless policy, accurately built and cleanly deployed. What you get instead is that every change is logged, deploys go to a sandbox with tests first, and there’s a snapshot before each one — so a wrong call is visible and recoverable rather than mysterious and permanent. That distinction matters more here than almost anywhere else in the org, because merges destroy data. If you want the full picture of how that layer works, the deployment safety deep dive covers it properly.

Sentinel is $500/month per Sentinel, plus a one-time $2,500 onboarding fee on your first one. Against the quotes you have been getting for “a data quality project,” that math tends to make itself.

Start with the count

You do not need a plan to begin. You need a number.

Run the count you have been avoiding — accounts by normalized domain, contacts by email, leads by name-and-phone — and look at the top of the list. Not to merge anything. To find out whether your problem is a hundred records or forty thousand, and to see, in your own data, which clause your policy is actually missing. Every duplicate project I’ve seen go well started with someone reading fifty rows and saying “oh — it’s the franchises.”

The native rules will keep doing their job on the narrow path. Build the rest yourself, on the paths your records actually arrive through, with your clauses and your merge order written down where the next person can read them. That’s not a Salesforce limitation you have to live with. It’s a week of work that used to be unbuyable.


Have a duplicate policy nobody’s ever been able to build? Get a Sentinel for your Salesforce org and describe it to your AI instead of scoping it to a consultant.

Sources: Salesforce Help, Things to Know About Duplicate Rules and Things to Know Before You Customize Matching Rules. ORG Endgame is not affiliated with Salesforce.

Ready to see what AI can do for your business?

Start a Conversation