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) anduploads_seconds(waiting for cache uploads at the end).iterations: how many trading iterations ran, the time spent insideon_trading_iteration, and the slowest iteration with its simulated time.providers: one row per data source and asset class, withrequests,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, withreads,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¶
Compare the phases with
wall_secondsto see which part is slow.If
provider_secondsis most ofsimulation_seconds, the backtest is waiting on market data. A second run of the same backtest should make far fewer requests, because data is cached.If the provider and cache do not explain the time, profile your strategy with
BACKTESTING_PROFILE=yappi. This writes a*_profile_yappi.csvfile you can sort by total time.
Field names are stable: new fields may be added, existing ones are never renamed.