Cookbook: Periodic Trace Snapshots

In this guide, you'll learn how to:

  • Run a continuous ring-buffer trace on an Android device or Linux machine.
  • Take periodic snapshots of the trace using --clone-by-name.
  • Analyze each snapshot with Trace Processor to monitor device metrics over time.

This workflow is useful when you need to repeatedly observe system metrics (CPU frequency, power rails, temperatures, etc.) while iterating on device or system configuration, without restarting tracing each time.

Use case

Imagine you are tuning device or system parameters (e.g. writing to /proc or /sys nodes) and want to see the effect on power, thermals and CPU behavior within seconds. The traditional workflow of “start trace, stop trace, pull, analyze” adds unnecessary friction.

With periodic trace snapshots you start a single ring-buffer trace once, then clone it as many times as you like. Each clone is an independent snapshot of the ring buffer at that point in time; the original trace keeps running undisturbed.

Prerequisites

Step 1: Start a ring-buffer trace

Step 2: Take a snapshot

Whenever you want to capture the current state of the ring buffer, clone the session by name:

Step 3: Pull and analyze a snapshot

You can analyze the snapshot using the trace_processor_shell command line, the Python API, or by opening it in the Perfetto UI.

Querying with trace_processor_shell

Run a one-off query directly from the command line using the query subcommand:

trace_processor_shell query /tmp/snapshot_1.pftrace "
  INCLUDE PERFETTO MODULE linux.cpu.frequency;
  SELECT * FROM cpu_frequency_counters LIMIT 100;
"

Or open an interactive SQL shell to explore the data:

trace_processor_shell /tmp/snapshot_1.pftrace

Here are some useful queries:

CPU frequency

INCLUDE PERFETTO MODULE linux.cpu.frequency;

SELECT *
FROM cpu_frequency_counters
LIMIT 100;

Power rails (Android, Pixel devices)

INCLUDE PERFETTO MODULE android.power_rails;

SELECT *
FROM android_power_rails_counters
LIMIT 100;

Battery counters (Android)

SELECT ts, t.name, value
FROM counter AS c
LEFT JOIN counter_track AS t ON c.track_id = t.id
WHERE t.name GLOB 'batt.*';

Thermal zones

SELECT ts, t.name, value
FROM counter AS c
LEFT JOIN counter_track AS t ON c.track_id = t.id
WHERE t.name GLOB '*thermal*';

Querying with the Python API

The perfetto Python package lets you load traces and query them programmatically, which is convenient for building custom dashboards or post-processing data with Pandas / Polars. Install it with:

pip install perfetto

Example:

from perfetto.trace_processor import TraceProcessor

tp = TraceProcessor(trace='/tmp/snapshot_1.pftrace')

# Query CPU frequency as a Pandas DataFrame.
qr = tp.query("""
  INCLUDE PERFETTO MODULE linux.cpu.frequency;
  SELECT cpu, ts, freq
  FROM cpu_frequency_counters
""")
df = qr.as_pandas_dataframe()
print(df.to_string())

# Plot frequency over time for each CPU.
import matplotlib.pyplot as plt
for cpu, group in df.groupby('cpu'):
  plt.plot(group['ts'], group['freq'], label=f'cpu {cpu}')
plt.legend()
plt.xlabel('Timestamp (ns)')
plt.ylabel('Frequency (kHz)')
plt.show()

See the Trace Processor Python docs for more details.

If you want to analyze multiple snapshots together, Batch Trace Processor lets you run a single query across a set of traces in one go.

Automating snapshots

A simple shell loop can take a snapshot every N seconds and run a query against it:

Stopping the trace

Limitations and caveats

  • Data source flush intervals: Not all data sources emit data continuously. For example, android.power polls at the configured battery_poll_ms interval, and some data sources only write data on trace start or stop. The snapshot will contain whatever has been written to the ring buffer up to that point.
  • Ring buffer overwrites: If the buffer is too small relative to the data rate, older data will be overwritten before you snapshot it. Increase size_kb if you find gaps.
  • Clone availability: The --clone-by-name flag requires Perfetto v49+. On Android this means Android 14 (U) or later. On Linux, ensure you are using a recent tracebox or Perfetto build.
  • Not real-time streaming: Each snapshot is a point-in-time copy of the buffer, not a live stream. There will always be some delay between the last event written and the moment you run the clone command.
  • Linux ftrace permissions: On Linux, ftrace-based data sources require access to tracefs. Rather than running as root, chown the directory to your user: sudo chown -R $USER /sys/kernel/tracing.
  • Intel CPU frequency: On most modern Intel CPUs, the power/cpu_frequency ftrace event is not emitted because frequency scaling is managed internally by the CPU. Use the linux.sys_stats polling data source with cpufreq_period_ms as a fallback.