Apex runs in a multi-tenant world where the platform actively defends shared resources with governor limits. Code that works on one record and explodes on two hundred is the most common — and most avoidable — failure mode in a Salesforce org. After years of architecting enterprise-grade applications, these are the patterns I insist on.

Bulkify everything, always

Assume every trigger and method will receive a collection, because eventually it will — a data load, an integration, a mass update. The cardinal sins are SOQL or DML inside a loop:

// WRONG — a query per record; dies at scale.
for (Case c : cases) {
    Account a = [SELECT Risk_Score__c FROM Account WHERE Id = :c.AccountId];
    c.Priority = a.Risk_Score__c > 80 ? 'High' : 'Medium';
}

// RIGHT — one query, one map, set-based work.
Set<Id> ids = new Set<Id>();
for (Case c : cases) ids.add(c.AccountId);
Map<Id, Account> accts = new Map<Id, Account>([
    SELECT Id, Risk_Score__c FROM Account WHERE Id IN :ids WITH SECURITY_ENFORCED
]);
for (Case c : cases) {
    Account a = accts.get(c.AccountId);
    c.Priority = (a != null && a.Risk_Score__c > 80) ? 'High' : 'Medium';
}
Design for the bulk case and the single-record case comes free. Design for one record and the bulk case becomes a production incident.

Respect the user's permissions

Apex runs in system context by default, which means it will happily read and write fields the running user should never see. In an enterprise org that's a security finding waiting to happen. Enforce sharing and field-level security deliberately:

  • with sharing on classes that act on behalf of a user, so record visibility is respected.
  • WITH SECURITY_ENFORCED in SOQL to enforce object and field-level read access.
  • Security.stripInaccessible() before DML, so you never write fields the user can't edit.

Architect for maintainability, not just limits

Staying under governor limits is table stakes. The harder goal is code your team can still reason about in two years. A few habits that compound:

  • One trigger per object, delegating to a handler class — predictable order of execution.
  • Service-layer separation — business logic in testable classes, not buried in triggers or controllers.
  • Query selectively — only the fields and rows you need, with sensible LIMITs.
  • Async where it belongs — Queueable/Batch Apex for large volumes, keeping synchronous paths snappy.

Prove it under load

Every test class should include a bulk scenario — 200 records minimum — plus negative and permission cases. If a test only ever inserts one record, it isn't testing the thing most likely to break.

Takeaway

Scalable Apex isn't about clever tricks; it's discipline applied consistently: bulkify, query once, enforce security, and separate concerns. Do that and governor limits stop being a threat and become a guardrail.

Reviewing an Apex codebase or setting standards for a team? I'm happy to help.