Skip to main content

SF-0272 · Compare · Medium

What is single vs Bulk DML operation?

✓ Verified by Vikas Singhal · Last reviewed 5/17/2026 · Updated for Spring '26

A single DML operates on one record at a time — insert account; where account is a single sObject. A bulk DML operates on a collection — insert accounts; where accounts is a List<Account>. They produce the same end result for one record, but in any code path that might handle more than one record, only the bulk form survives production.

Side-by-side

// Single DML
Account a = new Account(Name = 'Acme');
insert a;

// Bulk DML
List<Account> accounts = new List<Account>{
    new Account(Name = 'Acme'),
    new Account(Name = 'Beta'),
    new Account(Name = 'Gamma')
};
insert accounts;

Both compile, both run. The difference shows up the moment you put a single DML inside a loop.

Why bulk wins

Apex’s synchronous governor limits cap a transaction at:

  • 150 DML statements total
  • 10,000 records affected by DML, total

A bulk insert of 200 records is one DML statement affecting 200 records. A loop doing 200 single inserts is 200 DML statements — and dies on the 151st. Every trigger and every async job in Salesforce can receive up to 200 records per invocation, so single-DML-in-loop is one of the fastest ways to break production.

// Anti-pattern — will fail at scale
for (Account a : accounts) {
    a.Industry = 'Technology';
    update a;                   // one statement per iteration
}

// Correct — one statement regardless of size
for (Account a : accounts) {
    a.Industry = 'Technology';
}
update accounts;                // one statement, up to 10,000 records

Comparison table

AspectSingle DMLBulk DML
Statement countOne per recordOne per list
Governor limit hitAt 151 recordsAt 10,001 records
Failure modeOne bad record kills the callDatabase.update(list, false) allows partial success
Trigger firesFires once per recordFires in batches of up to 200
Code readabilityShorter for true single-record workClearer intent for set-based work
Production safetyRisky in any loopRequired for any bulk-aware context

When single DML is genuinely fine

There are a few legitimate single-DML scenarios:

  • A controller method that creates exactly one record from a Lightning component, with no possibility of receiving a list.
  • A test setup method creating one parent record before bulk-creating children.
  • An admin utility in anonymous Apex doing a one-off fix.

Even in these cases, defensive habits favour wrapping the record in a single-element list — costs nothing, scales to 200 if the requirement changes.

Bulkification beyond DML

The “bulk” mindset isn’t just about DML. The same logic applies to SOQL, callouts, and email sends — anything metered by the runtime. The trigger handler pattern that production code uses everywhere is:

  1. Loop through Trigger.new once to collect IDs into a Set.
  2. Query once with WHERE Id IN :ids.
  3. Loop again to build a List<sObject> of records to update.
  4. One DML on that list.

That four-step pattern is what interviewers mean when they say “is this code bulk-safe?”

What interviewers are really looking for

The single-vs-bulk question is a bulkification proxy. The interviewer wants to know whether you’ve internalized that triggers and async jobs receive lists, not records. If you can explain why the 200-record batch size matters and quote the 150-DML governor limit by heart, you’ve answered the question they actually asked.

Verified against: Apex Developer Guide — Bulk DML Operations, Execution Governors and Limits. Last reviewed 2026-05-17 for Spring ‘26 release.