A production-shaped FastAPI service (Task CRUD, Clerk auth) built as a benchmark rig for the three pillars of observability — metrics, logs, traces — plus repeatable load testing. Business logic is intentionally trivial; the point is the architecture around it.
Full requirements: api/prd.md.
Grafana — request rate, latency, DB pool, task ops, process CPU/memory:
Grafana — k6 load test results, live during a run:
k6 — health scenario, 20 VUs, p(95)=17ms, p(99)=27ms, 0% failures:
Jaeger — distributed traces for every request, correlated with logs via trace_id:
FastAPI · SQLAlchemy (async) · PostgreSQL · Alembic · Clerk auth · Prometheus · Grafana · structlog → Elasticsearch/Kibana (via Filebeat) · OpenTelemetry → Jaeger · k6 → InfluxDB · Docker Compose
Router → Service → Repository → Database
Every request gets a request_id (X-Request-ID) and an OpenTelemetry
trace_id/span_id (traceparent), bound into structured JSON logs and
Prometheus labels, so one request can be followed across logs, metrics, and
traces.
cp .env.example .env # fill in CLERK_SECRET_KEY / CLERK_JWT_KEY
docker compose up -d
curl localhost:8000/health/ready
| Service | URL |
|---|---|
| API / docs | http://localhost:8000/docs |
| Grafana | http://localhost:3000 (admin/admin) |
| Prometheus | http://localhost:9090 |
| Kibana | http://localhost:5601 |
| Jaeger UI | http://localhost:16686 |
Full guides: docs/setup.md ·
docs/observability.md ·
docs/load-testing.md
| Method | Endpoint | Auth |
|---|---|---|
| POST | /api/v1/tasks |
required |
| GET | /api/v1/tasks |
required |
| GET | /api/v1/tasks/{id} |
required |
| PATCH | /api/v1/tasks/{id} |
required |
| DELETE | /api/v1/tasks/{id} |
required |
| GET | /health/live, /health/ready |
none |
| GET | /metrics |
none |
Tasks are scoped to the authenticated Clerk user (user_id) — one user
cannot read, update, or delete another's tasks.
.venv/bin/pytest tests/unit tests/integration
Integration tests spin up an ephemeral Postgres via testcontainers — no
running compose stack required.
12 k6 scenarios (health, auth, CRUD, bulk, rollback, mixed, spike, soak)
under tests/load/, results visualized live in Grafana. See
docs/load-testing.md.



