> For the complete documentation index, see [llms.txt](https://statalpha.gitbook.io/statalpha-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://statalpha.gitbook.io/statalpha-docs/usage-analytics.md).

# Usage analytics

STAT-51 records one allowlisted event for every `/stats` or `/signals` API request. The API publishes to the environment-namespaced Redis Stream `<APP_ENV>:usage-events` with a 50 ms default upper bound. Publishing is fail-open. The `usage-analytics-worker` validates the shared versioned contract, writes valid batches to QuestDB table `api_usage_events`, and acknowledges Redis entries only after the write succeeds. Invalid events go to `<APP_ENV>:usage-events-dlq`; transient Redis and QuestDB errors are retried.

`timeframe` stores the requested candle/bar resolution (for example `15m` or `1D`). `time_window` stores a predefined historical lookback such as `6M`, `12M`, or `24M`. Explicit `start_date` and `end_date` values are stored separately. API query parameters `start_time`/`end_time` (and the aliases `session_start`/`session_end`) are recorded as `session_start` and `session_end`. Null session values mean the endpoint used its normal session-aware defaults.

## Configuration and health

The worker uses the existing `APP_ENV`, `REDIS_URL`, and QuestDB PGWire settings. Optional settings are `USAGE_ANALYTICS_ENABLED`, `USAGE_ANALYTICS_PUBLISH_TIMEOUT_SECONDS`, `USAGE_ANALYTICS_STREAM`, `USAGE_ANALYTICS_DLQ_STREAM`, `USAGE_ANALYTICS_BATCH_SIZE`, `USAGE_ANALYTICS_BLOCK_MS`, `USAGE_ANALYTICS_CLAIM_IDLE_MS`, and `USAGE_ANALYTICS_TABLE`.

Worker readiness is indicated by the structured `usage_analytics_worker_ready` log. Continued `usage_analytics_questdb_retry` or `usage_analytics_redis_retry` events indicate degraded processing. Inspect pending work with `XPENDING <APP_ENV>:usage-events usage-analytics-workers` and DLQ length with `XLEN <APP_ENV>:usage-events-dlq`.

No headers, bodies, raw URLs, unrestricted query strings, tokens, cookies, or API-key values enter the event contract. API-key requests store only the internal user-derived identifier.

## Initial QuestDB queries

All queries explicitly default to production data.

```sql
-- Requests per day
SELECT date_trunc('day', timestamp) day, count() requests
FROM api_usage_events WHERE environment = 'prod'
SAMPLE BY 1d;

-- Top statistics, assets, and timeframes
SELECT stat_type, count() requests FROM api_usage_events
WHERE environment = 'prod' AND timestamp > dateadd('d', -30, now())
ORDER BY requests DESC LIMIT 20;
SELECT asset_symbol, count() requests FROM api_usage_events
WHERE environment = 'prod' AND timestamp > dateadd('d', -30, now())
ORDER BY requests DESC LIMIT 20;
SELECT timeframe, count() requests FROM api_usage_events
WHERE environment = 'prod' AND timestamp > dateadd('d', -30, now())
ORDER BY requests DESC LIMIT 20;
SELECT time_window, count() requests FROM api_usage_events
WHERE environment = 'prod' AND timestamp > dateadd('d', -30, now())
ORDER BY requests DESC LIMIT 20;
SELECT session_start, session_end, count() requests FROM api_usage_events
WHERE environment = 'prod' AND timestamp > dateadd('d', -30, now())
GROUP BY session_start, session_end ORDER BY requests DESC;

-- Source, error rate, latency, and cache-hit rate
SELECT source, count() requests FROM api_usage_events
WHERE environment = 'prod' GROUP BY source ORDER BY requests DESC;
SELECT route, stat_type, 100.0 * sum(status_code >= 400) / count() error_rate_pct
FROM api_usage_events WHERE environment = 'prod' GROUP BY route, stat_type;
SELECT route, stat_type, avg(latency_ms) avg_ms, approx_percentile(latency_ms, 0.95) p95_ms
FROM api_usage_events WHERE environment = 'prod' GROUP BY route, stat_type;
SELECT stat_type, 100.0 * sum(cache_hit) / count(cache_hit) cache_hit_pct
FROM api_usage_events WHERE environment = 'prod' GROUP BY stat_type;
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://statalpha.gitbook.io/statalpha-docs/usage-analytics.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
