Understanding the "Too Many DML Rows: 10001" Error
The "Too Many DML Rows: 10001" error occurs when your Salesforce transaction attempts to process more than 10,000 records through Data Manipulation Language (DML) operations in a single execution context. This governor limit applies to records processed through insert, update, delete statements, approval processes, or database.emptyRecycleBin operations.
Causes of the "Too Many DML Rows: 10001" Error
-
Non-bulkified code: Your trigger, class, or flow is attempting to process too many records at once without proper bulkification techniques.
-
Large data volumes: When working with large datasets, especially during data migrations or mass updates, you're exceeding the 10,000 DML row limit.
-
Recursive triggers: Triggers that cause cascading updates can quickly multiply the number of DML operations, leading to exceeding the limit.
-
Custom applications or packages: Some installed applications or packages might perform excessive DML operations when processing records.
How to Handle the "Too Many DML Rows: 10001" Error
Implement Batch Apex
The most common solution is to use Batch Apex instead of standard synchronous processing:
apexpublic class YourBatchClass implements Database.Batchable<sObject> { public Database.QueryLocator start(Database.BatchableContext BC) { // Query to retrieve records return Database.getQueryLocator('SELECT Id, Name FROM YourObject__c WHERE Criteria = true'); } public void execute(Database.BatchableContext BC, List<sObject> scope) { // Process records in batches List<YourObject__c> recordsToUpdate = new List<YourObject__c>(); for(SObject record : scope) { YourObject__c obj = (YourObject__c)record; // Perform your logic recordsToUpdate.add(obj); } update recordsToUpdate; } public void finish(Database.BatchableContext BC) { // Logic after batch processing completes } }
To execute the batch:
apexYourBatchClass batch = new YourBatchClass(); Database.executeBatch(batch, 200); // Set appropriate batch size
Reduce Batch Size
If you're already using batch processing, try reducing the batch size:
apexDatabase.executeBatch(batchInstance, 100); // Smaller batch size
Optimize Triggers and Flows
Make sure your triggers and flows are properly bulkified and avoid processing unnecessary records:
apextrigger YourTrigger on YourObject__c (after update) { // Process only records that meet certain criteria List<YourObject__c> filteredRecords = new List<YourObject__c>(); for(YourObject__c record : Trigger.new) { if(record.SomeField__c == 'SomeValue') { filteredRecords.add(record); } } // Only process filtered records if(!filteredRecords.isEmpty()) { YourClass.processRecords(filteredRecords); } }
Use Queueable Apex for Complex Processing
For complex processes that might exceed limits, consider using Queueable Apex:
apexpublic class YourQueueableClass implements Queueable { private List<Id> recordIds; public YourQueueableClass(List<Id> recordIds) { this.recordIds = recordIds; } public void execute(QueueableContext context) { // Process records List<YourObject__c> records = [SELECT Id, Name FROM YourObject__c WHERE Id IN :recordIds]; // Perform your logic } }
Conclusion
The "Too Many DML Rows: 10001" error is a common Salesforce governor limit that restricts the number of records you can process in a single transaction. By implementing batch processing, optimizing triggers, and using asynchronous Apex, you can effectively work around this limitation while maintaining application performance and scalability in the Salesforce multi-tenant environment.