Introduction
The Salesforce Certified Platform Developer credential, still widely called Platform Developer I or PD1, is the core Salesforce developer certification. It validates that you can build custom business logic and interfaces with Apex, Lightning Web Components and declarative tools, and test and deploy that work.
The current exam has changed in two ways that older guides miss: the official name dropped the "I", and the outline now includes Agentforce for Developers objectives. This guide covers the current outline, the code patterns that show up again and again, and a study plan. Exam facts come from the official Platform Developer exam guide.
Understanding the Platform Developer Exam
Exam Specifications
- Questions: 60 scored multiple-choice/multiple-select, plus up to 5 unscored
- Time limit: 105 minutes
- Passing score: 68%
- Registration fee: US$200 (retake US$100), plus applicable taxes
- Delivery: online proctored or onsite at a testing center
- Prerequisite: none. Salesforce recommends, but does not require, the Platform Administrator certification.
What Makes This Exam Challenging?
Unlike the Administrator exam, Platform Developer expects you to:
- Read and reason about Apex and LWC code, often spotting the one line that breaks
- Know governor limits well enough to recognize code that will fail at scale
- Choose between declarative and programmatic solutions for a given requirement
- Understand the save order of execution and how triggers, flows and validation interact
Exam Topics Breakdown
The current outline has four sections.
1. Developer Fundamentals (27%)
- Multi-tenant concepts and design frameworks such as MVC and the Lightning Component Framework
- Declarative vs. programmatic customization, including governor limits, formula fields and roll-up summaries
- Designing and accessing the data model: objects, fields, relationships and external IDs
- Use cases and limitations of Agentforce for Developers
Relationship types you must know cold:
| Feature | Lookup | Master-Detail |
|---|---|---|
| Parent required on child | Optional by default | Always required |
| Delete parent | Child kept (configurable) | Children deleted |
| Sharing and ownership | Independent | Child inherits from parent |
| Roll-up summary fields on parent | No | Yes |
Querying across a relationship:
Contact queriedContact = [
SELECT Id, Account.Name, Account.Industry
FROM Contact
WHERE Id = :con.Id
];
System.debug(queriedContact.Account.Name);
2. Process Automation and Logic (28%)
The largest section. It covers:
- Capabilities of declarative automation (Flow) and when to use Apex instead
- Variables, constants, methods, modifiers and interfaces
- Control flow, SOQL, SOSL and DML, and what each statement returns
- Apex class and trigger best practices
- Governor limits and their effect on a transaction
- The save order of execution, recursion and cascading
- Exception handling, including custom exceptions
Bulkify everything. This is the single most tested idea on the exam:
// BAD: query inside a loop - hits the SOQL limit with large batches
for (Account acc : accounts) {
List<Contact> cons = [SELECT Id FROM Contact WHERE AccountId = :acc.Id];
}
// GOOD: one query for the whole batch
Set<Id> accountIds = new Set<Id>();
for (Account acc : accounts) {
accountIds.add(acc.Id);
}
List<Contact> cons = [SELECT Id, AccountId FROM Contact WHERE AccountId IN :accountIds];
Keep logic out of the trigger body with a handler class:
trigger AccountTrigger on Account (before insert, after insert) {
AccountTriggerHandler.handleTrigger();
}
public class AccountTriggerHandler {
public static void handleTrigger() {
if (Trigger.isBefore && Trigger.isInsert) {
beforeInsert(Trigger.new);
}
}
private static void beforeInsert(List<Account> newAccounts) {
for (Account acc : newAccounts) {
acc.Name = acc.Name.toUpperCase();
}
}
}
Asynchronous Apex at a glance:
// Future method: simple fire-and-forget; parameters must be primitives or collections of primitives
@future
public static void updateRecordsAsync(Set<Id> recordIds) { }
// Queueable: accepts sObjects and complex types, and can chain another job
public class UpdateRecordsQueueable implements Queueable {
private List<Account> accounts;
public UpdateRecordsQueueable(List<Account> accounts) { this.accounts = accounts; }
public void execute(QueueableContext context) { update accounts; }
}
// Batch Apex: large data volumes, processed in chunks (default scope of 200 records)
public class UpdateAccountsBatch implements Database.Batchable<SObject> {
public Database.QueryLocator start(Database.BatchableContext bc) {
return Database.getQueryLocator('SELECT Id, Name FROM Account');
}
public void execute(Database.BatchableContext bc, List<Account> scope) { update scope; }
public void finish(Database.BatchableContext bc) { }
}
3. User Interface (25%)
- Preventing UI and data-access security vulnerabilities (for example SOQL injection, and enforcing sharing and field-level security)
- Displaying custom UI with Lightning components, Flow and Visualforce
- Lightning Web Components: the framework, benefits and events
- Using Apex with page components, including Lightning components, Flow and Agentforce
LWC example. Note that class fields are reactive by default. You only need @track when you mutate properties inside an object or array and want the template to re-render:
// helloWorld.js
import { LightningElement } from 'lwc';
export default class HelloWorld extends LightningElement {
message = 'Hello, Salesforce!';
handleChange(event) {
this.message = event.target.value;
}
}
<!-- helloWorld.html -->
<template>
<lightning-card title="Hello World Component">
<div class="slds-m-around_medium">
<lightning-input label="Enter Message" value={message} onchange={handleChange}></lightning-input>
<p class="slds-m-top_medium">{message}</p>
</div>
</lightning-card>
</template>
4. Testing, Debugging, and Deployment (20%)
- Writing tests for triggers, controllers, classes and flows using different sources of test data
- Salesforce DX, Salesforce CLI and the Developer Console
- Debugging and monitoring flows, performance, and asynchronous and batch jobs
- Environments and the process for deploying code and configuration
Remember that Apex needs at least 75% code coverage, with all tests passing, before you can deploy to production.
Test class example:
@isTest
private class AccountTriggerTest {
@testSetup
static void setupTestData() {
List<Account> accounts = new List<Account>();
for (Integer i = 0; i < 200; i++) {
accounts.add(new Account(Name = 'Test ' + i));
}
insert accounts;
}
@isTest
static void uppercasesNameOnInsert() {
Account acc = new Account(Name = 'New Test Account');
Test.startTest();
insert acc;
Test.stopTest();
Account inserted = [SELECT Name FROM Account WHERE Id = :acc.Id];
Assert.areEqual('NEW TEST ACCOUNT', inserted.Name, 'Account name should be uppercase');
}
}
Study Strategy for Developers
Phase 1: Foundations (Weeks 1-2)
- Work through the official trail and Trailmix linked from the exam guide: "Study for the Platform Developer Exam" and "Prepare for Your Salesforce Platform Developer Certification".
- Build small projects in a Developer Edition org: a custom object with a trigger and handler, a simple LWC that calls Apex, and test classes for both.
Phase 2: Deep Dive (Weeks 3-4)
- Governor limits: SOQL, DML, CPU time and heap, and which patterns blow them.
- Order of execution: where before triggers, validation rules, after triggers and flows run in a save.
- Testing patterns: test data factories,
Test.startTest()/Test.stopTest(), and mocking callouts.
Phase 3: Practice and Review (Week 5)
- Timed practice exams. Our Platform Developer I practice exam follows the current section weights and is heavy on code-reading questions.
- Review every miss until you can explain the governor limit or best practice behind it.
Common Exam Mistakes to Avoid
1. Mixing up trigger context variables
Trigger.new // List<SObject>: new versions of the records
Trigger.old // List<SObject>: old versions (update and delete only)
Trigger.newMap // Map<Id, SObject>: not available in before insert
Trigger.oldMap // Map<Id, SObject>: old versions keyed by Id
Trigger.isBefore, Trigger.isAfter
Trigger.isInsert, Trigger.isUpdate, Trigger.isDelete, Trigger.isUndelete
2. Forgetting the per-transaction governor limits
Some of the most commonly tested synchronous limits, from the Apex execution governors and limits reference:
- 100 SOQL queries (200 asynchronous)
- 150 DML statements
- 50,000 records retrieved by SOQL
- 10,000 records processed by DML
- 6 MB heap (12 MB asynchronous)
3. Weak test classes
Don't: rely on @SeeAllData=true or existing org data, skip bulk tests, or skip negative cases.
Do: create your own test data, test with 200+ records, test the failure paths, and assert outcomes rather than just running code for coverage.
Essential Resources
Official Salesforce
- Apex Developer Guide and Lightning Web Components Developer Guide
- The Platform Developer exam guide, for the exact objectives
- Trailhead: the cert prep trail and Trailmix linked from the guide
Development Tools
- VS Code with the Salesforce Extensions
- Salesforce CLI (
sfcommands) - Developer Console for quick queries and logs
Exam Day Strategy
Time Management
With 105 minutes for up to 65 questions you have about 1.6 minutes per question. A workable split:
- First pass (about 50 minutes): answer what you know, flag the rest
- Second pass (about 40 minutes): work through flagged questions
- Review (about 15 minutes): recheck flags, make sure nothing is blank
Question Analysis
- Read the whole question and every option
- Identify what is being asked: a best practice, an error, a requirement or an output
- Eliminate options that break governor limits or ignore bulk processing
- Prefer the declarative answer when it fully meets the requirement
After Certification: Next Steps
- Keep it active: complete the Platform Developer maintenance badge on Trailhead once a year.
- Go deeper: Platform Developer II builds directly on this exam and requires it. If you spend most of your time in the front end, JavaScript Developer (formerly JavaScript Developer I) is a parallel track.
- Plan your path: see the developer certification path for how the credentials fit together.
Frequently Asked Questions
Is Platform Developer I still called PD1?
The official name is now Salesforce Certified Platform Developer, but most people still call it PD1. Platform Developer II keeps its name.
Do I need the Administrator certification first?
No. There is no prerequisite. Salesforce recommends Platform Administrator, and admin knowledge helps with the declarative vs. programmatic questions.
How much Agentforce is on the exam?
Agentforce appears in two objectives: the use cases and limitations of Agentforce for Developers, and using Apex with page components including Agentforce. Expect a handful of questions, not a whole section.
What is the passing score?
68%, per the official exam guide.
Conclusion
Platform Developer rewards hands-on coding more than memorization. Write bulkified code, learn the order of execution, test properly, and practice reading code under time pressure. When you are ready to test yourself, try the Platform Developer I practice exam.