Observability
Distributed traces, N+1 detection, slow query alerts, and automatic index suggestions — all built in, zero configuration.
Overview
Every request flowing through Flux is automatically instrumented. You don't add libraries or configure exporters. Just deploy and observe.
Distributed traces
Every request gets a unique x-request-id that is propagated across the gateway, runtime, and data-engine. All spans for a request are correlated under this ID.
View a trace in your terminal:
$ flux trace <trace-id>
Trace 4f9a3b2c 2026-03-10 14:22:01 UTC
▸ function:create_todo 312 ms
▸ db:query(todos) 28 ms [MISS]
table: todos
op: insert
▸ db:query(todos) 15 ms [HIT] ← cache
─── Slow Queries ────────────────────────────────
todos.user_id 284 ms
─── Index Suggestions ───────────────────────────
→ todos.user_id run: CREATE INDEX ON todos(user_id);
Trace IDs appear in:
x-request-idresponse header on every API callflux logsoutput- The Flux dashboard under Logs → Traces
Span types
| Span kind | What it tracks |
|---|---|
function | Total function execution time |
db:query | Individual database queries — table, operation, duration, cache status |
gateway | Auth, routing, rate-limit checks |
N+1 query detection
Flux automatically detects N+1 query patterns — when the same table is queried inside a loop, turning one request into dozens of database round-trips.
Example warning in a trace response:
{
"n1_warnings": [
{
"table": "users",
"count": 47,
"message": "N+1 detected: 'users' queried 47 times in one request"
}
]
}
Fix example — batch with a single IN filter instead:
// ✗ N+1 — one query per item
for (const item of items) {
const [user] = await ctx.db.query({
table: "users", operation: "select",
filters: [{ column: "id", op: "eq", value: item.user_id }],
});
}
// ✔ Batched — one query for all items
const users = await ctx.db.query({
table: "users", operation: "select",
filters: [{ column: "id", op: "in", value: items.map(i => i.user_id) }],
});
Slow query detection
Any database query that takes longer than 100 ms is flagged as slow. The trace shows which table and operation was slow, helping you prioritize optimization.
Automatic index suggestions
When slow queries repeatedly filter on the same column, Flux generates a CREATE INDEX suggestion:
{
"suggested_indexes": [
{
"table": "todos",
"column": "user_id",
"ddl": "CREATE INDEX ON todos(user_id);"
}
]
}
Apply it:
-- Run against your project's database
CREATE INDEX ON todos(user_id);
(table, column) pair appears
2 or more times in slow filter positions, a CREATE INDEX DDL statement is generated and returned
alongside the trace response.
Logs
All ctx.log() calls emit structured JSON logs correlated with the trace ID.
$ flux logs --tail
$ flux logs --function create_todo --since 1h --limit 100
Dashboard
All observability data is also visible in the Flux dashboard at /dashboard under Logs and Traces.