Salesforce Record Locking Best Practices

Salesforce Record Locking Best Practices

Home > Blog > Salesforce
Thiago Terzi February 21, 2026

Share Now |

Salesforce record locking is one of the most misunderstood causes of performance issues in enterprise orgs. It often surfaces only after users begin experiencing slow saves, failed data loads, or the familiar UNABLE_TO_LOCK_ROW error. Behind the scenes, Salesforce applies row-level locks to maintain data integrity whenever a record is inserted, updated, or deleted. While this mechanism protects consistency, it can create contention when multiple users, automation processes, or integrations attempt to modify related records at the same time.

In high-volume Sales Cloud and Service Cloud environments, concurrent updates, roll-up summaries, approval processes, and bulk integrations can amplify locking behavior. Without proper architecture, this leads to avoidable data contention problems and unpredictable system performance.

This guide explains how Salesforce locking works, where it typically occurs, and the best practices to prevent and troubleshoot lock conflicts. If your organization is already experiencing recurring lock errors or large-scale concurrency issues, discussing with an experienced Salesforce consulting partner can help you assess architecture risks and implement scalable remediation strategies.

Salesforce Record Locking Mechanism

Salesforce enforces locks on records during DML to maintain referential integrity. When a record is being updated, that record (row) is locked so no other process can write to it until the transaction commits. During this time, other users or processes can still read the record, but only the last committed version. For example, if Process A updates a record and hasn’t committed yet, Process B, reading the same record, will see the old value. If B then tries to update it, Salesforce makes B wait for A to finish. If A finishes within 10 seconds, B will resume and apply its changes; if A takes too long, B gets an UNABLE_TO_LOCK_ROW, unable to obtain exclusive access to this record exception.

This locking is effectively “row-level”: each individual record is locked, not the entire object. However, Salesforce will also lock certain related records as needed. For example, any required or “don’t allow deletion” lookup parent (a master) will also be locked during a child DML. In practice, this means: if you update a Contact, the parent Account is locked too; if you update an Opportunity, the Account is locked; and if you update a child in a master-detail, the parent record is locked. These implicit locks on parent records are why updating one child can block updates on its siblings (since any sibling update would also need the parent).

Salesforce also uses locks when maintaining sharing or role hierarchies. Operations like changing a user’s role, territory assignments, or group membership acquire a broad lock (organization-wide) and must run serially to avoid contention. In bulk data loads or integrations, locking can become even more apparent. Proper transaction design and custom logic optimization are critical aspects of Salesforce App development when addressing concurrency at scale. For instance, if an ETL tool tries to update many contacts in parallel, Salesforce will internally group records to minimize locks (see below). But if two batches happen to hit the same parent record at once, one will inevitably lose the race and throw a lock error. In other words, Salesforce concurrent record updates must be carefully coordinated.

In practice, Salesforce provides tools to help diagnose locking issues. The Record Locking Cheatsheet (from Salesforce’s own documentation team) lists common lock behaviors for different objects and operations. When you encounter an UNABLE_TO_LOCK_ROW error, check the debug logs and consult this guide to see which parent or related record might have been locked. In summary, Salesforce locking prevents conflicts by serialization, but can cause lock contention if multiple actors vie for the same records at once.

Key Locking Behaviors

Direct record update/delete

Locks the record itself and any sharing rows. (Low contention if no parent.).

Parent-child (master-detail) relationships

Inserting or deleting a detail record locks its parent master record. Updating the parent record locks the parent only. This cascades up the hierarchy to ensure no detail can violate master data.

This behavior also matters in Salesforce junction object design, where two master-detail relationships can increase the number of related records involved in a transaction and make relationship architecture an important consideration for controlling lock contention.

Lookup relationships

Inserting or updating a record with a lookup locks the lookup target if the lookup is marked “Don’t allow deletion” (the default). If instead the lookup is set to “Clear the value”, then updates won’t lock the parent. (Tip: Use “Clear value on delete” for non-critical lookups to avoid extra locks.) In document-heavy environments, a SharePoint Salesforce integration can also contribute to lock contention when file metadata updates trigger changes on related parent records. If multiple document sync operations execute simultaneously, parent-level locks may temporarily affect parallel updates.

Roll-up summary fields

If an object has a roll-up summary (parent) field, any insert/update/delete on its child records locks the parent record. For example, adding a new Opportunity (child) will lock its Account (master) if the Account has a roll-up.

Tasks & Activities

Inserting or updating a Completed Task with an ActivityDate locks its Who (Contact/Lead), What (related record), and the Account if related. (This is often overlooked, but critical in high-load systems.)

Group/Territory changes

Changes to roles, territories, or public groups acquire an org-wide group lock. Avoid doing large job-like updates on these in parallel.

Understanding these behaviors is vital. For example, suppose two users independently update the same Contact’s fields. Both transactions will lock the Contact row. One succeeds first; the second waits, then either applies or throws an UNABLE_TO_LOCK_ROW if the wait exceeds 10 seconds. If those updates also touched the Account via a roll-up, that Account was locked too, meaning any other Contact update under that same Account would have had to wait as well. These interactions underline why we must plan for Salesforce record locking in design.

Salesforce Record Locking Scenarios and Tips

Even well-intentioned code can bump into locking issues. For example, consider two simultaneous processes on an Opportunity’s Amount. User A updates the amount from 100 to 150 via the UI, while User B (via code) reads the same Opportunity and adds 30. Without precautions, User B’s code will query the old value (100) and compute 100+30=130. If User B then tries to save 130 at the same time User A is still finishing, Salesforce makes B wait for A. When A commits (to 150), B resumes and overwrites the record with 130, leaving the final result wrong (130 instead of 180). This classic lost-update scenario happens because B read stale data while A held the lock.

The solution is to lock the record on read. In Apex, you can use FOR UPDATE in your SOQL: e.g.

[SELECT Id, Amount FROM Opportunity WHERE Id =:oppId FOR UPDATE];

This causes Salesforce to obtain an exclusive lock on the row when querying, making B wait for A before reading. In other words, B will see the updated value (150) before adding 30. Salesforce Ben explains that using FOR UPDATE ensures the code reads the latest committed values and holds the lock until DML completes. However, use it judiciously: FOR UPDATE holds locks longer (from query until transaction end), so it can increase wait times if overused. Only add it when you absolutely need to avoid stale reads (for example, money calculations or inventory counts).

Beyond coding patterns, here are key best practices to reduce lock contention:

Keep transactions short and efficient

Write Apex (and Flows) so that DML happens at the end of execution, not the start. Do time-consuming calculations or external calls before your DML, so the actual lock duration is minimal. Salesforce recommends “keep execution contexts short by writing efficient code,” because long-running jobs hold locks longer.

Limit siblings on a parent (avoid lookup skew)

Salesforce recommends avoiding more than 10,000 child records under one parent, because large data skews make that parent a hot lock spot. If an Account has 100,000 Contacts, every update to any Contact risks locking the Account for other contacts. If possible, split children across multiple parents or use a different architecture (like an associative custom object).

These Salesforce data skew issues can occur when too many records share the same parent, lookup value, or owner, creating hot spots that increase lock contention, sharing recalculation work, and transaction delays.

The problem becomes more significant in a Salesforce large data volume environment, where millions of records, high transaction throughput, and concurrent automation can turn concentrated parent-child relationships into recurring locking and performance bottlenecks.

Use granular locking (if available)

Newer Salesforce features include Granular Locking, which isolates locks to only the records you change. With granular locking, updating a child record does not automatically lock its parent. For example, with granular locking on, updating an Opportunity would no longer lock the Account. This can dramatically reduce contention in hierarchies. (Check that your org has granular locking enabled for master-detail and campaign hierarchies, as discussed by Salesforce.)

Design with bulk data loads in mind

For integrations or ETL jobs, batch size and ordering are critical. If you use Bulk API in parallel, Salesforce divides the load into 200-record batches. If records in different batches share a parent, the parent will be locked multiple times. For example, one blog explains that sending 10,000 Contact updates unordered in parallel caused four batches to each try locking the same Account. As a result, most attempts failed due to locks. The fix is to sort and group by parent before loading: put all contacts of an account in the same batch to minimize locks. Even if you use Bulk API 2.0, pre-ordering your CSV by parent can speed up loading and avoid contention. If parallel processing still causes errors, consider switching to serial mode or smaller batches.

Consider ETL integration patterns

During large data migrations, poorly designed updates can trigger unnecessary lock contention. Effective Salesforce integration patterns reduce risk by grouping records by parent, controlling batch sizes, and avoiding parallel updates on related hierarchies. When using Bulk API, route records by parent key where possible. If automation such as flows or roll-ups increases lock scope, consider staggering execution or processing data in structured chunks to improve stability and throughput.

Adjust lookup settings when feasible

As mentioned, a lookup field’s “deletion behavior” setting affects locking. If you can change a lookup from “Don’t allow deletion” to “Clear the value,” that parent record will no longer be locked when you update the child. Evaluate which lookups truly need enforced parent existence. Making a lookup optional (with clear-on-delete) can eliminate unnecessary parent locking.

Catch and retry lock exceptions

Even with planning, locks can still occur. In Apex and integration code, catch the UNABLE_TO_LOCK_ROW exception and retry the operation (after a brief pause) a couple of times. Salesforce will automatically retry a lock internally up to 10 times before failing, but you can also implement your own exponential back-off or queue for failed records. Often, a simple retry succeeds because locks are usually very short.

Monitor and Troubleshoot

Use Salesforce debug logs, the Record Locking Cheat Sheet, and tools like Event Monitoring to identify patterns of locks and errors. The official Record Locking Cheatsheet from Salesforce’s engineering team is especially helpful. It lists how different objects and operations lock parents or shares. Reviewing error logs for UNABLE_TO_LOCK_ROW and correlating timestamps can reveal which processes conflicted. In many cases, simply reproducing two processes in a sandbox (e.g., editing the parent while inserting children) reveals the locking culprit.

By combining these practices, you can prevent most Salesforce data contention problems. For example, put DML at the end of your transaction and avoid mixing many parents in one batch. Use FOR UPDATE only when necessary. Enable granular locking if available, and keep parent-child hierarchies narrow. When done well, Salesforce’s locking mechanism largely works invisibly, but when neglected, it can be a major source of errors and delays.

Salesforce Record Locking in Data Integrations

Data integrations deserve special attention. As one integration architect notes, if you push records in batches without regard to their parent IDs, you can easily run into multiple processes contending for the same parent locks. Consider an ETL tool sending 10,000 Contact updates by splitting them arbitrarily into parallel batches: if four contacts in the dataset belong to the same Account, each parallel batch might try locking that Account at the same time, causing three of them to fail. Instead, group your data by parent: sort the CSV by Account ID so all contacts of an account appear together. Then each batch locks that account only once. This simple step can make bulk data loads both faster and more reliable.

Beyond grouping records by parent, following broader Salesforce data integration best practices helps teams manage batch sizes, synchronization patterns, data quality, API usage, and error recovery while reducing the risk of integration jobs creating unnecessary contention.

In practice, when working with a Salesforce integration company, we apply these same principles. We advise clients to break large jobs into logical chunks (by parent or by date) and to avoid parallel processing when conflicts are likely. If you use Salesforce’s Bulk API, try running a few batches serially or reducing batch size on early tests. If using middleware or ETL frameworks, configure them to sort by parent or to use Salesforce’s PK Chunking features. Always include error handling: if a batch fails due to locking, have the integration pause briefly and retry only the failed records.

In marketing automation environments, a Marketo Salesforce integration can introduce additional concurrency when lead scoring updates, campaign member syncs, or lifecycle stage changes occur simultaneously. If those updates target the same Account or Contact hierarchies, record locks may increase during peak campaign activity.

Another tip: Salesforce’s newer Bulk API 2.0 and Data Import Wizard may handle some grouping automatically, but you still benefit from pre-sorting critical fields. And remember, lookup settings as mentioned above,e an integration job that writes to a required lookup field will lock that parent unless you’ve allowed clearing on delete. Finally, if your integration can use Platform Events or Streaming to serialize updates, that can also help avoid spikes of simultaneous updates. The bottom line is to plan for record locking in your integration design, not as an afterthought.

Summary

In summary, Salesforce Record Locking is how the platform guarantees data consistency, but it demands careful design when many updates happen at once. By respecting Salesforce’s locking rules and following best practices, you can avoid most UNABLE_TO_LOCK_ROW errors. Key strategies include grouping data by parent to reduce contention, keeping transactions short and DML at the end, using FOR UPDATE only when needed, and leveraging granular locking and clear-on-delete settings to limit parent locks. When a lock conflict does occur, catch it and retry or queue the change. Salesforce even provides a detailed [Record Locking Cheatsheet] and documentation to aid lock contention troubleshooting. By combining developer rigor with these platform features, organizations ensure that concurrent record updates happen smoothly, maintaining both performance and data integrity.

Recent Posts

Salesforce Integration Tools: Middleware, iPaaS, and Connector Guide
August 28, 2026
8 Best Tips for Efficient Account Management in Salesforce
August 28, 2026
Salesforce Data Integration: Strategy, Mapping, and Synchronization Guide
August 25, 2026
Jira Salesforce Integration: Complete Planning and Setup Guide
August 18, 2026

Request a Free 30-Minute Salesforce Consultation

Whether it’s implementation, integration, or custom development—let’s discuss the right solution for your organization.

    Thiago T

    Senior Salesforce Consultant - Co-Founder @ dgt27

    Thiago is a highly skilled full-stack Salesforce developer with over 10 years of experience. He has successfully implemented Salesforce solutions for clients from various walks of life. His expertise extends across different sectors, including government, non-profit organizations, large and small companies, as well as universities. Thiago's diverse experience allows him to tailor Salesforce solutions to meet the unique needs and challenges of clients in different industries. Currently, he leads a team of 10x certified Salesforce developers across the US, Europe, and South Asia.

    Leave Comment

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    Was this blog helpful?

    Was this blog helpful?