For the complete documentation index, see llms.txt. This page is also available as Markdown.

25 - Latency Monitor

Overview

OpenAlgo tracks order execution latency at multiple stages to help identify performance bottlenecks and ensure SLA compliance.

Latency records live in their own database, LATENCY_DATABASE_URL (default sqlite:///db/latency.db), separate from both openalgo.db and logs.db.

Architecture Diagram

┌──────────────────────────────────────────────────────────────────────────────┐
│                       Latency Monitoring Architecture                        │
└──────────────────────────────────────────────────────────────────────────────┘

                              Order Request


┌──────────────────────────────────────────────────────────────────────────────┐
│                           Latency Tracking Points                            │
│                                                                              │
│  T0: Request Received ───────────────────────────────────────────────────►   │
│           │                                                                  │
│           ▼                                                                  │
│  ┌─────────────────┐                                                         │
│  │  Validation     │  ← T1: validation_latency_ms                            │
│  │  (API key,      │                                                         │
│  │   schema)       │                                                         │
│  └────────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│  ┌─────────────────┐                                                         │
│  │  Broker API     │  ← T2: rtt_ms (Round-Trip Time)                         │
│  │  Request/       │                                                         │
│  │  Response       │                                                         │
│  └────────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│  ┌─────────────────┐                                                         │
│  │  Response       │  ← T3: response_latency_ms                              │
│  │  Processing     │                                                         │
│  └────────┬────────┘                                                         │
│           │                                                                  │
│           ▼                                                                  │
│  T4: Response Sent ─────────────────────────────────────────────────────►    │
│                                                                              │
│  total_latency_ms = T4 - T0                                                  │
│  overhead_ms = validation_ms + response_ms                                   │
└──────────────────────────────────────────────────────────────────────────────┘

Metrics Tracked

Latency Components

Metric
Description

rtt_ms

Broker API round-trip time

validation_latency_ms

Pre-request validation

response_latency_ms

Post-response processing

overhead_ms

Total OpenAlgo overhead

total_latency_ms

End-to-end time

The column names on OrderLatency are validation_latency_ms and response_latency_ms. The request_body and response_body columns exist but are always written as None: _log_latency_async() passes request_body=None, response_body=None to save space, so no payloads are stored.

Database Schema

Implementation

Latency Tracker Class

utils/latency_monitor.LatencyTracker records named stages rather than fixed marks:

get_rtt() returns the broker round trip, get_overhead() the sum of the non-broker stages, and get_total_time() the end-to-end elapsed time. The record itself is written off the request thread by _log_latency_async() on a single-worker ThreadPoolExecutor, so the SQLite commit never delays the order response.

Decorator Wiring

track_latency(api_type) is not applied by hand to route functions. init_latency_monitoring(app) walks the Flask-RESTX namespaces and wraps every resource method through wrap_resource_methods(), mapping each namespace name to an uppercase api_type.

An unmapped namespace falls back to its uppercased name.

Dashboard

Access

Routes

latency_bp is registered with url_prefix="/latency". All routes require a valid session.

Route
Behavior

GET /latency/

Older server-side dashboard template, still registered

GET /latency/api/logs

Recent records; limit defaults to 100 and is capped at 1,000

GET /latency/api/stats

Overall stats, per-broker stats, and per-broker RTT histograms

GET /latency/api/broker/<broker>/stats

One broker's stats plus its histogram

GET /latency/export

Export all records as latency_logs.csv

Histograms are computed with 30 numpy bins over the observed RTT range.

Dashboard View

SLA Targets

Performance Thresholds

get_latency_stats() reports two independent things: the share of orders under three hard-coded millisecond thresholds, and four percentiles of total_latency_ms. The thresholds are not configurable and there is no 175 ms bucket.

Field
Meaning

sla_100ms

Percent of orders under 100 ms end to end

sla_150ms

Percent of orders under 150 ms end to end

sla_200ms

Percent of orders under 200 ms end to end

p50_total, p90_total, p95_total, p99_total

Percentiles of total_latency_ms

SLA Calculation

The whole statistics block is computed in a handful of aggregate queries and cached for 60 seconds (_stats_cache, a TTLCache of size 1). Percentiles are computed only over the last PERCENTILE_WINDOW_DAYS (30) days so the fetch cannot grow without bound.

Broker Comparison

Per-Broker Stats

Retention

init_latency_monitoring(app) calls purge_old_data_logs(days=7) once at startup.

Order-execution records are kept forever. Everything else, meaning data and account queries, is deleted after seven days. The keep-forever set is PLACE, SMART, MODIFY, CANCEL, CLOSE, CANCEL_ALL, BASKET, SPLIT, OPTIONS, OPTIONS_MULTI, GTT_PLACE, GTT_MODIFY, and GTT_CANCEL. The same set is written out twice, in utils/latency_monitor.KEEP_FOREVER_TYPES and in database/latency_db.purge_old_data_logs, and the two must stay in step: a type listed in only the first is purged despite being an order.

Alerting

There is no latency alerting. Nothing in the codebase raises a notification on a slow order or a broker timeout. The monitor records, aggregates, and displays; acting on a threshold is left to the operator watching the dashboard.

HTTP Client Integration

Connection Timing

Analytics Queries

Common Queries

Key Files Reference

File
Purpose

utils/latency_monitor.py

Tracking utilities

database/latency_db.py

Latency model

blueprints/latency.py

Dashboard and export routes

utils/httpx_client.py

HTTP timing hooks

frontend/src/pages/monitoring/LatencyDashboard.tsx

React dashboard

Last updated