Stage History
Stage History in Salesforce is the record of every Stage transition an Opportunity has gone through over its lifetime, stored in the OpportunityHistory standard object and surfaced through the Opportunity History report type.
Definition
Stage History in Salesforce is the record of every Stage transition an Opportunity has gone through over its lifetime, stored in the OpportunityHistory standard object and surfaced through the Opportunity History report type. Each time a user changes an Opportunity's Stage, Amount, Probability, Close Date, or Forecast Category, Salesforce creates a new OpportunityHistory record capturing the new values, the previous Stage, the user who made the change, and the timestamp of the save.
Stage History is the canonical source for time-in-stage analytics: how long deals sit at Discovery, which stages get skipped, how often deals move backward from Proposal to Discovery, what amount adjustments happen during negotiation. Sales operations teams build dashboards on the OpportunityHistory object to answer questions standard Opportunity reports cannot, because the live Opportunity record only shows the current state, not the history of how the deal got there.
How Stage History captures every Opportunity transition
What gets captured in an OpportunityHistory record
An OpportunityHistory record captures a snapshot of the Opportunity at the moment a tracked field changed. The standard tracked fields are Stage, Amount, Probability, Expected Revenue, Close Date, and Forecast Category. Each history record stores the new values for all of these fields plus the Created Date (when the change happened), Created By Id (who made it), and Opportunity Id (the parent). The record is read-only after creation; the platform writes one history row per save that touches any tracked field, not one per field change.
When the OpportunityHistory records are written
Salesforce writes an OpportunityHistory record whenever an Opportunity's tracked fields change through any path: UI edit, Apex DML, REST API PATCH, Flow update, Data Loader import. The write happens automatically inside the platform's order of execution, after the database commit but before triggers fire on the parent. Records are written even when only one tracked field changes; a Stage change with no Amount change still produces a row. Records are not written for changes to untracked fields, which is why Field History Tracking is a separate feature for non-Stage audit.
The Opportunity History standard report type
Salesforce ships with an Opportunity History report type that exposes the OpportunityHistory object alongside the parent Opportunity. The report type shows one row per history record, with both the Opportunity fields (current state) and the history fields (state at time of change). This is the canonical way to build Stage History reports in the standard report builder; admins do not need to create a custom report type unless they want to add custom fields from related objects. The report type is hidden by default in the New Report picker; pin it to the Frequently Used list for sales operations team members who need it daily.
Time-in-stage and other time-based metrics
The most common reason to query Stage History is time-in-stage analysis. The pattern is to subtract the Created Date of one history record from the next: if an Opportunity moved from Discovery to Proposal on March 1 and from Proposal to Closed Won on March 20, time-in-stage at Proposal is 19 days. Sales operations teams build aggregate reports that average time-in-stage across all opportunities by stage, which surfaces bottlenecks (deals stuck at Proposal) and the inverse (deals racing through stages too quickly to validate). Time-in-stage trends quarter over quarter also reveal whether the sales process is getting faster or slower over time.
Stage History vs Field History Tracking
Stage History is automatic and applies only to Opportunity. Field History Tracking is an opt-in feature that captures changes on up to 20 fields per object, available on most standard and custom objects. The two coexist on Opportunity: OpportunityHistory captures Stage, Amount, Probability, Close Date, Forecast Category changes automatically; Opportunity Field History captures changes on any other field the admin enabled tracking for. For full audit, both features are needed because each covers fields the other does not. Reports built on Field History Tracking use a separate History object per parent object, not OpportunityHistory.
Limitations of OpportunityHistory
OpportunityHistory has three limits sales operations teams hit. The first is retention: history records are retained indefinitely on Opportunity, but the standard report type only surfaces records from the last few years cleanly; very old deals may need direct SOQL queries against OpportunityHistory to retrieve. The second is volume: orgs with millions of opportunities produce tens of millions of history rows; reports against the object can hit row limits without tight filtering. The third is the one-row-per-save rule: a single save that changes both Stage and Amount creates one row, not two, which means parsing the history sometimes requires inferring which field caused the row from the value differences.
Reporting patterns and dashboard recipes
Mature sales operations teams build a small set of recurring reports on OpportunityHistory. A Stage Velocity report aggregates average time-in-stage per stage across a quarter. A Backward Movement report flags Opportunities where the Stage moved to an earlier value than the prior history record (often a signal of overoptimistic forecasting). A Stage Skip report finds deals that bypass required stages (Discovery to Closed Won without Proposal). An Amount Drift report tracks how the Amount field changes through the deal lifecycle, surfacing patterns where deals consistently shrink during negotiation. Each report is a few minutes' build on the Opportunity History report type and pays for itself in coaching insights.
Build an Opportunity Stage History report
Stage History is captured automatically and surfaced through the Opportunity History report type. The steps below cover building a useful report and the most common reporting patterns sales operations teams need.
- Open a new report with the Opportunity History type
In Reports, click New Report. Search for and pick Opportunity History as the report type. The type exposes both the parent Opportunity fields and the OpportunityHistory row fields.
- Add the relevant columns
Add Opportunity Name, Account Name, Stage at Save, From Stage, To Stage, Created Date, Created By, Amount at Save. The combination gives a full picture of who changed what, when, and where the deal was before the change.
- Apply date and stage filters
Filter Created Date to the period you care about (Last 90 Days for recent transitions, This Fiscal Quarter for current-quarter analysis). Filter Stage to the stages you want to study, or leave open for a full picture.
- Add a grouping for analysis
Group by Stage to see counts per stage. Group by Created By to see per-rep transition patterns. Group by Month to see how transitions are trending over time.
- Save and pin for reuse
Save the report in a folder shared to the sales operations team. Pin the report to the Recent list for quick access. Schedule the report to deliver weekly if the team uses it for stand-up reviews.
The standard report type that exposes OpportunityHistory. Required for any Stage History reporting in the standard report builder.
An admin-built variant that adds related-object fields beyond what the standard type exposes. Useful for cross-object reports.
The most flexible option for very old or very large history queries. Bypasses the report builder limits but requires query knowledge.
- OpportunityHistory only writes on changes to Stage, Amount, Probability, Expected Revenue, Close Date, or Forecast Category. Changes to other fields are invisible to Stage History; configure Field History Tracking for those fields if audit is needed.
- A single save that changes multiple tracked fields produces one history row, not one per field. Parsing the history for specific field changes requires inferring the cause from value differences between consecutive rows.
- Very old Opportunities produce a long history; reports against OpportunityHistory without tight filters can hit row limits on large orgs. Always filter Created Date to a bounded period unless you need the full history for a specific deal.
Trust & references
Cross-checked against the following references.
- OpportunityHistory ObjectSalesforce Developers
- Opportunity History ReportsSalesforce Help
- Opportunities OverviewSalesforce Help
- Field History TrackingSalesforce Help
Straight from the source - Salesforce's reference material on Stage History.
- OpportunityHistorySalesforce Developers
- Opportunity History Report TypeSalesforce Help
Hands-on resources to go deeper on Stage History.
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 Stage History?
Q2. What does each entry show?
Q3. What can history analysis reveal?
Discussion
Loading discussion…