Understanding Data Skew in Salesforce
Data skew in Salesforce refers to an uneven distribution of records that causes performance problems, locking errors, or sharing recalculation overhead. It typically happens when many records are associated with a single parent, owner, or lookup value — creating hotspots that impact DML operations, queries, and sharing calculations.
Common types of Data Skew
There are three common skew scenarios you should know:
- Ownership skew — many records owned by a single User or Queue (e.g., a user owning thousands of Accounts or Cases).
- Lookup (parent) skew — many child records referencing the same parent record (e.g., thousands of Contacts linked to a single Account or thousands of custom child records referencing one parent).
- Picklist / Value skew — many records share the same value on a lookup-like field or indexed field (less common but can cause selective index/search issues).
Why Data Skew matters
Data skew can manifest as:
- Row locking and “UNABLE_TO_LOCK_ROW” or deadlock errors during concurrent updates.
- Long-running or timeouts for bulk DML operations and batch jobs.
- Excessive sharing recalculations when ownership changes, causing CPU and database pressure.
- Slow list views or reports when filtering or aggregating skewed values.
How to detect Data Skew
Start with targeted SOQL queries and basic analytics to find concentration points. Example queries:
SELECT OwnerId, COUNT(Id)
FROM Account
GROUP BY OwnerId
HAVING COUNT(Id) > 1000
To find lookup skew (children per parent):
SELECT Parent__c, COUNT(Id)
FROM Child__c
GROUP BY Parent__c
HAVING COUNT(Id) > 1000
Other techniques:
- Use reports or external data tools to group and count records by Owner or Parent.
- Review debug logs and Apex/Batch job failures for UNABLE_TO_LOCK_ROW or long DML times.
- Salesforce Optimizer and debug metrics may surface sharing recalculation hotspots.
Mitigation and best practices
Mitigating data skew involves both data-model changes and operational changes:
- Distribute ownership — avoid having a single user/queue own a large number of records. Use multiple queues or pseudo-owners and rotate ownership where possible.
- Re-design relationships — for lookup skew, introduce intermediate parent records (sharding), or split data across multiple parents to remove the single hotspot.
- Use asynchronous processing — move bulk updates to Queueable, Batch Apex, or Platform Events so work is serialized and retries are possible.
- Order operations to minimize locks — when updating many records, process them in OwnerId/ParentId order so that locks are acquired consistently (and reduce chance of deadlocks).
- Reduce sharing recalculations — minimize frequent ownership changes; for mass ownership changes, schedule them during low-usage windows and break into smaller batches.
- Avoid large transactions — keep batch sizes small (e.g., 50-200 depending on scenario) to reduce the chance of locking conflicts.
- Use skinny indexes and selective filters — ensure queries are selective; consider composite keys or indexed fields to improve performance.
Apex example — processing by OwnerId to reduce locks
This pattern groups records by owner and processes per-owner batches to avoid multiple transactions contending for the same locks.
Map
for (Account a : [SELECT Id, OwnerId FROM Account WHERE /* your filter */ LIMIT 5000]) {
byOwner.computeIfAbsent(a.OwnerId, k -> new List
}
for (Id ownerId : byOwner.keySet()) {
List
// process group in its own transaction (e.g., Queueable or smaller DML chunks)
}
Real-world tips
- Plan for scale: when designing objects, estimate record counts and distribution.
- Monitor and alert on owner/parent counts that exceed thresholds.
- Where possible, avoid making heavily-used parent records the target of massive child record creation.
- Test batch/process behavior in a sandbox with realistic data distribution — not just with small sample sets.
Summary
Data skew is an important scalability and performance consideration in Salesforce. Recognizing ownership and lookup skews early in design and applying distribution, asynchronous processing, and careful batching will save you from sharing recalculation storms and record lock errors. When in doubt, measure — use GROUP BY counts, analyze failures, and apply targeted mitigations.








Leave a Reply