Theoretical question please.

When writing a batch class and using a start method that returns a QueryLocator (or Iterable for that matter), we can potentially include child accounts in the query. For example: SELECT Id, (Select Id From Contact) FROM Account.

Now let's say the batch is being executed with a scope size of 200. Which records would scope per this 200 parameter? Is it 200 accounts? Or is it counting retrieved rows - each account as 1, and then as many contacts as it has? And if that's the case, what happens if the very first retrieved account has 203 contacts? So 1 account and 199 of its contacts are transferred to the execute method, what happens in the next execution?

Will it remember to pick up those remaining 4 contacts? And how will they be associated to the account from the previous execution, given that by defition we're actually transferring account records and not contact records?

Many thanks!

1 Answer 1


It's 200 top-level records (e.g. in your example, 200 Accounts). There can be as many children as necessary, even thousands per record. However, including a child relationship query will significantly increase the start method's execution time, and may even cause the start method to time out if there are sufficient number of children. It is strongly advisable to query children in the execute method to make sure that the start time is not severely impacted.

  • So beyond the slow start method execution time, since we don't really have any control over the number of child records entering each execute method - we could also exceed a governor limit if we perform any DML on the child records, correct?
    – EranV
    May 14, 2020 at 23:02
  • 1
    @EranV Yes, if you have large accounts with many thousands of contacts, you could end up blowing any of a number of limits, including heap, CPU, DML, etc.
    – sfdcfox
    May 14, 2020 at 23:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .