Prometheus metrics collector for FastAPI event loop lag and thread pool utilization
Project description
fastapi-runtime-details-collector
Prometheus metrics collector for FastAPI applications that exposes event loop health and thread pool utilization in real time.
Why
FastAPI runs on an asyncio event loop with a thread pool for synchronous route handlers. Neither is observable out of the box. This library adds two key signals:
- Event loop lag — how long the loop was blocked before it could process the next iteration. Sustained lag means CPU-bound or blocking work is starving your async handlers.
- Thread pool saturation — how many of anyio's sync-handler threads are currently active versus the total capacity.
Installation
pip install fastapi-runtime-details-collector
Requires Python 3.10+ and a FastAPI application already using prometheus_client to expose a /metrics endpoint.
Metrics
| Metric | Type | Description |
|---|---|---|
fastapi_eventloop_lag_seconds |
Gauge | Drift between a scheduled asyncio.sleep and its actual wake-up, in seconds |
fastapi_eventloop_tasks_total |
Gauge | Number of asyncio tasks currently pending in the event loop |
fastapi_threadpool_capacity_tokens |
Gauge | Total token capacity of anyio's default thread limiter (max concurrent sync handlers) |
fastapi_threadpool_active_threads |
Gauge | Number of sync handler threads currently executing (anyio borrowed tokens) |
fastapi_metrics_last_collection_timestamp_seconds |
Gauge | Unix timestamp of the last successful metrics collection |
Metrics are collected every second by a background task. No metrics are exposed until the first successful collection.
Setup
1. Expose a /metrics endpoint
If you don't already have one:
pip install prometheus-client
from prometheus_client import make_asgi_app
metrics_app = make_asgi_app()
app.mount("/metrics", metrics_app)
2. Register the collector in your lifespan
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi_runtime_details_collector import FastAPIRuntimeCollector, setup_lag_monitor
@asynccontextmanager
async def lifespan(app: FastAPI):
collector = FastAPIRuntimeCollector()
task = setup_lag_monitor(collector)
yield
task.cancel()
app = FastAPI(lifespan=lifespan)
setup_lag_monitor must be called from within a running anyio event loop, so the FastAPI lifespan startup is the right place.
Custom registry
If you use a custom Prometheus registry instead of the global default:
from prometheus_client import CollectorRegistry
from prometheus_client import make_asgi_app
from fastapi_runtime_details_collector import FastAPIRuntimeCollector, setup_lag_monitor
registry = CollectorRegistry()
@asynccontextmanager
async def lifespan(app: FastAPI):
collector = FastAPIRuntimeCollector(registry=registry)
task = setup_lag_monitor(collector)
yield
task.cancel()
metrics_app = make_asgi_app(registry=registry)
app.mount("/metrics", metrics_app)
Full example
from contextlib import asynccontextmanager
from fastapi import FastAPI
from prometheus_client import make_asgi_app
from fastapi_runtime_details_collector import FastAPIRuntimeCollector, setup_lag_monitor
@asynccontextmanager
async def lifespan(app: FastAPI):
collector = FastAPIRuntimeCollector()
task = setup_lag_monitor(collector)
yield
task.cancel()
app = FastAPI(lifespan=lifespan)
app.mount("/metrics", make_asgi_app())
@app.get("/")
async def root():
return {"status": "ok"}
Run with uvicorn main:app and scrape http://localhost:8000/metrics.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fastapi_runtime_details_collector-1.0.0.tar.gz.
File metadata
- Download URL: fastapi_runtime_details_collector-1.0.0.tar.gz
- Upload date:
- Size: 4.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c543affd1855973ac4772e46de052eddbd300b40f9e07e3bf62a275b9fad4079
|
|
| MD5 |
b87b8719c788fecd54f33907ae336b36
|
|
| BLAKE2b-256 |
3353a7b2a058c46f858a5a6ce7b93488faf20ab97d0d2f822f5224a60df2d00a
|
Provenance
The following attestation bundles were made for fastapi_runtime_details_collector-1.0.0.tar.gz:
Publisher:
publish-pypi.yml on SIB-rennes/fastapi_runtime_details_collector
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastapi_runtime_details_collector-1.0.0.tar.gz -
Subject digest:
c543affd1855973ac4772e46de052eddbd300b40f9e07e3bf62a275b9fad4079 - Sigstore transparency entry: 1693577644
- Sigstore integration time:
-
Permalink:
SIB-rennes/fastapi_runtime_details_collector@f0ee1be18721a5898a63970aff291b4bd1732453 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/SIB-rennes
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@f0ee1be18721a5898a63970aff291b4bd1732453 -
Trigger Event:
push
-
Statement type:
File details
Details for the file fastapi_runtime_details_collector-1.0.0-py3-none-any.whl.
File metadata
- Download URL: fastapi_runtime_details_collector-1.0.0-py3-none-any.whl
- Upload date:
- Size: 5.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27a788afa76d6237aff829af49b5476166c9629cf0f86e9e8de15410b08bc28a
|
|
| MD5 |
3505e18646f9d348638e700212697b23
|
|
| BLAKE2b-256 |
c01bbc85ec09a5b46ca67aa9f2105ce37c158831f0478ab768df477f6df57811
|
Provenance
The following attestation bundles were made for fastapi_runtime_details_collector-1.0.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on SIB-rennes/fastapi_runtime_details_collector
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastapi_runtime_details_collector-1.0.0-py3-none-any.whl -
Subject digest:
27a788afa76d6237aff829af49b5476166c9629cf0f86e9e8de15410b08bc28a - Sigstore transparency entry: 1693577882
- Sigstore integration time:
-
Permalink:
SIB-rennes/fastapi_runtime_details_collector@f0ee1be18721a5898a63970aff291b4bd1732453 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/SIB-rennes
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@f0ee1be18721a5898a63970aff291b4bd1732453 -
Trigger Event:
push
-
Statement type: