Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
DictionaryAApex
DevelopmentAdvanced

Apex

Apex is Salesforce's proprietary, strongly typed, object-oriented programming language that runs on the Lightning Platform servers.

§ 01

Definition

Apex is Salesforce's proprietary, strongly typed, object-oriented programming language that runs on the Lightning Platform servers. It looks like Java syntactically but is purpose-built for the Salesforce environment: every script runs inside a transaction, every operation counts against governor limits, and the language has first-class support for SOQL queries, DML operations, and platform events without external libraries.

Apex powers most of the custom logic in any production Salesforce org. Triggers fire Apex on record save events. Classes hold reusable business logic invoked from Lightning components, Flow actions, REST API endpoints, scheduled jobs, batch operations, and queueable jobs. Apex tests run in the same execution context as production code, with a 75 percent coverage requirement for deployment. Apex is the right tool when declarative automation (Flow, validation rules, formula fields) cannot express the logic, when bulk processing exceeds Flow's performance envelope, or when the integration pattern requires programmatic precision. Most Salesforce engineers spend the majority of their career writing, reading, and refactoring Apex.

§ 02

How Apex powers custom logic in Salesforce

The execution context and governor limits

Every Apex execution runs inside a transaction with strict governor limits: 100 SOQL queries, 150 DML statements, 50,000 records returned by SOQL, 10 callouts to external systems, 10 megabytes of heap, 10,000 milliseconds of synchronous CPU. The limits exist to keep the multi-tenant platform fair. Most Apex problems trace back to bulk operations that hit one of these ceilings. The bulkification pattern (process collections of records, do DML outside loops) is the foundational discipline every Apex developer learns first.

Triggers, classes, batch, queueable, and scheduled jobs

Apex code lives in two main forms: classes and triggers. Triggers fire on record save events (before/after insert, update, delete, undelete). Classes hold business logic and can be invoked from triggers, Flow, REST endpoints, and other classes. Specialized execution contexts handle workloads that exceed standard limits: Batch Apex processes large data sets in chunks, Queueable Apex chains async operations with rich data, Scheduled Apex runs on a cron-style schedule. Choosing the right execution context is half the design work; the other half is writing the actual logic.

SOQL and DML as first-class language features

Unlike Java or C#, Apex treats SOQL queries as inline language constructs: List<Account> accts = [SELECT Id, Name FROM Account WHERE Industry = ''Tech'']. The query compiler checks the SOQL at compile time against the org schema. DML operations like insert, update, delete, and upsert also work directly on sObject variables without external connection management. This tight integration is why Apex feels lighter than equivalent code in a general-purpose language; the database is part of the language, not an external dependency.

Test coverage and deployment requirements

Salesforce requires at least 75 percent code coverage across all Apex classes before deploying to production. Each class and trigger needs test methods that exercise its behavior, and the tests run during deployment. This requirement enforces a basic level of testing hygiene that many other platforms lack. Mature teams aim for 90 percent coverage and prioritize meaningful assertions over coverage padding. The Test class annotations (@isTest, @testSetup, @TestVisible) and the System.Assert methods are the foundation of every production-grade Apex codebase.

Sharing, with sharing, and without sharing

Apex classes can declare their sharing context: with sharing (respects the running user's record access), without sharing (ignores sharing, sees everything), or inherited sharing (uses the calling context). The default is implicit, which usually means without sharing in unannotated trigger handlers. Getting this wrong is a major security risk because Apex can return records the user should not see. The Salesforce Security Review and the Lightning Web Security framework both flag classes without explicit sharing declarations.

Apex versus Flow and the modern dividing line

For most CRUD automation, Flow is now the right tool. Apex remains the right choice for complex string parsing, recursive algorithms, performance-critical bulk operations over millions of records, callouts that need fine-grained transaction control, and any logic that exceeds Flow's expressiveness. The pragmatic rule is to start in Flow and switch to Apex when Flow starts feeling fragile, slow, or unmaintainable. The old "Apex for everything" stance from the early 2010s is no longer defensible, but neither is the reverse.

Apex versioning and API consideration

Each Apex class is associated with a Salesforce API version (currently in the 60s). The API version controls which platform features the class can access and how certain behaviors execute. Newer versions add features, deprecate behaviors, and tighten security defaults. Salesforce occasionally end-of-lifes very old API versions, forcing class updates. Keep classes on a recent API version (within the last two years) to avoid accumulated technical debt and to access the latest platform features.

§ 03

How to write your first Apex class

Writing Apex looks like writing Java with extra Salesforce-specific keywords. The hard part is not the syntax but the discipline: bulkification, governor limits, test coverage, and sharing context. Build in a scratch org or sandbox, test thoroughly with bulk data, and only then deploy to production with a change set or SFDX pipeline.

  1. Decide between trigger, class, batch, or queueable

    Pick the execution context that fits the use case. Trigger for save-event reactions. Class for reusable logic invoked from elsewhere. Batch Apex for nightly processing of large data sets. Queueable Apex for chained async work. Scheduled Apex for cron-based execution.

  2. Open the Developer Console or VS Code with Salesforce Extensions

    Setup > Developer Console for ad-hoc class authoring. VS Code with the Salesforce Extensions Pack for serious project work. SFDX commands authenticate, deploy, and run tests from the command line. Pick the toolchain that matches your team workflow.

  3. Create the class file with explicit sharing context

    Use the with sharing keyword by default. Explicit declaration documents intent and passes Security Review checks. Inherited sharing is acceptable for utility classes; without sharing should be the exception with a comment explaining why.

  4. Write the logic with bulkification in mind

    Process collections, not single records. Do SOQL queries outside loops. Do DML outside loops. Aggregate updates into one DML statement per object type. Every Apex review starts with checking these patterns.

  5. Write the test class with @isTest annotation

    Create a separate test class (or use @isTest at the method level). Include positive cases, negative cases, bulk cases (200 records), and boundary conditions. Use System.runAs to test sharing behavior with different user contexts.

  6. Run the tests and confirm coverage

    Run tests through Developer Console, VS Code, or SFDX. Confirm code coverage meets the 75 percent minimum (aim for 90 percent in production code). Review the coverage line-by-line, not just the percentage, to catch logic paths that tests skipped.

  7. Deploy via change set, metadata API, or SFDX

    Change sets work for ad-hoc deployment but slow down at scale. Metadata API and SFDX pipelines are the standard for serious team workflows. Use a CI/CD pipeline that runs tests on every deployment, fails on coverage drops, and gates production releases.

  8. Monitor the class in production

    Setup > Apex Jobs shows recent execution history. Setup > Email Logs shows Apex exception emails. Build a custom Error Log object and a Flow that logs caught exceptions, because the Apex Exception Email rarely lands with enough detail to debug from.

Key options
Sharing Contextremember

with sharing, without sharing, or inherited sharing. Explicit declaration documents intent and prevents accidental access escalation.

API Versionremember

Controls which platform features and behaviors apply. Keep on a recent version to access new features and avoid deprecation.

Test Coverageremember

Minimum 75 percent across the codebase to deploy. Aim for 90 percent in production code with meaningful assertions, not coverage padding.

Gotchas
  • Governor limits cap every Apex execution. SOQL inside loops, DML inside loops, and unbulkified triggers are the leading causes of LimitException in production.
  • Test coverage minimum is 75 percent, but coverage is not correctness. Tests with no assertions count toward coverage but verify nothing. Insist on meaningful assertions in code review.
  • Apex classes without an explicit sharing declaration default to without-sharing semantics in unannotated trigger handlers. Always declare with sharing explicitly to avoid unintended access escalation.
  • Recursion in triggers is a common bug pattern. A trigger that updates a record can fire itself again. Use static booleans or specialized frameworks (Trigger Handler patterns) to break the recursion.
  • Old API versions accumulate behavioral debt. A class on API 30 may execute differently from a class on API 60. Periodically upgrade API versions during planned refactoring windows.

Related free tools

§

Trust & references

Sources

Cross-checked against the following references.

Official documentation

Straight from the source - Salesforce's reference material on Apex.

Keep learning

Hands-on resources to go deeper on Apex.

Was this entry helpful?
Help us write better definitions. Quick reactions or detailed edit suggestions.

About the Author

Dipojjal Chakrabarti is a B2C Solution Architect with 29 Salesforce certifications and over 13 years in the Salesforce ecosystem. He runs salesforcedictionary.com to help admins, developers, architects, and cert/interview candidates sharpen their fundamentals. More about Dipojjal.

§

Test your knowledge

Q1. What is a Governor Limit in the context of Apex?

Q2. What is required before deploying Apex-related code to production?

Q3. What skill set is typically needed to work with Apex?

§

Discussion

Loading…

Loading discussion…