Database queries
IDebug records each ORM/driver round-trip as a dbQuery event on the same request session as req / functionCall / res. The query is a leaf of the call tree, not a second timeline.
What you see
| Surface | Story |
|---|---|
| Session header | db 3q / 18ms total queries and time |
| Request path | Teal DB chips between the issuing function’s enter and exit |
| Call tree | Controller → Service → prisma.User.findMany with SQL + duration |
| Timeline | DB badge, expandable payload (SQL, params, rowCount, error) |
How attribution works
- Request middleware enters ALS with an empty
callStack. logFunction/@Loggable/ the Nest performance interceptor push a frame.@idebug/dbadapters wrap the ORM; when a query runs they readgetParentCallName()and emitdbQuerywithparentName+executionOrder.- The UI walks enter → query → exit to rebuild the tree.
If you skip wrapping application functions, queries still appear on the request but at the root of the tree.
Setup
See @idebug/db for instrumentPrisma, TypeORM, Drizzle, Knex, Mongoose, and Sequelize.
Try it
The monorepo sample sample-db-api (samples/db-api, port 3003) wires Drizzle + Knex + traceQuery under logModule controllers.
pnpm build:packages
pnpm --filter sample-db-api startThen:
curl -s http://127.0.0.1:3003/users # Drizzle under listUsers → findUsers
curl -s http://127.0.0.1:3003/users/1 # Drizzle + Knex in one request
curl -s http://127.0.0.1:3003/stats # concurrent branches + raw sql
curl -s http://127.0.0.1:3003/demo/n-plus-one
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3003/demo/errorOpen http://localhost:3003/\_\_idebug, pick the session, and read Call tree first — each query sits under the function that issued it. Full route table: Samples.