GET /stats

Public process-wide runtime statistics — engine, compile, prewarm, deltas, sessions, datafeed and HTTP counters.

This page

Abstract

GET /stats is a public (no API key) snapshot of what this worker has been doing since it started: request counts and latency, execution-engine runs, compile cache outcomes, prewarm results, live-session delta sizes, and datafeed traffic.

It is process-local. Counters reset when the worker restarts — which is honest for the single-worker gunicorn setup live sessions require, but means the numbers describe this process, since it booted, not a durable time series. Export them if you need dashboards.

Interface surface

http
GET /stats
json
{
  "status": "ok",
  "service": "pynescript-pro-api",
  "version": "1.0.0",
  "timestamp": 1791968289,
  "debug": { "env": "PYNE_DEBUG", "enabled": true, "scopes": [], "level": "DEBUG" },
  "counters":   { "run.total": { "total": 4 }, "run.by_mode": { "total": 2, "by": { "auto": 2 } } },
  "latencies":  { "run.total": { "count": 4, "total_ms": 9251.2, "avg_ms": 2312.8,
                                 "min_ms": 0.36, "max_ms": 9250.3,
                                 "p50_ms": 1.2, "p95_ms": 8974.6 } },
  "gauges":     { "sessions.active": 1, "sessions.capacity": 64, "http.in_flight": 0 },
  "compile_cache": { "source_entries": 2, "ir_entries": 1, "has_numba": true, … },
  "sessions":      { "sessions": 1, "max_sessions": 64, "ttl_seconds": 900.0 },
  "notes": "in-process counters; reset on worker restart"
}

Three metric kinds

KindShapeNotes
counters{total, by?}Monotonic. by is a dimension breakdown (mode, endpoint, status class, fallback reason).
latencies{count, total_ms, avg_ms, min_ms, max_ms, p50_ms, p95_ms}Percentiles come from a bounded reservoir of the last 512 samples per metric, so they describe recent behaviour, not the whole run.
gaugesnumberLast value — in-flight requests, active sessions, cache entries.

Metric names are dotted (run.total, delta.bars_appended, http.request) so the payload groups naturally.

What is tracked

NamespaceExamples
httprequests, by_endpoint, by_status_class, client_errors, server_errors, slow_requests; in_flight gauge
runtotal, bars, by_mode, mode_resolved, auto_backend, errors, error_kind, timed_out, compile_cached, compile_fallback_reasons
interpretbars, bar_loop latency, errors by kind, timeouts
compileattempts, eligibility, host_cache (hit/miss), errors, run / total latency
compile_scriptcache split by memory_raw / memory_sanitized / disk / ir_share / miss
prewarmcalls, builtin_warm, scripts_ok, scripts_failed, total latency
deltaappend_calls, bars_appended, update_last_bar_calls; bars_per_append_max gauge
session / sessionsengine created and parse; store created, dropped, evicted, active, capacity, active_max
datafeedstreams, exchanges_connected, reconnects, errors, session_binds, watch_connections, watch_bars, gateway ohlcv / markets counters and latency
providercreated, fetches, bars_fetched, fetch_errors

Relationship to other surfaces

GET /stats complements, and does not replace:

  • the per-run profile in the /run envelope (total_ms, parse_ms, eval_ms, per-line rows) — that is client-visible, per-run detail;
  • the compile block on GET /health — that is capability plus cache configuration;
  • GET /auth/usage — that is business metering for rate limits.

/health deliberately stays a cheap liveness probe. It does not absorb these counters.

Cardinality

Dimension values come from closed sets — route rules, interpret/compile/auto, 2xx–5xx, a small set of exchange ids. compile_fallback_reasons is truncated to 120 characters for the same reason. The registry is not a Prometheus-style label store; do not point a high-cardinality metric at it.

Failure modes

SymptomCauseFix
All counters resetWorker restarted / redeployedExpected — counters are in-process
Counters look low behind a load balancerMultiple workers, each counting its own sliceAggregate per worker, or run with GUNICORN_WORKERS=1
p95_ms disagrees with max_msPercentiles use a 512-sample reservoirTreat p95 as recent-window; max_ms is all-time
compile_cache or sessions shows errorEngine import failedThe rest of the payload still serves — /stats never fails the request

Internals (map)

PathRole
src/pynescript/stats.pyThread-safe counter / latency / gauge registry
src/pynescript/debug.pyPYNE_DEBUG toggle (reported under debug)
backend/logging_setup.pydebug_report()
backend/app.py/stats route, request hooks
backend/api/datafeed.py, backend/middleware/sessions.pyDatafeed + session counters

See also