Salesforce Governor Limit Forecast Engine
A Visual Studio Code extension that predicts Salesforce governor limit risks before deployment using static and heuristic analysis of Apex classes, triggers, and Flow XML metadata.
Catch SOQL-in-loops, DML-in-loops, heap accumulation, callout risks, and more — before your code hits production.
Features
- Apex Static Analysis — Detects SOQL, DML, callouts,
@future, System.enqueueJob(), and loop nesting in .cls and .trigger files
- Flow XML Analysis — Parses
.flow-meta.xml files with BFS connector-graph traversal for loop containment detection
- Cross-File Analysis — Traces method calls across your entire workspace to detect governor limit risks spanning multiple classes
- Heuristic Estimation — Estimates CPU time, heap size, SOQL row counts, and DML row counts using configurable cost models
- Risk Scoring — Rates each governor limit as LOW / MEDIUM / HIGH based on estimated utilization percentage
- Inline Diagnostics — Warnings and errors appear directly in the VS Code editor with squiggly underlines
- Sidebar Panel — Real-time forecast breakdown with per-limit progress bars and actionable findings
- Developer Annotations — Override heuristic estimates per-operation using
// @governor-estimate comments
- Configurable Defaults — All 25 estimation constants are exposed as VS Code settings for project-wide tuning
- Scenario Simulation — Simulate specific DML scenarios with custom batch sizes
Getting Started
Prerequisites
- VS Code 1.85.0 or later
- A Salesforce DX project (with
sfdx-project.json)
Installation
- Open VS Code
- Go to the Extensions view (
Ctrl+Shift+X / Cmd+Shift+X)
- Search for "Salesforce Governor Limit Forecast Engine"
- Click Install
The extension activates automatically when it detects sfdx-project.json or an Apex file in your workspace.
Commands
Open the Command Palette (Cmd+Shift+P / Ctrl+Shift+P) and search for:
| Command |
Description |
SF Governor: Analyze Current File |
Analyze the active file |
SF Governor: Analyze Entire Workspace |
Scan all Apex and Flow files in the workspace |
SF Governor: Simulate Scenario |
Run a custom scenario with specific DML parameters |
Governor Limits Covered
| Limit |
Synchronous Cap |
| SOQL Queries |
100 |
| SOQL Rows Retrieved |
50,000 |
| DML Statements |
150 |
| DML Rows |
10,000 |
| CPU Time |
10,000 ms |
| Heap Size |
6,000,000 bytes (6 MB) |
| Callouts |
100 |
| Future Calls |
50 |
| Queueable Jobs |
50 |
Two Levels of User Control
The engine supports a three-tier priority chain for estimation values:
@governor-estimate annotation > VS Code settings > built-in defaults
Level 1: Per-Operation Annotations
Add // @governor-estimate comments directly above any SOQL or DML operation to override the heuristic estimate for that specific line:
// @governor-estimate rows=3
List<Contact> contacts = [SELECT Id, Name FROM Contact WHERE AccountId = :accId];
// @governor-estimate rows=1 cpu=5
update myRecord;
Syntax:
- Must be a single-line comment (
//)
- Place 1–3 lines above the target operation
- Supported keys:
rows, cpu
- Case-insensitive, unknown keys are ignored
Level 2: VS Code Settings
Tune project-wide defaults in your .vscode/settings.json or via the VS Code Settings UI:
{
"sfGovernor.estimation.soqlRowsFilteredDefault": 50,
"sfGovernor.estimation.loopIterationBase": 5,
"sfGovernor.estimation.heapPerSoqlRowBytes": 1024,
"sfGovernor.estimation.cpuCostSoqlMs": 3
}
Available Settings
General
| Setting |
Default |
Description |
sfGovernor.defaultBatchSize |
200 |
Default trigger batch size for simulation |
sfGovernor.analyzeOnSave |
true |
Automatically analyze files on save |
sfGovernor.riskThresholds |
{low: 0.5, medium: 0.75} |
Risk scoring thresholds as fraction of limit |
SOQL Row Estimation
| Setting |
Default |
Description |
soqlRowsFilteredDefault |
100 |
Rows for WHERE clause without LIMIT |
soqlRowsUnfilteredDefault |
200 |
Rows for unfiltered queries (no WHERE, no LIMIT) |
soqlRowsIdEqualityDefault |
1 |
Rows for WHERE Id = :var lookups |
soqlRowsAggregateDefault |
1 |
Rows for aggregate queries (COUNT, SUM, etc.) |
soqlRowsDynamicQueryDefault |
100 |
Rows for Database.query() dynamic queries |
soqlRowsCountQueryDefault |
1 |
Rows for Database.countQuery() |
DML & Loop Estimation
| Setting |
Default |
Description |
dmlRowsInTriggerLoop |
1 |
DML rows per execution inside trigger loop |
dmlRowsOutsideLoop |
200 |
DML rows for bulk operations outside loops |
loopIterationBase |
10 |
Base iteration count per loop depth (base^depth) |
CPU Cost Model (milliseconds)
| Setting |
Default |
Description |
cpuCostSoqlMs |
5 |
CPU per SOQL query |
cpuCostDmlMs |
3 |
CPU per DML statement |
cpuCostPerDmlRowMs |
0.01 |
Additional CPU per DML row |
cpuCostCalloutMs |
2 |
CPU per callout (Apex HTTP setup only) |
cpuCostLoopIterationMs |
0.5 |
CPU per loop iteration per nesting depth |
cpuBaseOverheadMs |
50 |
Flat base CPU overhead per transaction |
Heap Cost Model (bytes)
| Setting |
Default |
Description |
heapPerSoqlRowBytes |
2048 |
Heap per SOQL row (~10 field sObject) |
heapPerDmlPrepBytes |
512 |
Heap per DML record in prep buffer |
heapBaseOverheadBytes |
51200 |
Base heap overhead per transaction |
heapTriggerOldFactor |
0.5 |
Amortization factor for Trigger.old heap |
Flow Element Estimation
| Setting |
Default |
Description |
flowRecordLookupRows |
50 |
Rows for Get Records element |
flowRecordCreateRows |
1 |
Rows for Create Records element |
flowRecordModifyInLoop |
1 |
Rows for Update/Delete inside a loop |
flowRecordModifyOutsideLoop |
200 |
Rows for Update/Delete outside a loop |
flowSubflowSoqlRows |
50 |
SOQL rows from a subflow invocation |
flowSubflowDmlRows |
10 |
DML rows from a subflow invocation |
All estimation settings are prefixed with sfGovernor.estimation. in settings.json.
Example Output
FILE: AccountTrigger_HighRisk.trigger
RISK: HIGH RISK
Scenario: Trigger on Account (after update) with batch size 200
LIMIT ESTIMATED GOVERNOR %USED STATUS
------------------------------------------------------------------
soqlQueries 200 100 200% EXCEEDED
soqlRows 600 50,000 1% OK
dmlStatements 200 150 133% EXCEEDED
dmlRows 200 10,000 2% OK
cpuTimeMs 1,952 10,000 20% OK
heapSizeBytes 1,996,800 6,000,000 33% OK
FINDINGS: 2 critical, 0 warnings
[!!] SOQL Queries: 200 / 100 (200%)
Fix: Move SOQL queries outside the loop.
[!!] DML Statements: 200 / 150 (133%)
Fix: Collect records into a List<SObject>, then perform a single DML operation.
Feedback & Issues
Found a bug or have a feature request? Open the Command Palette (Ctrl+Shift+P / Cmd+Shift+P) and run "SF Governor: Submit Feedback" to send us your feedback directly from VS Code.
License
MIT