Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
Full Data Manipulation Language (DML) entry
How-to guide

How to write DML in Apex correctly

The DML statements are simple; the discipline is in bulkification, error handling, and respecting governor limits.

By Dipojjal Chakrabarti · Founder & Editor, Salesforce DictionaryLast updated May 20, 2026

The DML statements are simple; the discipline is in bulkification, error handling, and respecting governor limits.

  1. Build a list, do not DML in a loop

    Wrong: for (Lead l : leads) { update l; }. Right: List<Lead> toUpdate = new List<Lead>(); for (Lead l : leads) toUpdate.add(l); update toUpdate. One DML statement covers all records.

  2. Use Database methods for partial success

    Database.SaveResult[] results = Database.update(records, false). Loop the results to find which records failed and why. Critical for batch imports where some records will inevitably fail.

  3. Handle DmlException correctly

    Wrap DML in try-catch (DmlException e). Log the record IDs and error messages. Decide whether to retry, skip, or fail the whole batch based on the error type.

  4. Pre-validate when possible

    Validation rules fire on DML, but Apex pre-validation (checking required fields, format) before DML produces clearer error messages than letting the platform validation rule fail mid-transaction.

  5. Use upsert for repeatable imports

    When loading data from an external system, define an external ID field and use upsert. New rows insert; existing rows update. Avoids duplicate detection logic.

  6. Test with bulk data

    Apex unit tests should insert 200+ records in setup and run the triggered code on the full set. Tests that only exercise 1 record miss bulkification bugs that fail in production.

Gotchas
  • DML inside a loop fails on bulk data. Build a list, then DML once. This is the most common Apex bug.
  • Governor limits: 150 DML statements, 10,000 records per transaction. Hitting either aborts the entire transaction.
  • Mixed DML Exception: cannot insert User and Account in the same transaction without async. Set up affected objects need @future.
  • DML triggers cascading automation. A single update can fire triggers, workflows, processes, Flows; all counting against the same limits.
  • Upsert requires a unique external ID. Sending two records with the same external ID in one upsert call throws DUPLICATE_EXTERNAL_ID.

See the full Data Manipulation Language (DML) entry

Data Manipulation Language (DML) includes the definition, worked example, deep dive, related terms, and a quiz.