Diagnostics Persistence automatically captures and stores Inspect data across device reboots. This can be used to preserve anything that can be written to Inspect.
Overview
Automatic collection in development: On
enganduserdebugbuilds, all Inspect data across the system is automatically persisted across reboots. No configuration required.Production (
user) builds require privacy configuration: On production devices, persisted Inspect data must be explicitly allowlisted in a product'sprevious_bootpipeline (for example, in go/previous-boot-pipeline) and undergo privacy review.Available in Feedback & Crash Reports: Persisted Inspect data is automatically ingested by Feedback and included in snapshot archives (as
inspect.previous_boot.json) when generating feedback or crash reports.
Field collection on user builds
On production (user) builds, diagnostic data exfiltration is restricted for
user privacy. To persist specific Inspect properties or trees on production
devices, you must add your selectors to the product's previous_boot pipeline
and complete a privacy review.
The privacy requirements for Persistence are functionally identical to go/tq-feedback-privacy.
1. Identify Inspect selectors
Determine the exact Inspect selectors for the properties or nodes you need.
You can inspect your component on a running device or emulator using
ffx inspect.
2. Add selectors to the previous_boot pipeline
Create or update the selector configuration for your component in the product repository's pipeline directory:
Create a component directory under the product's
previous_bootpipeline://vendor/*/privacy/pipelines/previous_boot/<component_name>/inspect/Add a
.cfgfile (e.g.<component_name>.cfg) containing the exact selectors to persist:core/my_component:root/my_node:error_count core/my_component:root/my_node:last_failure_reasonUpdate the corresponding
BUILD.bazelor pipeline list to include your new configuration.
3. Submit for privacy review
Refer to go/tq-feedback-privacy.
Accessing persisted data
Feedback reports and snapshots
When a feedback report or crash snapshot is taken after a reboot, Feedback automatically retrieves the previous boot's Inspect data from Persistence. The resulting snapshot contains:
inspect.previous_boot.json: The complete or filtered Inspect JSON tree from the prior boot.
Technical architecture and behavior
Under the hood, Diagnostics Persistence operates as a scheduled and event-driven pipeline snapshotting service:
┌───────────────────────────┐
│ Archivist │
│ ArchiveAccessor │
│ .previous_boot pipeline │
└─────────────┬─────────────┘
│ Snapshot query
▼
┌───────────────────────────┐ writes active snapshot
│ Diagnostics Persistence ├───► /cache/active/active.json
│ │ /cache/active/metadata.json
│ • Periodic (every 300s) │
│ • Low battery trigger │ on reboot: rotate
│ • Wait for update check ├───► /cache/previous_boot/active.json
└─────────────┬─────────────┘ /cache/previous_boot/metadata.json
│ Serves via FIDL
▼
┌───────────────────────────┐
│ PreviousBootDataProvider │
│ (e.g. Feedback component) │
└───────────────────────────┘
1. Archivist previous_boot pipeline
Persistence connects to fuchsia.diagnostics.ArchiveAccessor.previous_boot.
Archivist dynamically applies the allowlist selectors configured for the
pipeline, or bypasses filtering when DISABLE_FILTERING.txt is present (such
as in eng and userdebug builds).
2. Snapshot triggers
Persistence records active system snapshots using two triggers:
Periodic Interval: Runs every $N$ seconds (configured by
fuchsia.diagnostics.persist.PersistencePeriodSeconds, default 300 seconds).Low-Battery Trigger: Connects to
fuchsia.power.battery.BatteryManagerto monitor battery status. If battery drops to or belowfuchsia.diagnostics.persist.LowBatteryThresholdPercent(default 10%), an immediate snapshot is captured to preserve state prior to impending shutdown.
3. Active-to-previous boot rotation
Active snapshots and metadata are saved to
/cache/active/active.jsonand/cache/active/metadata.json.On startup, Persistence atomically cleans
/cache/previous_bootand moves/cache/activeto/cache/previous_boot.Persisted data is retained strictly for the single previous boot cycle.
4. Software update check gating
To protect against persistent crash loops across updates, Persistence
registers with fuchsia.update.Listener and withholds serving previous boot
data until the first post-boot software update check completes. On eng and
userdebug builds, this check can be skipped (skip_update_check: true).
Assembly configuration
Persistence parameters can be customized in product assembly configuration
under the diagnostics.persistence section:
persistence_period_seconds(integer, default:300): Duration in seconds between periodic snapshots onArchiveAccessor.previous_boot.low_battery_threshold_percent(integer, default:10): Battery percentage threshold that triggers an immediate active snapshot.skip_update_check(boolean, default:falseon user,trueon userdebug/eng): Iftrue, does not wait for the post-boot update check before publishing previous boot data. Alwaysfalseon user builds.
FAQ
Does Persistence work with Lazy Nodes?
Yes. Because Persistence requests a snapshot from Archivist via
ArchiveAccessor, Archivist actively evaluates all Lazy Nodes that match the
pipeline's active selectors at the time of each snapshot.
Where did .persist configuration files go?
Legacy .persist files and per-tag fetch scheduling have been replaced by the
Archivist previous_boot pipeline. Components no longer publish separate
.persist files or re-export persisted data in the live Inspect hierarchy
under core/diagnostics/persistence:root/persist. All previous boot Inspect
is unified into a single snapshot file served directly to Feedback.