Skip to Content
IdentityLimit Rules

Limit Rules

Limit rules cap how many distinct source records may share a single identifier value. They exist because real source data always contains at least one value that is not an identity — a placeholder email, a support inbox, a bot’s cookie, an empty-string surrogate — and without a cap, every record carrying that value merges into one profile.

Why Limit Rules Matter

Suppose noreply@company.com appears on 50,000 records. The email merge rule links records that share an email, so with no cap it links all 50,000 into a single profile. That profile is not a person, and everything downstream of it — audiences, journeys, suppression — is wrong.

A limit rule on the email family with a maximum of 100 says: an email value shared by more than 100 distinct records is not an identity signal. Those records contribute no email edges. They can still be linked by any other identifier they share.

A capped value does not make records disappear. Each one still resolves — as its own profile, or merged via a different identifier family. Only the over-shared value stops linking them.

Every Enabled Merge Rule Is Capped

Each merge rule family gets a cap whether or not you configure one:

ConfigurationEffective cap
No limit rule for the family100 (the default)
Limit rule with max unique values = 2525
Limit rule with max unique values = 0Unlimited — you have deliberately turned the cap off

The graph detail page’s Limit Rules table lists every enabled family with its effective cap and whether that cap is Configured or Default, so the value the resolver actually enforces is always visible.

Setting a family to 0 removes its only protection against a shared value collapsing unrelated people into one profile. Prefer raising the number to disabling the cap.

What a Limit Rule Controls

There is one kind of limit rule: maximum distinct records per identifier value, configured per identifier family.

SettingDescription
Identifier familyWhich family the cap applies to (email, phone, user_id, cookie_id, …)
Max unique valuesHow many distinct source records may share one value in that family before it is ignored

The cap is on one value, not on a profile. A profile can legitimately end up with many emails by chaining through other identifiers; what the rule prevents is a single value acting as a hub.

Choosing a Number

FamilyTypical rangeWhy
email10–100Household and shared-inbox addresses are the usual offenders
phone5–50Support and store numbers appear on many records
user_id50–500Should be near-unique; a high count usually means a placeholder value
cookie_id20–200Shared or reset devices inflate counts legitimately

Measure before you choose. This query gives the distribution of how widely each value is shared, which is exactly what the cap compares against:

SELECT shared_by, COUNT(*) AS values_at_this_level FROM ( SELECT LOWER(TRIM(email)) AS value, COUNT(DISTINCT id) AS shared_by FROM crm_contacts WHERE email IS NOT NULL AND TRIM(email) <> '' GROUP BY 1 ) _dist GROUP BY shared_by ORDER BY shared_by DESC LIMIT 50;

A healthy family has a long tail at shared_by = 1 and a handful of outliers. Set the cap above the legitimate cluster sizes and below the outliers.

How Limits Are Enforced

The cap is applied in two places, and the first is the one that matters.

During edge building. Each identifier value’s group size is computed as the edges are written, and groups larger than the cap emit no edges at all. This is the only placement that can prevent a super-node: a cap applied afterwards has to let the rows be written before it can delete them, and for a value shared by tens of thousands of records, writing them is the step that does not complete.

After edge building. A second pass deletes edges for over-shared values. Deterministic edges were already capped above, so what this catches is probabilistic edges, which are scored pair by pair and therefore cannot carry a group-size condition while being built.

Incremental runs apply the same cap, so a delta run can never reintroduce a group the full run refused to build.

Limits Drop Edges, They Do Not Split Profiles

Limit rules work by preventing edges from being created, not by breaking up profiles after the fact. Merge rule priority does not change the outcome — edges are a set, and the same edges are produced whichever order the rules are compiled in. Priority decides which family is resolved first, not which one wins.

Symptoms and Tuning

What you seeLikely causeWhat to do
Profiles that should be one person are separateCap too tight for a family whose values are legitimately sharedRaise that family’s max unique values
One profile contains obviously unrelated peopleCap too loose, or a shared value just under itLower the cap, or clean the placeholder value at the source
Profile count barely drops after resolutionCaps are suppressing most edgesCheck the distribution query above — a cap below your typical cluster size suppresses everything
A run that used to finish now produces fewer mergesThe default cap now applies to a family that previously ran uncappedConfigure an explicit limit rule for it

The most durable fix is usually upstream: a placeholder identifier that trips the cap is a data quality problem, and excluding it in the model’s SQL is better than tuning around it.

Last updated on