A Salesforce debug log is a chronological transcript of everything Apex (and the surrounding platform) did during one transaction. Each line is an event — a tagged record like USER_DEBUG, SOQL_EXECUTE_BEGIN, DML_BEGIN, LIMIT_USAGE_FOR_NS. The log captures both your code and the platform’s work around it.
The major event categories
Apex execution
CODE_UNIT_STARTED/CODE_UNIT_FINISHED— entry into a class, trigger, anonymous block.METHOD_ENTRY/METHOD_EXIT— every method call.CONSTRUCTOR_ENTRY/CONSTRUCTOR_EXIT.SYSTEM_MODE_ENTER/SYSTEM_MODE_EXIT— when code switches to system mode.STATEMENT_EXECUTE— at FINEST level, every line.
Debug statements
USER_DEBUG— what yourSystem.debug()calls produced, with the line number and message.
Data operations
SOQL_EXECUTE_BEGIN/SOQL_EXECUTE_END— every query, with the SOQL text and row count.SOSL_EXECUTE_BEGIN/SOSL_EXECUTE_END.DML_BEGIN/DML_END— every insert/update/delete/upsert.CALLOUT_REQUEST/CALLOUT_RESPONSE— HTTP callouts.
Validation and automation
VALIDATION_RULE— every validation rule that ran and its result.WF_RULE_EVAL_BEGIN/WF_RULE_EVAL_END— workflow rules (legacy).FLOW_START_INTERVIEW/FLOW_END_INTERVIEW— Record-Triggered Flows and Screen Flows.TRIGGER_HANDLED(not a literal event, but trigger fires show up asCODE_UNIT_STARTED Trigger:).
Exceptions
EXCEPTION_THROWN— every thrown exception, including the type and message.FATAL_ERROR— unhandled exceptions that ended the transaction.
Governor limit reporting
LIMIT_USAGE_FOR_NS— at the end of each namespace’s portion of the transaction, a block listing every governor limit and how much was used. This is the most useful single section for performance tuning.
LIMIT_USAGE_FOR_NS
Number of SOQL queries: 12 out of 100
Number of query rows: 1,500 out of 50,000
Number of SOSL queries: 0 out of 20
Number of DML statements: 3 out of 150
Number of DML rows: 200 out of 10,000
Maximum CPU time: 8,924 out of 10,000 ← spike
Maximum heap size: 4,500,000 out of 6,000,000
CPU at 89% means you’re one slow loop away from a LimitException. Heap at 75% means a bigger payload will break.
Cumulative limits
CUMULATIVE_LIMIT_USAGE— appears once at the very end of the log: the total usage across the whole transaction, including all callouts, sub-transactions, and nested namespaces.
The log header — debug levels
The first few lines describe what’s captured:
APEX_CODE,FINEST;APEX_PROFILING,INFO;CALLOUT,INFO;DATABASE,INFO;
SYSTEM,DEBUG;VALIDATION,INFO;VISUALFORCE,INFO;WAVE,INFO;
WORKFLOW,INFO;NBA,INFO;
Each pair is Category,Level. The platform only emits events at or above the configured level for each category.
| Category | What it controls | Typical level |
|---|---|---|
| Apex Code | Apex execution events, USER_DEBUG | DEBUG or FINEST |
| Apex Profiling | METHOD/CONSTRUCTOR entries | INFO |
| Callout | HTTP requests/responses | INFO (raise to FINER for body) |
| Database | SOQL, SOSL, DML | INFO |
| System | System-level events | DEBUG |
| Validation | Validation rules | INFO |
| Workflow | Workflow rules and PB | INFO |
| Visualforce | VF lifecycle | INFO |
FINEST captures the most; ERROR captures only failures.
Truncation — the 20 MB ceiling
A single debug log is capped at about 20 MB. If your transaction generates more than that, the log is truncated with a MAXIMUM DEBUG LOG SIZE REACHED event near the end. The most common cause is Apex Code at FINEST with a long-running batch — you see the first part of the work, then the log stops.
Fixes when this happens:
- Lower the Apex Code level to
FINEorDEBUG. - Lower Apex Profiling to
INFO. - Add a
LIMITor scope the test to fewer records.
Reading a log effectively
The raw log is overwhelming. Use the right view for the question:
| Question | View |
|---|---|
| ”Why did this throw?” | Search for FATAL_ERROR or EXCEPTION_THROWN |
| ”Did my method actually run?” | Look for METHOD_ENTRY with the method name |
| ”How many SOQL queries fired?” | Count SOQL_EXECUTE_BEGIN, or read LIMIT_USAGE_FOR_NS |
| ”Why is this slow?” | LIMIT_USAGE_FOR_NS → CPU line, or Log Inspector → Limits panel |
| ”What did my debug statement print?” | Grep USER_DEBUG |
| ”Did the trigger fire twice?” | Count CODE_UNIT_STARTED Trigger: events |
What interviewers are really looking for
The naming check: “every event that happened in the transaction.” Strong signals: (1) name specific event types — USER_DEBUG, SOQL_EXECUTE_BEGIN, DML_BEGIN, LIMIT_USAGE_FOR_NS, (2) the limits block is the most valuable single section for performance, (3) debug level per category controls what’s captured, (4) logs are capped at 20 MB and can truncate, (5) different categories at different levels — Apex Code at FINEST is the most informative but the heaviest.
Verified against: Apex Developer Guide — Debug Log, Debug Log Levels. Last reviewed 2026-05-17.