A reporting snapshot runs a report on a schedule and writes its results into a custom object, so you can report on history that Salesforce does not otherwise keep. It is the only native way to answer “what did the pipeline look like in March” without field history on every relevant field. The setup order is fixed and unforgiving: target object first, source report second, snapshot definition third, and each run carries at most 2,000 rows.
The problem it solves
Most Salesforce data is current-state. An opportunity has one amount and one stage, the values it has right now. Ask what the amount was eight weeks ago and there is no answer, unless the field is history-tracked, and history tracking gives you change events rather than a periodic picture.
A snapshot solves it by brute force. Every night, run the report, copy each row into a custom object record, stamp it with the run date. Three months later you have ninety daily pictures and trend reporting becomes ordinary reporting on an ordinary object.
The setup order
Do these in sequence. Skipping ahead means going back.
- Build the target custom object. One field for every value you intend to capture, with types that match what the report produces. Add a date or date/time field for the run stamp if you want one you control, and give it a tab only if people will browse it.
- Build the source report. Tabular or summary format. The columns of this report are what you will map, so finalise it before mapping anything.
- Create the reporting snapshot in Setup. Name it, pick the running user, pick the source report and the target object.
- Map the fields. Source column on the left, target field on the right. Unmapped target fields stay blank. Unmapped source columns are discarded.
- Schedule it. Daily, weekly or monthly, in a time window.
The running user matters as much as it does on a dashboard. The snapshot is computed with that person’s record access, so a snapshot run as a sales rep captures the rep’s slice of the world. Run it as a user with the access the analysis needs, and remember that deactivating that user stops the snapshot.
The limits that bite
2,000 rows per run. This is the one that ends projects. A source report returning more than 2,000 rows is truncated, not rejected, so you get a partial snapshot and no obvious signal. The fix is to snapshot summary rows rather than detail rows: group the source report and capture the subtotals. A hundred groupings a day is sustainable for years. 50,000 detail rows a day is not.
Storage. Every snapshot row is a record consuming data storage. Daily snapshots of a few thousand rows add up faster than anyone budgets for. Decide the retention policy on day one and build the scheduled deletion at the same time as the snapshot, not two years later when storage alerts start.
The mapping is fragile. Change the source report’s columns and the mapping breaks. Sometimes it errors, sometimes it silently stops populating a field. Treat the source report as part of the snapshot’s configuration: rename it so nobody assumes it is a working report they can edit.
Target object behaviour. Validation rules, required fields and triggers on the target object apply to snapshot inserts. A validation rule that rejects a row causes that row to fail while the rest succeed, which produces a snapshot that is quietly incomplete. Keep the target object free of automation.
Format restrictions on the source. Joined reports cannot be a snapshot source, and other formats have their own restrictions. Build the source as a plain summary report and keep any fancier presentation in a separate report.
Reporting on the result
The target object is an ordinary custom object, so it needs a report type like anything else. Build a custom report type on it, and if you want to relate snapshot rows back to live records, include a lookup field in the target object and map the record Id into it.
Frequently asked
Can I backfill a snapshot? No. Snapshots capture the present at run time. There is no way to reconstruct last month, which is why the advice is always to set the snapshot up before you need the data.
Can I snapshot a report from a managed package? The source report must be one the running user can access, and package reports usually qualify. The report type restrictions still apply.
What runs first if several snapshots share a time slot? Scheduled work is queued and the exact order is not guaranteed. If one snapshot depends on another having finished, that dependency is not expressible here and the design needs rethinking.
