Core objects, automation tools, and platform reference for Salesforce.
| Object | Represents | Notes |
|---|---|---|
| Account | A company or organisation. | The hub most other records hang off. Person Accounts are a separate, hard-to-reverse setting. |
| Contact | A person, usually linked to an Account. | Contact-to-multiple-accounts exists but is off by default. |
| Lead | An unqualified prospect. | Converts into Account + Contact + optional Opportunity. Conversion is effectively one-way. |
| Opportunity | A potential deal, with an amount, stage, and close date. | Drives forecasting. Stage changes are what most reporting is built on. |
| Case | A support request. | Core of Service Cloud. Has its own assignment and escalation rules. |
| Campaign | A marketing effort. | Campaign Members link it to Leads and Contacts for attribution. |
| Task / Event | Activities — calls, emails, meetings. | Both are Activity records underneath, which makes reporting on them quirky. |
| Custom object | Anything you define. | API name always ends __c. Managed-package objects carry a namespace prefix. |
- Lookup — a loose reference. The child survives if the parent is deleted, and it has its own sharing.
- Master-detail — a tight ownership link. Deleting the parent deletes the children, the child inherits the parent's sharing and has no owner of its own, and it enables roll-up summary fields.
- Converting master-detail to lookup is possible only if no roll-ups exist, and going the other way requires every child to have a parent. Choose deliberately.
- Junction object — a custom object with two master-detail fields, the standard many-to-many pattern.
- Roll-up summary fields (COUNT, SUM, MIN, MAX) work only over master-detail. For lookups you need a Flow, Apex, or a tool like DLRS.
- A record's 15-character ID is case-sensitive; the 18-character version is not. Always use the 18-character form in integrations.
- 1. Object — profiles and permission sets grant Create/Read/Edit/Delete per object.
- 2. Field — field-level security can hide a field even on a readable object.
- 3. Record — org-wide defaults, then role hierarchy, sharing rules, and manual shares open access up from there.
- Org-wide defaults are the floor: set them Private and open selectively, rather than starting open.
- Use permission sets, not profiles. A user has one profile but many permission sets — that's how you avoid a profile per person.
- Apex runs in system mode by default, ignoring all of the above.
with sharingandWITH USER_MODEare how you respect it — see the Apex tab.
| Group | Syntax | Notes |
|---|---|---|
| Traversal | Account.Owner.Name | Up through lookups. Five levels maximum. |
| Traversal | (SELECT ... FROM Contacts) | Down to children. Only one level. Plural relationship name. |
| Traversal | Parent__r.Field__c | Custom relationships end __r, custom fields __c. |
| Dates | TODAY, YESTERDAY, THIS_WEEK | Unquoted literals — quoting them breaks the query. |
| Dates | LAST_N_DAYS:30 | Also NEXT_N_QUARTERS:n, LAST_N_FISCAL_YEARS:n. |
| Filter | LIKE 'Acme%' | % and _ wildcards, on text fields only. |
| Filter | INCLUDES ('A';'B') | Multi-select picklists. Semicolon means AND, comma means OR. |
| Filter | :variable | Apex bind variable. Always bind rather than concatenating — SOQL injection is real. |
| Special | ALL ROWS | Includes soft-deleted and archived records. |
| Special | FOR UPDATE | Row locking. Overuse causes lock contention errors. |
| Special | WITH USER_MODE | Enforces FLS and sharing on the query. Prefer this in new Apex. |
| Search | FIND {term} RETURNING ... | SOSL — the only way to text-search several objects at once. |
Know the order of execution
Roughly: validation rules → before triggers → before-save Flows → save to database (not committed) → after triggers → after-save Flows → assignment/auto-response/workflow rules → escalation → roll-up summaries → commit.
Two automations touching the same field in different phases is the usual cause of a value that reverts.
Pick the right Flow type
Record-Triggered for reacting to a change — and prefer before-save when you're only setting fields on the same record, since it's dramatically faster and consumes no DML.
Screen Flow for guided user input. Scheduled for batch work. Autolaunched to be called from elsewhere.
One record-triggered Flow per object per timing
Several Flows on the same object and timing run in an unpredictable order. Consolidate into one with branching logic, or you'll be debugging race conditions.
Never put a DML or query element inside a loop
This is the number one Flow mistake and it hits governor limits the moment someone does a bulk import. Collect records into a variable inside the loop, then do a single Update after it.
Set fault paths
An unhandled Flow error shows the user an unhelpful message and emails the admin. Add a fault connector on every DML element with a real message.
Test with bulk data before deploying
A Flow that works on one record can fail on 200. Load a batch in a sandbox — that's the test that matters.
- Formula field — calculated on read, always current, no storage. First choice for derived values.
- Roll-up summary — aggregate over master-detail children with no code.
- Validation rule — blocks a save when the formula evaluates true. Note it fires on every save path, including integrations and data loads.
- Duplicate and matching rules — deduplication without a managed package.
- Custom Metadata Types — configuration that deploys between orgs, unlike Custom Settings data. Use these for anything a developer would otherwise hardcode.
- Only reach for Apex when the platform genuinely can't express it. Declarative config is upgraded by Salesforce; your Apex is your problem forever.
| Governor limit | Synchronous | Notes |
|---|---|---|
| SOQL queries | 100 | 200 in async. The limit a loop-query blows first. |
| Records returned by SOQL | 50,000 | Use a query loop or Batch Apex beyond this. |
| DML statements | 150 | Counts statements, not records — one update of 10,000 records is a single DML. |
| Records per DML | 10,000 | Per transaction. |
| CPU time | 10,000 ms | 60,000 ms async. Excludes database and callout wait time. |
| Heap size | 6 MB | 12 MB async. Large collections hit this. |
| Callouts | 100 | 120 s total. No callouts after DML in the same transaction without @future or Queueable. |
| Trigger batch size | 200 | Why bulkification matters. |
| Test coverage to deploy | 75% | Org-wide, and every trigger needs some coverage. |
Gotchas
- Apex runs in system mode — it ignores object permissions, field-level security, and sharing rules unless you say otherwise.
with sharingon the class enforces record-level sharing. It does not enforce object or field permissions.WITH USER_MODEon a query (andas useron DML) enforces FLS, object permissions, and sharing together. This is the modern answer — prefer it in new code.inherited sharingtakes the caller's context — the right default for a utility class.- A class with no sharing declaration defaults to without sharing in many contexts. Be explicit, always.
- This is the most common source of real Salesforce security findings. Exposing an Apex method to Lightning or a Site without user-mode enforcement leaks data across accounts.
- Lead conversion is effectively one-way. There's no supported unconvert; you're restoring from a backup or rebuilding by hand.
- Deleting a field is a two-stage process. It sits in a recycle bin for 15 days before permanent erasure, and its data is gone when it goes.
- You cannot reduce a text field's length or change certain field types once data exists — some changes require a new field and a migration.
- Validation rules fire on every save path, including data loads and integrations. A well-meant rule can break a nightly sync.
- Formula fields are recalculated on read and count toward query performance; deeply nested ones on large objects cause real slowness.
- Changing an org-wide default is asynchronous and can take hours on a large org while sharing recalculates.
- Sandboxes refresh on a schedule — Full copy every 29 days, Partial every 5, Developer daily. Plan around it.
- Test classes don't see org data unless annotated
@isTest(SeeAllData=true), which you should avoid. Create your own test data. - Salesforce force-upgrades all orgs three times a year (Spring, Summer, Winter). Read the release notes; things do change.
Tips
Setup → Users → Login. The only reliable way to answer "why can't they see this record" — permission theory rarely matches reality.
Setup → Debug Logs, or sf apex tail log. Set the Apex level to FINEST and the rest to NONE, or the useful lines drown in noise.
Developer Console → Execute Anonymous, or sf apex run. Perfect for a data fix. Wrap risky work in a rollback to preview: Savepoint sp = Database.setSavepoint(); ... Database.rollback(sp);
Limits.getQueries() and Limits.getLimitQueries() tell you how close you are. Log them in complex transactions before they fail in production.
Custom Metadata records deploy between orgs as metadata; Custom Settings data doesn't. Anything a developer might hardcode belongs here instead.
Free, hands-on, with a real practice org attached. Unusually, the vendor's own training is the best available resource for this platform.
Resources
sf command. Note sfdx is the retired predecessor.
developer.salesforce.com
Well-Architected framework
Salesforce's own guidance on when to configure versus when to code.
architect.salesforce.com
Release notes
Three forced upgrades a year — Spring, Summer, Winter. Read them.
help.salesforce.com
Microsoft Excel
Where most Salesforce data imports and exports begin and end.
build.ty1er.com