---
title: "Ownership skew, explained by its symptoms"
url: "https://trailassembly.com/salesforce-ownership-skew/"
topic: "Architecture"
published: "2026-09-13T03:56:02+00:00"
updated: "2026-10-06T13:54:02+00:00"
error_codes: "UNABLE_TO_LOCK_ROW"
---

# Ownership skew, explained by its symptoms

**The answer, briefly:** ownership skew is one user owning more than about 10,000 records of an object. It costs you nothing day to day and a great deal at the moment something changes that user’s position (a role change, a deactivation, a sharing rule edit) because the platform then has to recalculate sharing for every one of those records in one operation.

## The symptoms, which is how you will meet it

Nobody discovers skew by looking for it. They discover it as one of these:

- **A role change that takes hours** and locks records while it runs. Moving a user in the hierarchy means recalculating every share for everything they own.

- **`UNABLE_TO_LOCK_ROW` during a data load** that has nothing obvious to do with the skewed user. The recalculation holds locks that your load wants.

- **A deactivation that fails or times out.** Deactivating a user with 400,000 records is not a click, it is a job.

- **Sharing rule changes that take a weekend.** Adding one rule triggers a recalculation across the affected records, and the skewed owner dominates the work.

The thing that makes it hard to diagnose is the delay. The skew is created over months by an integration inserting records, and the pain arrives on the day someone does something unrelated.

## Where it comes from

Almost always an integration user. A middleware account inserts records and becomes the owner by default, because nothing said otherwise. Three years later that user owns two million cases.

The other common source is a queue-like pattern built on a real user: unassigned leads owned by a “Lead Router” user, or closed records reassigned to an “Archive” account owner.

## Finding it

```apex
SELECT OwnerId, COUNT(Id)
FROM Case
GROUP BY OwnerId
ORDER BY COUNT(Id) DESC
LIMIT 10
```

Run it per object that matters. An aggregate query consumes query rows equal to the number of groups, not the number of records, so this is cheap even on a large object.

Anything over 10,000 is worth noting. Anything over 100,000 is worth doing something about before someone changes that user’s role.

## The fix, in order of preference

**1. Take the user out of the [role hierarchy](https://trailassembly.com/role-hierarchy/).** A user with no role has no hierarchy sharing to recalculate, which removes most of the cost at a stroke. This is the standard advice for integration users and it is genuinely the single most effective change.

The catch: nobody above them sees their records through the hierarchy any more. For an integration user who owns records nobody manages personally, that is usually fine. Check before you do it.

**2. Distribute ownership.** Assign records to the user who should actually own them, at creation. This is better data as well as better performance, and it is the fix that requires changing the integration.

**3. Use a queue.** Queues do not participate in the role hierarchy the way users do, so ownership by a queue does not create the same recalculation load. For genuinely unassigned work this is the right model anyway.

**4. If none of those are possible,** at least make the change window deliberate. Deactivating a skewed user or changing their role is a planned operation with Salesforce Support informed, not something done on a Tuesday afternoon.

## It is not the same as account data skew

Ownership skew is many records owned by one user. Account data skew is many child records under one parent account — both over roughly the same 10,000 threshold, both causing locking, and they have different fixes. The parent-child version is covered in [data skew](https://trailassembly.com/salesforce-data-skew/), and an org can have both at once on the same object.

## What it does not affect

Query performance, mostly. A skewed owner does not make your SOQL slow — that is [selectivity](https://trailassembly.com/selective-queries-at-scale/), a separate problem with a separate diagnosis. Conflating the two sends people optimising indexes when the actual issue is a sharing recalculation.

## Frequently asked

**Is 10,000 a hard limit?** No, it is the point where the cost becomes noticeable. There is no error at 10,001.

**Does it matter if the [org-wide default](https://trailassembly.com/org-wide-defaults/) is Public Read/Write?** Much less. With no sharing to calculate there is little to recalculate. The problem lives in orgs with Private or Read Only defaults, which is most orgs with anything sensitive.

**Can Salesforce fix it for me?** Support can run a recalculation as a background job and advise on a change window. They cannot make the skew not exist.

---

Source: https://trailassembly.com/salesforce-ownership-skew/
Trail Assembly — independent Salesforce write-ups.
