[SalesForce] DML “10 chunks exception” and weird pattern

I am aware of System.TypeException: Cannot have more than 10 chunks in a single operation exception and it seems to be a known bug. I am also aware, that there are some other ways one can encounter this exception.

However, after a while of playing with the limits, I found a pattern that shows how many records of some type one can insert in mixed-type DML. It seems to be:

maxRec = 2000 - (200 * T)
where
T - number of types in SObject[]
maxRec - max number of records of single type in sorted (by type) SObject[]

So, let's say we want to insert:

  • 1400 Accounts
  • 1 Contact
  • 1 Bar__c
  • 1 Foo__c

insert myListOfSobjects;

And that's perfectly fine. Now, if we would try to do the same, but instead of 1400 Accounts, we would try to insert 1401 of them, we should get our 10 chunks exception. Similarly, the following would work:

  • 1800 Accounts
  • 1 Foo__c

And it works as long as we'll try to insert 1800 Accounts. But wait, there's more.

If you try to add 1400 Accounts, 1 Contact, 1 Foo and 1 Bar, you could think – why couldn't I just add some more Foos? Here's your Collection:

  • 1400 Accounts
  • 1 Contact
  • 1 Bar__c
  • 201 Foo__c

Wrong (notice that we are far from 2000)! It seems that you cannot exceed the number of 200 within any type when one of your types reached the limit of maxRec = 2000 - (200 * T) ! So, to be more precise, what I found is:

maxRec = 2000 - (200 * T)
AND
maxRecForOthersTypes = 200
where

T - number of types in SObject[]
maxRec - max number of records of single type in sorted (by type) SObject[]
maxRecForOthers - records of type other then maxRec, if there is any. Limit for each type.

Now, the obvious, base question – why? I think it's hard to explain, as it's simply a bug, but seems to be a really deterministic one. Perhaps knowing the pattern, someone would have a better clue.

Best Answer

When you do a DML operation Salesforce breaks down the records into chunks of 200. So if you insert or update say 2000 Accounts Salesforce actually does 10 chunks of 200.

Now when you try to do a mixed-type DML operation Salesforce first breaks apart each object and then splits them into chunks of 200 rounding up. So in your first example

  • 1400 Accounts = 7 chunks of 200
  • 1 Contact = 1 chunk of 1
  • 1 Bar__c = 1 chunk of 1
  • 1 Foo__c = 1 chunk of 1

Which totals 10, so no problem. No lets look at your last example

  • 1400 Accounts = 7 chunks of 200
  • 1 Contact = 1 chunk of 1
  • 1 Bar__c = 1 chunk of 1
  • 201 Foo__c = 2 total chunks. 1 chunk of 200 and 1 chunk of 1.

Here we have a total of 11 chunks which breaks the limit, even though we have less than 2000 records total.


UDPATE:

Per @Mossi and further testing the chunking only applies when the List<sObject> contains mixed types (ie Contact(s) and Account(s)).

If you use a List<sObject> with that only contains 1 type (ie only Contacts, or only Accounts) then it doesn't chunk and you can insert more that 2,000 records.

Related Topic