Salesforce PD1 · Domain 2 of 4

Salesforce PD1 Domain 2: Process Automation and Logic

The heaviest section of the exam and the core of Apex: what Flow can do, how Apex declares and executes logic, what SOQL, SOSL and DML return, and how triggers behave inside one transaction's limits and order of execution.

Exam weight
28%
Official objectives
9
Estimated questions estimate
~17
Suggested study time estimate
30–40 hrs

About 21 min read Reviewed October 2026

Overview

Process Automation and Logic is where the Platform Developer I exam tests whether you can actually write Apex. It covers the capabilities of declarative automation in Flow, Apex declarations (variables, constants, methods, modifiers and interfaces), control flow, SOQL, SOSL and DML with their return types, trigger and class best practices, governor limits, the save order of execution with recursion and cascading, exception handling, and combining Flow with Apex.

The section exists because Apex runs inside a shared, limited transaction that also contains flows, validation rules and other triggers. Code that works for one record in a test can fail on a 200-record data load, re-fire itself through a workflow field update, or roll back an entire batch because of one bad row. It builds directly on the data model and declarative-first thinking from Developer Fundamentals and supplies the logic that User Interface components call and that Testing, Debugging, and Deployment must cover.

How it's tested

Expect code reading and scenario design. Many questions present a short Apex snippet, trigger or query and ask what it returns, how many times something executes, or which limit it breaks. Others describe a requirement and ask for the best automation design, often with two or three answers to select. Read code line by line and count queries and DML inside loops.

  • Predict the output

    A snippet with a loop, switch, SOQL assignment or DML call is shown, and you choose its result, return type or the exception it throws.

  • Find the limit problem

    Code works for one record but contains SOQL or DML inside a loop, and you identify the failure under bulk load and the bulkified fix.

  • Order and automation design

    A requirement involves triggers, flows and validation rules, and you place them in the save order or choose the right before or after context and tool.

Reasoning it through

A trigger loops over Trigger.new and runs a SOQL query for each Contact's Account. A data load inserts 300 contacts. Triggers process records in chunks of 200, so the 101st query in the first chunk exceeds the synchronous limit of 100 and throws an uncatchable LimitException. The fix collects AccountIds into a Set, runs one query into a Map, and reads from the map inside the loop.

Objectives 9

Official objectives from the Salesforce outline, in outline order.

2.1 Identify the capabilities of the declarative process automation features.What Flow and approval processes can automate before you reach for Apex.
What it means
Flow is Salesforce's primary declarative automation tool: record-triggered flows (before-save for fast same-record updates, after-save for related records and actions), screen flows for guided user input, schedule-triggered flows, autolaunched flows called from Apex or other flows, and platform event-triggered flows. Approval processes handle multi-step approvals, and Workflow Rules and Process Builder are retired in favor of Flow.
What to understand
Know what Flow can do without code: create, update and delete records, send emails, call invocable Apex, run on a schedule, and run asynchronously after save. Also know where it stops: complex data processing, sophisticated error handling and some integration patterns still call for Apex.
How it shows up
A requirement such as updating a field on the same record before save, or creating a task when an opportunity closes, is described and you choose the right flow type or decide Apex is needed.
Common confusion
Candidates pick an after-save flow to update fields on the triggering record, when a before-save flow does it faster with no extra DML.
2.2 Understand how to declare variables, constants, methods, modifiers, Apex interfaces, and the appropriate use cases for each.Apex declarations, access modifiers, static versus instance, and interfaces.
What it means
Apex variables are strongly typed and default to null, including Integer and Boolean. Constants use static final. Access modifiers are private (the default), protected, public and global; static members belong to the class and persist for the transaction, while instance members belong to an object. Interfaces declare method signatures that a class must implement, as with Database.Batchable, Queueable, Schedulable and Comparable.
What to understand
Know which modifier fits: global only when code must be visible outside the namespace (managed packages, web services), public within the namespace, private by default for members. Know that virtual and abstract allow extension and that a class implementing an interface must implement every method it declares.
How it shows up
A snippet declares a variable without initializing it and adds to it, or asks which modifier lets a managed package expose a method, or which interface a class needs to be scheduled.
Common confusion
Candidates assume an uninitialized Integer is 0; it is null, and arithmetic on it throws a NullPointerException.
2.3 Given a scenario, assess how Apex control flow statements will execute and when to apply different control flow statements.if/else, switch, loops, break and continue, and SOQL for loops.
What it means
Apex supports if/else, switch on (with when values and when else) for Integer, Long, String, sObject and Enum values, traditional for loops, list or set iteration loops, while and do-while loops, and break and continue. A SOQL for loop iterates over query results in chunks to reduce heap use.
What to understand
Be able to trace a loop and give the exact count or final value, including do-while running at least once and continue skipping the rest of one iteration. Know that a SOQL for loop is the memory-efficient way to process large query results, though it still counts as one query.
How it shows up
A snippet with nested loops, a switch statement or a do-while condition asks for the printed value or the number of iterations.
Common confusion
Candidates treat do-while like while and miss that the body runs once before the condition is checked.
2.4 Given a scenario, write SOSL, SOQL, and DML statements in Apex, and assess what they will return.Query syntax, return types, bind variables and DML options.
What it means
SOQL queries one object (plus related objects through relationships) and returns List<sObject>, a single sObject when assigned to one, an Integer for COUNT(), or AggregateResult[] for aggregate functions. SOSL searches text across multiple objects and returns List<List<sObject>>. DML statements (insert, update, upsert, delete, undelete, merge) are all-or-none; Database methods such as Database.insert(records, false) allow partial success and return result objects.
What to understand
Know the exact return types, that assigning a SOQL query with zero rows to a single sObject variable throws a QueryException, that bind variables (:name) safely pass Apex values into queries, and that Database.SaveResult tells you which rows failed.
How it shows up
A snippet shows a query or DML call and asks what it returns, or a requirement says valid records must save even if some fail, pointing to Database methods with allOrNone set to false.
Common confusion
Candidates use SOQL to search a phrase across several objects, which is SOSL's job, or expect SOSL to return a flat list.
2.5 Given a scenario, follow best practices to write Apex classes and triggers.Bulkified, logic-less triggers with handler classes and correct context use.
What it means
Best practice is one trigger per object that delegates to a handler class, code bulkified to handle up to 200 records per trigger chunk, no SOQL or DML inside loops, collections and maps for lookups, and correct use of trigger context variables such as Trigger.new, Trigger.oldMap and Trigger.isBefore.
What to understand
Update fields on the triggering records in a before trigger by assigning to Trigger.new, with no DML; changes to other records belong in an after trigger with explicit DML. Trigger.new is read-only in after triggers, and Trigger.old is always read-only.
How it shows up
A trigger is shown with a query inside a loop or a DML update on Trigger.new in a before trigger, and you identify the flaw or choose the corrected design.
Common confusion
Candidates write update Trigger.new in a before trigger, which is unnecessary and throws an error, instead of just assigning field values.
2.6 Given a scenario, understand governor limits and their implications on Apex transactions.Per-transaction limits on queries, DML, rows, CPU and heap.
What it means
Key synchronous limits per transaction: 100 SOQL queries (200 asynchronous), 150 DML statements, 50,000 rows retrieved by SOQL, 10,000 rows processed by DML, 20 SOSL queries, 10 seconds of CPU time (60 asynchronous) and 6 MB heap (12 MB asynchronous). Exceeding any limit throws a LimitException that cannot be caught and rolls back the transaction.
What to understand
All code in one transaction shares the same limits, including triggers fired by your DML and other automation. The Limits class reports consumption, and asynchronous Apex gets higher limits for heavier work.
How it shows up
Code is shown processing records in a loop, and you identify which limit fails first at a given volume, or choose a bulkified or asynchronous fix.
Common confusion
Candidates wrap code in try/catch to handle a limit breach; LimitException cannot be caught, so only redesign avoids it.
2.7 Describe the relationship between Apex transactions, the save order of execution, and the potential for recursion and/or cascading.What runs, in what order, when a record is saved, and how logic re-fires.
What it means
When a record is saved, Salesforce runs system validation, before-save record-triggered flows, before triggers, custom validation rules and duplicate rules, saves the record without committing, then runs after triggers, assignment and auto-response rules, any workflow field updates, after-save record-triggered flows, roll-up summary updates to parents, and finally commits and runs post-commit logic such as emails and asynchronous jobs.
What to understand
Cascading happens when a save causes other saves, for example an after trigger updating related records or a roll-up summary sending the parent through its own save. Recursion happens when logic re-fires itself, such as an after update trigger updating its own records; use static variables or sets of processed IDs to stop it before the maximum trigger depth error.
How it shows up
A scenario asks whether a validation rule sees a value set in a before trigger, or why a trigger runs twice after a field update, and you answer from the order of execution.
Common confusion
Candidates think validation rules run before before triggers; custom validation runs after before triggers, so values set in a before trigger are validated.
2.8 Implement exception handling in Apex, including custom exceptions as needed.try/catch/finally, built-in exception types, custom exceptions and addError.
What it means
Apex uses try, catch and finally blocks with built-in exceptions such as DmlException, QueryException, NullPointerException and ListException. A custom exception is a class that extends Exception and whose name ends in Exception, thrown with the throw keyword. In triggers, addError on a record or field blocks the save and shows a message to the user.
What to understand
Catch specific exception types before the generic Exception, use finally for cleanup, and do not swallow errors silently. Know that LimitException cannot be caught and that addError in a before trigger is the standard way to reject a record with a friendly message.
How it shows up
A snippet with nested try/catch asks which block runs, or a requirement asks how to stop a record from saving with a custom message.
Common confusion
Candidates name a custom exception without the Exception suffix or forget to extend Exception, both of which fail to compile.
2.9 Given a scenario, use declarative functionality and Apex together to automate business logic.Invocable Apex in Flow, Apex launching flows, and splitting work by tool.
What it means
Flow and Apex combine in both directions: a flow calls Apex through a method annotated @InvocableMethod (one per class, static, public or global, taking and returning lists), with @InvocableVariable for structured inputs, and Apex can start an autolaunched flow through the Flow.Interview class.
What to understand
Design so each tool does what it does best: Flow for orchestration and admin-maintained rules, Apex for complex logic, heavy processing or callouts. Invocable methods receive inputs as lists so that Flow can bulkify calls when many records trigger the same flow.
How it shows up
An admin's flow needs a calculation or callout that Flow cannot perform, and you choose an invocable method signature or identify why an existing method is not visible in Flow Builder.
Common confusion
Candidates write an invocable method that takes a single record instead of a List, or put two invocable methods in one class.

High-yield concepts

The terms, rules and formulas this domain turns into questions most often.

  • Bulkification

    Writing Apex so it handles many records per execution by working with collections, querying once outside loops and issuing one DML statement per object.

    Remember
    Triggers receive up to 200 records per chunk, so code must never assume Trigger.new has one record.
    Tested as
    Almost every trigger question tests it, directly or through a limit failure.
    Trap
    Code that passes a single-record test but fails on a data load because it queries or saves inside a loop.
  • SOQL return types

    A query returns List<sObject>; assigned to one sObject variable it must return exactly one row; COUNT() returns an Integer; aggregate functions return AggregateResult[].

    Remember
    Assigning a zero-row result to a single sObject throws System.QueryException rather than returning null.
    Tested as
    'What is returned' and 'what happens' snippet questions.
    Trap
    Expecting a null value or an empty object when the query matches nothing.
  • SOSL

    Salesforce Object Search Language searches text across multiple objects and fields with FIND ... RETURNING, using the search index.

    Remember
    SOSL returns List<List<sObject>>, one inner list per object in RETURNING, in the order listed.
    Tested as
    Chosen when a scenario searches a term across several objects, such as a phone number in Accounts, Contacts and Leads.
    Trap
    Using several SOQL LIKE queries where one SOSL search fits, or casting the result to a flat list.
  • DML statement vs. Database method

    DML statements such as insert are all-or-none and throw a DmlException on any failure; Database.insert(records, false) saves valid rows and reports failures in SaveResult objects.

    Remember
    Use allOrNone false when some records may fail and the rest must still be saved.
    Tested as
    Scenarios about partial success in bulk loads or integrations.
    Trap
    Wrapping an insert statement in try/catch and expecting the good rows to be saved anyway.
  • Governor limits (synchronous)

    Per transaction: 100 SOQL queries, 150 DML statements, 50,000 rows queried, 10,000 rows in DML, 20 SOSL queries, 10,000 ms CPU and 6 MB heap.

    Remember
    Asynchronous Apex raises some limits, including 200 SOQL queries, 60,000 ms CPU and 12 MB heap.
    Tested as
    Counting queries or DML in a loop to find the first limit hit.
    Trap
    Assuming each trigger or each record gets its own limits rather than sharing one transaction's budget.
  • LimitException

    The exception thrown when code exceeds a governor limit, which ends the transaction and rolls back its changes.

    Remember
    It cannot be caught by try/catch, so prevention through bulkification or asynchronous processing is the only fix.
    Tested as
    Distractor answers propose catching it.
    Trap
    Choosing an answer that handles a limit breach with exception handling.
  • Before vs. after triggers

    Before triggers run before the record is saved and can change field values on Trigger.new without DML; after triggers run after the save, when record IDs and system fields are available.

    Remember
    Use before for validation and same-record field updates, after for work on related records or anything needing the new record's ID.
    Tested as
    Context-selection questions and snippet errors.
    Trap
    Running DML on Trigger.new in a before trigger, or editing Trigger.new in an after trigger, both of which fail.
  • Order of execution

    On save: before-save flows, before triggers, validation rules and duplicate rules, save, after triggers, assignment and workflow rules, after-save flows, roll-up summary updates, commit, then post-commit logic.

    Remember
    Before-save flows run before before triggers, and custom validation rules run after before triggers.
    Tested as
    Questions about which automation sees which value and why logic fires twice.
    Trap
    Placing validation rules ahead of before triggers, or assuming emails and asynchronous jobs run before commit.
  • Recursion control

    Recursion occurs when automation causes the same trigger to run again in the same transaction, such as an after update trigger updating its own records.

    Remember
    A static Boolean or a static Set<Id> of processed records in a handler class prevents repeated processing, because static variables last for the transaction.
    Tested as
    Scenarios where a trigger runs twice or hits the maximum trigger depth.
    Trap
    Using an instance variable as the guard, which resets each time a new handler object is created.
  • Custom exception

    A class that extends Exception and whose name ends with Exception, used to signal application-specific errors.

    Remember
    Throw it with throw new MyAppException('message'); constructors for message and cause are inherited automatically.
    Tested as
    Syntax questions and best-practice error handling.
    Trap
    Omitting the Exception suffix or the extends Exception clause.
  • @InvocableMethod

    An annotation that exposes a static Apex method to Flow and other automation as an Apex action.

    Remember
    Only one per class; the method must be public or global and static, and its input and output are lists to support bulk calls.
    Tested as
    The standard bridge when a flow needs logic Flow cannot perform.
    Trap
    Declaring a single sObject parameter or adding a second invocable method to the same class.
  • Static vs. instance members

    Static variables and methods belong to the class and persist for the whole transaction; instance members belong to each object created with new.

    Remember
    Static variables are the tool for transaction-wide state such as recursion guards and caches.
    Tested as
    Declaration questions and recursion design.
    Trap
    Expecting a static variable to keep its value across separate transactions.

Side by side

Concepts candidates mix up, compared on the point that decides the answer.

SOQL vs. SOSL

ConceptMeaningKey differenceCommon trap
SOQL Structured query on one object and its relationships Returns List<sObject>, Integer or AggregateResult[]; precise filters with WHERE Using LIKE across several objects instead of one search
SOSL Text search across multiple objects using the search index Returns List<List<sObject>> in RETURNING order Treating the result as a flat list of records

Before-save flow vs. before trigger vs. after trigger

ConceptMeaningKey differenceCommon trap
Before-save flow Declarative update of fields on the triggering record Runs first in the save order, with no DML needed Using an after-save flow for same-record updates
Before trigger Apex that runs before the save and can modify Trigger.new Validation and same-record changes with code-level logic Issuing DML on Trigger.new
After trigger Apex that runs after the save, before commit Record IDs are available; related-record changes need explicit DML Trying to modify Trigger.new directly

DML statement vs. Database method

ConceptMeaningKey differenceCommon trap
DML statement insert, update, upsert, delete as language statements All-or-none; any failure throws DmlException Expecting valid rows to save when one fails
Database method Database.insert(records, allOrNone) and similar allOrNone false saves valid rows and returns result objects Ignoring SaveResult and missing which rows failed

Exam traps

Each trap is an answer that looks right. Learn the clue that should change your mind.

  1. Catch the limit

    What candidates pick
    Wrap the loop in try/catch so the transaction survives a governor limit error.
    Why it looks right
    Exception handling is the usual way to deal with runtime failures.
    Why it's wrong
    LimitException cannot be caught; the transaction ends and rolls back regardless of handlers.

    Clue to watch for The scenario mentions bulk volumes, data loads or 'Too many SOQL queries'.

  2. DML on Trigger.new

    What candidates pick
    Add update Trigger.new at the end of a before update trigger to save field changes.
    Why it looks right
    In most code, changes are not saved until you issue DML.
    Why it's wrong
    In a before trigger, changes to Trigger.new are saved automatically; explicit DML on those records is redundant and throws an error.

    Clue to watch for The trigger context is before insert or before update and the changes target the same records.

  3. Null for no rows

    What candidates pick
    Check if the queried Account is null after Account a = [SELECT ... LIMIT 1].
    Why it looks right
    Many languages return null when nothing is found.
    Why it's wrong
    Assigning a zero-row SOQL result to a single sObject throws a QueryException before the null check runs; query into a List and check isEmpty().

    Clue to watch for A single sObject variable receives a query that might match no records.

  4. After-save for same record

    What candidates pick
    An after-save record-triggered flow to set a field on the record that triggered it.
    Why it looks right
    After-save flows can do everything a before-save flow can and more.
    Why it's wrong
    Updating the triggering record after save requires another DML and re-runs the save order; a before-save flow does it faster with no DML.

    Clue to watch for The only change is to fields on the triggering record itself.

  5. Instance-variable guard

    What candidates pick
    A non-static Boolean in the handler class to stop a trigger from running twice.
    Why it looks right
    It looks like a normal flag that remembers state.
    Why it's wrong
    Each trigger invocation can create a new handler instance, so the flag resets; recursion guards need static variables that persist for the transaction.

    Clue to watch for The trigger runs again because of a workflow field update or its own DML.

  6. SOQL for searching

    What candidates pick
    Several SOQL queries with LIKE to find a term in Accounts, Contacts and Leads.
    Why it looks right
    SOQL is the query language candidates practice most.
    Why it's wrong
    SOSL is designed for text search across multiple objects in one call and returns results grouped by object.

    Clue to watch for A free-text term searched across multiple objects or fields.

  7. All-or-none by default

    What candidates pick
    An insert statement inside try/catch to keep the good records from a mixed batch.
    Why it looks right
    Catching the DmlException seems to isolate the failures.
    Why it's wrong
    The insert statement rolls back every row when any row fails; Database.insert(records, false) is needed for partial success.

    Clue to watch for The requirement says valid records must be saved even if some fail.

Answer framework

For any Apex or automation scenario in this section, work through these steps before picking an answer.

  1. Decide whether Flow can meet the requirement on its own, and prefer a before-save flow for same-record field updates.
  2. If Apex is needed, pick the context: before trigger for validation and same-record changes, after trigger for related records or new IDs.
  3. Scan the code for SOQL or DML inside loops and count consumption against the transaction limits at the stated record volume.
  4. Check return types and failure modes: single-row assignments, SOSL nested lists, and all-or-none versus partial-success DML.
  5. Place every piece of automation in the save order and add a static guard wherever logic could re-fire itself through cascading updates.

Practice question

A trigger contains this line: Account acct = [SELECT Id, Name FROM Account WHERE AccountNumber = :num]; The trigger then checks whether acct is null. What happens when no Account has that number?

Choose one answer

Want more like this? The Salesforce PD1 practice test has questions for every domain.

Checklist

0 of 13

Tick each one you can do without notes. Your ticks stay in this browser.

Study strategy

Give this section the most time, since it carries the most weight. Start with Apex syntax basics: declarations, modifiers, static versus instance, interfaces and control flow, and trace small snippets by hand until you can predict output without running them. Anonymous Apex in the Developer Console is the fastest way to check yourself.

Then move to SOQL, SOSL and DML, writing each query type and printing what it returns. Memorize the return types and the zero-row QueryException, because these are easy points that are easy to lose.

Next, build triggers. Write one handler-based trigger, deliberately put a query in a loop, insert 201 records from anonymous Apex and read the error. Then fix it with sets and maps. Learn the main governor limit numbers at this point, while they mean something.

The order of execution and recursion are the most underestimated areas: draw the save sequence from memory and explain where before-save flows, validation rules and after-save flows fall. Finish with exception handling and invocable methods. Afterwards, practice code-reading questions under time pressure and review every miss by re-running the snippet.

FAQ

How much of the Platform Developer I exam is Process Automation and Logic?

It is 28% of the exam, the largest of the four sections. Applied to 60 scored questions that suggests about 17 questions as a planning estimate; Salesforce does not publish per-section counts.

Which governor limits should I memorize?

Know the synchronous per-transaction limits of 100 SOQL queries, 150 DML statements, 50,000 queried rows, 10,000 DML rows, 10 seconds of CPU time and 6 MB heap, plus the higher asynchronous values for SOQL, CPU and heap. Questions usually require counting usage in a loop against these numbers.

Do I need to know Flow on a developer exam?

Yes. The section starts with declarative process automation, and many design questions expect a before-save or after-save flow where it meets the requirement. You also need to know how Flow calls Apex through invocable methods.

What is the difference between SOQL and SOSL?

SOQL queries specific objects with precise filters and returns a list of records. SOSL searches text across multiple objects using the search index and returns a list of lists, one per object in the RETURNING clause.

How much of the order of execution do I need?

Know the main sequence: before-save flows, before triggers, validation and duplicate rules, save, after triggers, assignment and workflow rules, after-save flows, roll-up summaries, commit, then post-commit actions. Most questions ask which step sees a value or why logic runs twice.

How do I stop a trigger from running recursively?

Use a static variable in a handler class, such as a Boolean flag or a Set of processed record IDs, because static variables persist for the entire transaction. Check it before processing and update it afterwards.

Are there code snippets on the exam?

The exam guide frames many objectives as 'given a scenario', and this section involves predicting what Apex statements, queries and DML return. Practicing by reading and running short snippets is the most direct preparation.

Other CRM & Business Applications certifications

Where the same subject shows up in other exams. Cards marked "Same subject" open the matching domain.

Test your Domain 2 knowledge

You have covered Flow capabilities, Apex syntax, queries and DML, trigger best practices, governor limits and the order of execution. See whether you can predict what code does under timed conditions.

Keep going