SfSkills Domains Docs GitHub

Home / architect / limits-and-scalability-planning

limits-and-scalability-planning

Use when planning a new org build for scale, auditing an existing org for governor limit exposure, or investigating a limit-related incident.

Open the skill folder on GitHub


Use this skill when designing a new Salesforce implementation for scale, auditing an existing org for governor limit exposure before a major release, or troubleshooting a production incident caused by limit violations. This skill provides a structured approach to understanding, measuring, and planning around Salesforce's governor limit architecture. It does not cover individual code optimization techniques — for code-level CPU and heap tuning, use apex-cpu-and-heap-optimization.


Before Starting


Core Concepts

How Governor Limits Work

Salesforce enforces governor limits per transaction to ensure fair resource sharing across all tenants on a shared infrastructure. Every Apex execution — whether triggered by a user action, a scheduled job, a platform event trigger, or an inbound API call — runs inside a transaction that has hard resource ceilings. When any ceiling is hit, the transaction fails immediately with a System.LimitException. There is no warning; the only prevention is design.

Limits are not shared across transactions. A Batch Apex job that processes 10,000 records in 10 batches of 1,000 gets a fresh governor limit reset for each batch execution. This is the fundamental reason Batch Apex exists: it provides a controlled way to work around single-transaction limits by chunking work.

Synchronous Transaction Limits

These apply to all Apex executed in the context of a synchronous user action (button click, page load, inbound REST/SOAP call, platform event trigger in synchronous mode):

ResourceLimit
SOQL queries100 per transaction
DML statements150 per transaction
DML rows10,000 per transaction
CPU time10,000ms (10 seconds)
Heap size6MB
Callouts (HTTP or web service)100 per transaction
Callout total timeout120 seconds
Records locked simultaneously10

Asynchronous Transaction Limits

Future methods, Queueable Apex, and scheduled Apex run asynchronously. They receive the same SOQL and DML limits as synchronous code, but CPU and heap are higher:

ResourceLimit
SOQL queries100 per transaction
DML statements150 per transaction
DML rows10,000 per transaction
CPU time60,000ms (60 seconds)
Heap size12MB
Callouts100 per transaction

The expanded CPU limit (6x synchronous) is why callout-heavy or compute-heavy operations should be moved to @future, Queueable, or Batch Apex.

Batch Apex Limits

Batch Apex (Database.Batchable) is the correct pattern for processing large data sets that exceed single-transaction limits. Key limits:

ResourceLimit
Records processed per 24-hour rolling window50,000,000 (50 million)
Batch jobs in queue or active simultaneously5
Minimum scope size1 record
Maximum scope size2,000 records
Recommended scope for most workloads200 records
CPU time per batch execute() call60,000ms (async limit)
Heap per batch execute() call12MB (async limit)

Scope size tuning: The default scope size when not specified in Database.executeBatch() is 200. Smaller scopes (50–100) reduce heap and CPU pressure per chunk at the cost of more execute() calls and more governor limit cycles. Larger scopes (1,000–2,000) maximize throughput but risk heap overflow if each record produces a large object graph. Tune scope size based on record complexity and the operations in execute().

Queue contention: The limit of 5 active/queued batch jobs applies across all jobs in the org. If multiple teams submit batch jobs simultaneously — data migrations, nightly rollups, integration sync jobs — they will queue behind each other. Plan batch job schedules to avoid collision. Apex Flex Queue (capacity: 100 jobs) can hold additional jobs in Holding state before they enter the active queue.

Org-Wide Metadata Limits

These apply to the entire org and do not reset per transaction:

ResourceLimit (Enterprise/Unlimited)
Custom objects800
Custom fields per object500 (Enterprise), 800 (Unlimited/Performance) — shared across all field types
Relationship fields (lookup + master-detail) per object40
Roll-up summary fields per object25
Active flows (all types)4,000
Custom tabs25
Custom apps10 (Enterprise), unlimited (Unlimited)
Apex classes5,000
Apex triggers5,000

The 500 custom fields per object limit is a shared pool. Long text area fields, formula fields, and lookup fields all count toward the same 500. Orgs that model a single object (e.g., Account) as a multi-purpose record type with many field sets risk exhausting this limit. Review field usage regularly and archive or deprecate unused fields.

Data Volume Planning

Data volume directly affects query performance, sharing recalculation, and storage. Plan around these thresholds:

Query performance thresholds:

SOQL selectivity rules: A query is selective when it uses indexed fields and the result set is a small fraction of total records. The selectivity thresholds that Salesforce uses internally:

Data skew — sharing recalculation: When a single user or a small set of users owns a disproportionate number of records (more than 10,000 records per owner is the threshold for skew concern), sharing recalculation after ownership changes becomes slow and can lock the org for extended periods. Common causes: integration users who own all imported records, queue-based ownership without ownership reassignment, single admin owning all accounts. Mitigation: distribute ownership, use public read/write sharing where data sensitivity allows, or use territory management.

Platform Event Limits

ResourceLimit
Event deliveries per 24-hour rolling window250,000 (standard orgs)
Event deliveries per 24-hour rolling window500,000 (high-volume add-on)
Maximum event message size1MB
Stored events (replay)3 days
Event bus throughputdependent on org type and event volume

Platform events are not a substitute for high-frequency streaming. At 250,000 deliveries per 24 hours, a single integration sending events every second hits the limit in roughly 70 hours of sustained operation. Batch or aggregate events where possible, and monitor usage against the limit in Setup > Platform Events.

Storage Limits

ResourceBasePer-License Add
Data storage (Enterprise)1GB20MB per user license
File storage (Enterprise)1GB2GB per user license
Data storage (Unlimited)1GB120MB per user license

Data storage counts every record in every standard and custom object, plus chatter activity, email logs, and archived records. File storage counts attachments, files, documents, and Content records. When either limit is approached, record creation fails. Monitor storage in Setup > Storage Usage and plan archival or deletion strategies before limits are reached.


Mode 1: Plan for Scale (New Build)

Use this mode when designing a new org, new feature, or new integration before development begins.

Step 1 — Build the Governor Limit Inventory

For each planned transaction type (user action, trigger, integration event, batch job), document:

  1. SOQL count: How many queries are needed? Include queries from helper methods, triggers on related objects, and validation rules that use formula fields backed by SOQL.
  2. DML count: How many DML statements and rows per transaction? Each insert, update, delete, upsert on a different SObject type is one DML statement.
  3. CPU budget: Estimate CPU usage. Complex formula field evaluation, large collection iterations, and string manipulation all consume CPU. If callouts are involved, they consume CPU during response parsing.
  4. Heap budget: Estimate peak heap. Large SOQL result sets, deep object graphs, and string concatenation in loops are common heap killers.

Step 2 — Identify Async Offload Candidates

Move any of the following to async execution:

Step 3 — Plan Data Volume Milestones

Project record growth for key objects at 1-year, 3-year, and 5-year intervals. Flag any object projected to exceed 1 million records and design queries to use indexed fields from day one. Large volume objects need:

Step 4 — Plan Storage

Calculate data storage: estimated records × average record size (roughly 2KB per standard record, more for objects with many long text fields). Add file storage for attachments, content versions, and emails. If projected storage exceeds 80% of allocated within 2 years, include an archival strategy in the design (Big Objects for cold archival, data export + deletion for compliance retention, or a Salesforce Shield archive strategy).

Step 5 — Check Metadata Headroom

Count existing custom objects, fields per object, and active flows. Calculate headroom against org limits. Flag any object approaching 400 custom fields (80% of the 500 limit) for a field audit before adding new fields.

Count deleted-but-not-yet-purged fields in that total. Setup > Object Manager > object > Fields & Relationships > Deleted Fields lists them; each one still consumes its slot in the 500/800 pool — and in the 40-relationship or 25-roll-up pool for its type — until the hard-delete process completes, which is up to 15 days after the delete. If the plan's remediation for a near-full object is "delete unused fields," schedule it 15 days ahead of the release that needs the headroom, or plan to Erase and Purge.


Mode 2: Audit an Existing Org for Limit Risk

Use this mode when reviewing an org before a major release, after an acquisition, or during a health check engagement.

Audit Checklist

Governor limit exposure:

Org-wide metadata headroom:

Data volume risks:

Platform event throughput:

Storage:

Risk Rating Model

Risk LevelCriteria
CriticalAny governor limit at > 90% in a production transaction, or metadata count > 90% of org limit
HighAny governor limit at 70–90% in production, or data volume > 5M on an object with non-selective queries
MediumLimits at 50–70% of ceiling, or objects projected to hit thresholds within 12 months
LowBelow 50% with no projected breach within 24 months

Use this mode when a production incident involves System.LimitException, timeout errors, or unexpected job failures.

Diagnostic Table

SymptomMost Likely CauseWhere to Investigate
Too many SOQL queries: 101SOQL inside a loop, or SOQL from managed packages consuming shared quotaDebug log — filter for SOQL_EXECUTE_BEGIN entries; check for loops
Too many DML statements: 151DML inside a loop, or multiple DML across too many object typesDebug log — filter for DML_BEGIN entries
CPU time limit exceededComplex formulas, large collection iteration, string operations, or unindexed sort in ApexDebug log — check CUMULATIVE_LIMIT_USAGE for CPU line; profile with System.currentTimeMillis() checkpoints
Heap size too largeLarge SOQL result set held in memory, deeply nested object graphs, or string concatenation in a loopReduce SELECT fields, process in chunks, use aggregateResult instead of record collections
Batch job stuck in queue5-job active/queued limit reachedCheck Apex Jobs in Setup; cancel or complete queued jobs before submitting new ones
Maximum batch size exceededscope argument to executeBatch() is > 2,000Reduce scope; default to 200
Callout loopFuture methods chained, or a trigger fires on an object updated by a callout responseReview async method chain; use Platform Events to decouple
Query took too longNon-selective SOQL on a large object (full table scan)Add indexed WHERE clauses; check SOQL selectivity thresholds
Record lock timeoutDML on the same records from concurrent transactionsReduce batch scope to limit the number of records locked simultaneously; stagger concurrent jobs
Platform events dropping250,000/24hr delivery limit exceededCheck Setup > Platform Events delivery metrics; throttle event emission rate

Limit Incident Response Steps

  1. Capture a debug log at FINEST level from the failing user or job. Look for LIMIT_USAGE_FOR_NS entries at the end — this shows the exact limits consumed when the failure occurred.
  2. Identify the worst-offending limit — the one closest to its ceiling.
  3. Trace the caller — which method, trigger, or flow caused the limit spike?
  4. Apply the shortest-path fix first — if SOQL is in a loop, extract it. If heap is too large, reduce the SELECT field list or chunk the data set.
  5. Validate the fix in a full-volume sandbox — limit errors that only occur at scale cannot be reliably caught in developer orgs with small data sets.
  6. Add monitoring — insert System.debug(Limits.getQueries() + ' / ' + Limits.getLimitQueries()) checkpoints in high-risk transactions to catch future creep before it becomes an incident.

Planning Strategies Reference

StrategyWhen to UseKey Consideration
Async offloadingAny non-user-facing operation that does not need same-transaction resultUse @future, Queueable, or Batch based on complexity and chaining needs
Chunking via Batch ApexProcessing > 10,000 records per business operationTune scope for heap budget; schedule to avoid queue congestion
Custom Settings for bypass flagsFeature flags, bypass logic for data migrationsCustom Settings are cached after first access; no SOQL cost after first read
Hierarchical rollup patternsParent aggregations over many child recordsUse Platform Events + Batch rollup rather than trigger-time rollup on millions of children
Skinny tablesRead-heavy queries on objects > 5M recordsRequires Salesforce support case; significant read performance gain
Big ObjectsHistorical archival, cold storageAsync SOQL only; no standard DML; designed for write-once-read-rarely patterns
Platform Events for decouplingCallouts, downstream processing, cross-org messagingMonitor 250K/24hr delivery ceiling; do not use as a high-frequency message bus without the add-on
Field audit before adding fieldsObject approaching 400 custom fieldsUnused fields still count against the 500 limit — and so do deleted ones, until hard delete completes (up to 15 days)

Step-by-step instructions for an AI agent or practitioner activating this skill:

  1. Gather context — confirm the org edition, relevant objects, and current configuration state
  2. Review official sources — check the references in this skill's well-architected.md before making changes
  3. Implement or advise — apply the patterns from Core Concepts and Common Patterns sections above
  4. Validate — run the skill's checker script and verify against the Review Checklist below
  5. Document — record any deviations from standard patterns and update the template if needed

Package files