Skip to main content

SF-0338 · Scenario · Medium

When an account is created then automatically 3 contacts should be created. What type of trigger should it be? (Before or After)

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

after insert. The reason is structural: each Contact needs AccountId to link to its parent Account, and the parent Account’s Id only exists after the save commits. In a before insert trigger, Trigger.new is populated but the records have no Ids yet — there’s no key to put on the child Contact.

The reasoning, step by step

When Salesforce processes an insert, the order of relevant phases is:

  1. System validation (required fields, FLS, sharing).
  2. Custom validation rules.
  3. before insert trigger fires. Records exist only in memory. No Ids assigned.
  4. The DML commits to the database. Ids are now assigned.
  5. after insert trigger fires. Trigger.new and Trigger.newMap are populated with Ids.
  6. Roll-up summary recalculations, post-commit logic, post-commit events.

You can see why an attempt to do this in before insert fails:

trigger AccountAutoContacts on Account (before insert) {
    List<Contact> toCreate = new List<Contact>();
    for (Account a : Trigger.new) {
        toCreate.add(new Contact(
            LastName  = 'Auto Contact',
            AccountId = a.Id  // <-- a.Id is null here
        ));
    }
    insert toCreate; // links every Contact to a null parent
}

The Contacts get inserted, but they’re orphaned — AccountId = null — because a.Id wasn’t yet assigned when we read it. That defeats the entire purpose of the rule.

The right shape

trigger AccountAutoContacts on Account (after insert) {
    List<Contact> toCreate = new List<Contact>();
    for (Account a : Trigger.new) {
        for (Integer i = 1; i <= 3; i++) {
            toCreate.add(new Contact(
                FirstName = 'Auto',
                LastName  = a.Name + ' Contact ' + i,
                AccountId = a.Id // populated — we're after the save
            ));
        }
    }
    if (!toCreate.isEmpty()) insert toCreate;
}

A second reason: Trigger.new is read-only in after, and that’s OK here

In after triggers, the records in Trigger.new cannot be modified — they’re already saved. That restriction would matter if the rule said “set a field on the Account itself”; it doesn’t matter here because we’re inserting child Contacts, not editing the Account.

A useful framing for “before vs after”:

GoalTrigger phase
Default or sanitize fields on the record being savedbefore (insert/update)
Run logic that depends on the record’s Idafter (insert/update)
Insert/update/delete related recordsafter
Block the save with addErrorbefore

The 3-contacts-per-Account rule is “insert related records” → after insert.

What about a recursive risk?

When you insert Contacts inside the Account trigger, any Contact trigger on the org also fires. That’s normal — Salesforce trigger recursion is one level deep here (Account → Contact), not infinite. Watch out only if you have logic that updates the Account from within the Contact trigger, which could re-enter AccountTrigger.after update. Standard recursion guards handle that.

A subtler version of the question

Interviewers sometimes follow up: “What if the rule says default the Account’s Type__c to ‘Prospect’ AND create three contacts?” Now you split:

trigger AccountTrigger on Account (before insert, after insert) {
    if (Trigger.isBefore && Trigger.isInsert) {
        for (Account a : Trigger.new) {
            if (a.Type == null) a.Type = 'Prospect';
        }
    }
    if (Trigger.isAfter && Trigger.isInsert) {
        // create 3 contacts per account
    }
}

The default goes in before (mutate the record in flight, save once). The child creation goes in after (need the parent Id).

What interviewers are really looking for

The one-word answer is “after”. The signal is why: parent Id is needed and only exists post-save. Bonus points for naming the matrix — Trigger.newMap is null in before insert for the same reason — and for explaining the “before mutates the record being saved; after touches related records” rule of thumb.

Verified against: Apex Developer Guide — Triggers and Order of Execution, Trigger Context Variables. Last reviewed 2026-05-17.