Telemetry JSON

Every backtest writes a small *_telemetry.json file next to the other output files (for example logs/MyStrategy_2026-11-11_14-00_AbC123_telemetry.json). It answers “why did this backtest take so long?” without a profiler. It is always written and costs well under a tenth of a second, even on a year of minute data.

It contains only counts, seconds and sizes. It never contains your keys, account details, symbols or server addresses.

What it shows

  • wall_seconds: the whole run.

  • phases: data_setup_seconds (until the first trading iteration), simulation_seconds, reports_seconds (tearsheet, trades and indicator files) and uploads_seconds (waiting for cache uploads at the end).

  • iterations: how many trading iterations ran, the time spent inside on_trading_iteration, and the slowest iteration with its simulated time.

  • providers: one row per data source and asset class, with requests, provider_seconds (time waiting for answers), rows, retries, and rate-limit or backoff waits (count and seconds).

  • caches: one row per cache layer, data source and asset class, with reads, hits, misses, bytes read, and uploads.

Example (a 12-month options backtest on a repeat run, shortened):

{
 "schema": "lumibot.backtest_telemetry/1",
 "wall_seconds": 38.0,
 "phases": {"data_setup_seconds": 0.6, "simulation_seconds": 33.9, "reports_seconds": 3.5, "uploads_seconds": 0.0},
 "iterations": {"count": 97140, "total_seconds": 22.1, "slowest_seconds": 2.4, "slowest_at": "2025-10-06T10:00:00-04:00"},
 "providers": [{"source": "alpaca", "asset_class": "option", "requests": 48, "provider_seconds": 5.6, "rows": 0}],
 "caches": [{"layer": "shared_bars", "source": "alpaca", "asset_class": "option", "reads": 2984, "hits": 2561, "misses": 423}]
}

Finding a slow backtest

  1. Compare the phases with wall_seconds to see which part is slow.

  2. If provider_seconds is most of simulation_seconds, the backtest is waiting on market data. A second run of the same backtest should make far fewer requests, because data is cached.

  3. If the provider and cache do not explain the time, profile your strategy with BACKTESTING_PROFILE=yappi. This writes a *_profile_yappi.csv file you can sort by total time.

Field names are stable: new fields may be added, existing ones are never renamed.