Why Your Salesforce Sharing Model Quietly Becomes Technical Debt
A Salesforce sharing model that worked cleanly at launch can quietly become technical debt as an org's data and role hierarchy grow - not because anyone misconfigured it, but because nobody revisited it against the record volumes it now carries. Here's the mechanism, the real thresholds, and a decision framework for fixing it.
What you’ll learn
- The exact threshold - roughly 10,000 related records under one account or one owner - where Salesforce's own guidance says sharing recalculation starts becoming a real performance problem, not a hypothetical one.
- Why role hierarchy and public groups solve two different problems, and forcing matrix or cross-functional access into a hierarchy is the most common way orgs make their own recalculation slower.
- A six-row decision table for choosing role hierarchy, public groups, criteria-based rules, deferred recalculation, or Apex managed sharing for a specific access requirement.
- What Salesforce's newer, faster sharing recalculation actually fixes on the platform side - and what it can't fix about a data model that was never revisited.
Somewhere past 10,000 child records under one account - or 10,000 records owned by one user - Salesforce's sharing engine stops being fast, and almost nobody designs a data model with that number in mind. It isn't a bug. Sharing recalculation has to walk every record's access whenever an ownership, role, or sharing-rule change could affect it, and it does that walk faithfully whether the org that hits the threshold has 50 users or 5,000. That mechanism is what turns a sharing model into technical debt without anyone deciding it should: nobody misconfigured anything, the org just grew past the assumptions the model was built under, and the first symptom usually isn't a system error. It's a user who should see a record and can't, and an admin who can't explain why.
The short answer
In brief: a Salesforce sharing model becomes technical debt the same way Flow automation does (see AI Just Made Salesforce Flow Technical Debt Move Faster) - not through one bad decision, but through steady growth against a design nobody revisited. The two most common causes are data skew (too many records stacked under one account or one owner) and a role hierarchy being asked to do a job it was never built for: modelling matrix or cross-functional access it can't actually represent. Neither is fixed by layering more sharing rules on top. Both are fixed by matching the access mechanism to the actual shape of the requirement - role hierarchy for vertical roll-up, public groups for horizontal access, criteria-based rules where access depends on data rather than ownership, and Apex managed sharing only for the narrow cases nothing declarative can express. A Salesforce Health & Roadmap review is the right place to find out which of these an org is actually carrying before it becomes a bigger project.
Why a sharing model becomes technical debt
Every layer of Salesforce's sharing model - org-wide defaults, role hierarchy, sharing rules, manual or Apex sharing - exists to answer one question for one record at one moment: who can see this, and why. That answer isn't cached forever. Change a record's owner, move someone in the role hierarchy, edit a sharing rule, or change a public group's membership, and Salesforce has to recalculate access for every record that change could touch. For a normal-sized batch of records, that recalculation is invisible. Past a certain volume, it isn't.
Salesforce's own guidance names this pattern data skew, and it comes in three shapes that all trip the same underlying cost. Ownership skew is more than roughly 10,000 records owned by a single user - a common outcome of integration users or a 'default owner' queue nobody ever rebalanced. Account (parent) skew is the same threshold applied to child records under one account, which shows up constantly in B2B orgs where one large customer's contacts, cases, or orders accumulate under a single parent. Lookup skew is the general case of either: many child records pointing at the same parent record of any kind. Cross any of these thresholds and a single ownership change - one account getting reassigned, one queue getting restructured - can force Salesforce to re-evaluate access on tens of thousands of records it wouldn't otherwise have touched.
Org-wide default
Sets the floor: Private, Public Read Only, or Public Read/Write. Every other layer can only add access on top, never restrict below it.
Role hierarchy
Rolls access upward for management visibility. Adds vertical access only - it was never meant to model lateral or cross-functional access.
Sharing rules
Opens access by ownership or by criteria to a defined role or public group. Criteria-based rules recalculate themselves as the data changes; ownership-based ones recalculate when ownership does.
Manual / Apex managed sharing
Grants access record-by-record for what the layers above can't express - temporary access, or logic tied to a related object. Maintained by hand or in code, not by platform improvements.
What the user actually sees
The union of every layer above. When nobody in the org can predict this from the configuration alone, that's the real signal the model has outgrown its own documentation.
The role hierarchy trap
Role hierarchy and public groups solve two different access problems, and the most common way orgs make their own sharing model slower is using one to solve the other. Role hierarchy is vertical - a manager sees what a report owns, rolled up automatically. Public groups paired with sharing rules are horizontal - two teams that don't report to each other but both need to see the same accounts, or a regional group that spans several reporting lines. When matrix or cross-functional access gets forced into the role hierarchy instead - a role created purely so two unrelated teams end up on the same branch - the org gets a deeper hierarchy with no real reporting meaning, and every extra level compounds the cost of the next recalculation. Salesforce can technically support hundreds of role levels; in practice, three to five is usually enough for the actual reporting structure, and a hierarchy that's grown past seven or eight levels is worth asking, honestly, how many of those levels exist to model management and how many exist to route around a sharing problem that a public group would have solved directly.
What to use for what
| Situation | Recommended approach | Why |
|---|---|---|
| Access needs to roll up through management levels | Role hierarchy, kept to roughly 3-5 levels | This is what roles are for - each extra level compounds recalculation cost for limited additional access benefit |
| Cross-functional or matrix access that doesn't follow reporting lines | Public group + sharing rule, not a forced role branch | Public groups model horizontal access directly instead of bending the hierarchy to fit it |
| Access depends on a field value, not who owns the record | Criteria-based sharing rule | Recalculates automatically as records change, without an ownership change needed to trigger it |
| One account or user is approaching roughly 10,000 related or owned records | Redesign the ownership or parent model before it happens, not after | This is the threshold where Salesforce's own guidance says recalculation becomes a real performance risk |
| A bulk role hierarchy change, territory realignment, or mass sharing-rule edit | Defer sharing recalculation, then run it once as a scheduled job | Recalculating after every intermediate change multiplies cost for no benefit over running it once at the end |
| Access logic genuinely can't be expressed by roles, groups, or criteria | Apex managed sharing - as a last resort, scoped to that one case | Code-based sharing has to be maintained by hand and doesn't automatically benefit from future platform improvements the declarative model gets |
What the numbers actually say
~10,000
related or owned records under one account or user - the threshold Salesforce's own guidance flags for ownership, account, and lookup skew
300
sharing rules Salesforce allows per object, of which only 50 can be criteria-based - a ceiling worth knowing about before you're near it, not after
3-5
role hierarchy levels that cover most genuine reporting structures - depth beyond that is usually solving a horizontal-access problem the hard way
From the field
CloudAvant's multi-region B2B Commerce platform work for a global manufacturer's distributor network sits right next to this problem, even though B2B Commerce's Buyer Group and Entitlement Policy model is a distinct layer from core sharing rules. The account hierarchies involved were large enough - spanning EMEA, North America, LATAM, and APAC - that the team had to engineer the Apex controlling which catalogues, features, and entitlements applied to which account and location specifically to stay bulk-safe against governor limits as those hierarchies grew. The underlying discipline is the same one this article argues for: design the access model for the record volumes it will actually carry, not the volumes it launched with.
What actually changed on the platform - and what didn't
Salesforce has been shipping platform-level improvements aimed squarely at this pain: object-specific share locks, so a sharing change on one object no longer has to queue behind an unrelated recalculation on another, and automatic recalculation of org-wide defaults and sharing rules that runs asynchronously and in parallel rather than as one long blocking job. Both are genuinely useful, and worth confirming are active in your org rather than assumed. Neither fixes the underlying design problem. A role hierarchy that's modelling matrix access it was never meant to, or an account that's already ten times past the skew threshold, still needs to be redesigned - the platform improvements just mean that redesign, and the ordinary recalculation that follows normal business activity, cost less time and cause less contention while it happens. Faster plumbing is not the same thing as a smaller pipe.
What to check first
- Pull a count of records per account and per owner. Anything approaching 10,000 is worth flagging now, as a design conversation, rather than after a recalculation job times out or a support ticket asks why access looks wrong.
- Count the role hierarchy's actual depth, and ask honestly whether any level exists to route around lateral access rather than to model real reporting. That's usually the level to replace with a public group.
- Before any bulk role, territory, or sharing-rule change, defer sharing recalculation and run it once at the end - not once per intermediate step.
- Before writing Apex managed sharing, confirm in writing that the requirement genuinely can't be expressed by a criteria-based rule or a public group. It's the one sharing mechanism that doesn't get faster just because Salesforce improves the platform underneath it.
A few questions worth asking before your next sharing review
What is data skew in Salesforce, exactly?
It's what happens when too many records concentrate under one parent account (account skew), one owner (ownership skew), or any single parent record generally (lookup skew) - conventionally flagged around the 10,000-record mark. Past that point, an ownership or hierarchy change that touches the skewed record can force Salesforce to recalculate access on a disproportionate number of related records at once.
Should cross-functional access use role hierarchy or public groups?
Public groups, almost always. Role hierarchy answers 'who reports up to whom' and grants access along that line automatically. It was never designed to represent two teams that both need visibility into the same accounts without reporting to each other - forcing that relationship into the hierarchy just adds depth without adding reporting meaning, and every added level compounds recalculation cost the org didn't need to take on.
Will Salesforce's newer, faster recalculation fix a slow org automatically?
It will make ordinary recalculation less disruptive - less queuing, less blocking, faster completion. It won't redesign a role hierarchy that's modelling matrix access, and it won't undo an account that's already accumulated records well past the skew threshold. Those are data-model and access-model decisions, and no amount of faster infrastructure underneath them changes what decision was actually made.
The bottom line
A Salesforce sharing model rarely fails all at once. It degrades quietly, one ownership change and one extra role level at a time, until an admin is troubleshooting an access complaint with no clean way to answer 'why does this user see this record' short of tracing every layer by hand. That's the actual cost of letting a sharing model go unreviewed - not a single outage, but a slow erosion of the one thing a sharing model is supposed to provide: a predictable, explainable answer to who can see what. If that answer has stopped being predictable in your org, a Salesforce Health & Roadmap review is built to find out where, and a scoped Fix Sprint is usually the right size of engagement once the redesign itself is well understood rather than a full reimplementation. Talk to an architect before assuming which one you need.
Sources and further reading
- Data Skew in Salesforce - Why It Matters - Salesforce Ben
- Recalculate Sharing Rules Manually - Salesforce Help
- Automatic Recalculation of Org-Wide Defaults and Sharing Rules - Salesforce Help
- Object-Specific Share Locks - Salesforce Help
- Platform Sharing Architecture - Salesforce Architects (architect.salesforce.com)
- Apex Managed Sharing - When to Use It and How It Works - SFDC Developers
Not sure whether your sharing model still matches how your org actually runs?
Written by CloudAvant Team - Senior Salesforce consultants and architects with hands-on enterprise delivery experience across Sales Cloud, Service Cloud, Experience Cloud, and complex multi-region implementations. More about CloudAvant.
