Profiler UI
A visual tour of the profiler web interface - the profiles list, the built-in tabs, and every collector panel.
Open /_profiler to browse the list of captured profiles, then click any row to open its detail view. The detail view is organized into built-in tabs (request, response, performance, logs, exceptions) plus one tab per active collector. The screenshots below come from the example application with every collector enabled.
This page is a visual tour of the panels and tabs. For the reference side — the UI endpoints, the debug response headers, the filter query parameters and how to export a profile — see Browsing profiles.
Profiles list
/_profiler opens on a sticky sidebar of views. Each entrypoint kind (HTTP, GraphQL, Commands, RabbitMQ) gets its own page under a Profiling group, and every global-scope collector (Config, Routes, Schemas) is a view of its own — each badged with its count. Only the active view is rendered; it is picked server-side from a ?view= link, so there is no client-side routing.
Every list carries its own filter bar and is filtered independently: the universal filters (search, duration, performance tag — slow / N+1 / chatty / large payload / no rows — plus an Exception select and an Errors checkbox), the HTTP-status filters (status, status class) shown only on the kinds that carry an HTTP response (HTTP, GraphQL), and filters specific to that kind (e.g. HTTP method, RabbitMQ delivery/exchange/handler). A kind hides a universal filter that is redundant for it — the Commands list has no Errors checkbox, its Status filter already asking the same question.

GraphQL operations
Requires @eleven-labs/nest-profiler-graphql - see the GraphQL support section in Getting started.
GraphQL operations get their own GraphQL view in the sidebar (separate from REST requests), each row showing the operation type (QUERY, MUTATION, or SUBSCRIPTION) and the operation or field name. Its filter bar adds an Operation filter to narrow the list by operation type.

Opening an operation lands on its dedicated GraphQL detail tab, displaying:
- Operation type badge (Query / Mutation / Subscription)
- Operation name if present in the request
- Field name - the entry-point resolver
- Query - syntax-highlighted GraphQL document
- Variables - the variables object, syntax-highlighted as JSON
- Response - the
{ data, errors }envelope returned to the client - Request headers - the underlying HTTP headers


GraphQL-level errors (schema validation failures, resolver errors returned in response.body.errors) appear in the Exceptions tab with an amber GraphQLError badge, visually distinct from NestJS runtime exceptions which use a red badge. Since GraphQL names every error GraphQLError, its extensions.code is shown alongside — BAD_REQUEST here — and that code is what the Exception filter lists and what decides whether the operation counts as an error.

Built-in tabs
The Request tab details the method, URL, headers, and collected body.

The Response tab shows the status, response headers, and body returned by the handler.

The Performance tab groups request duration, memory, and timestamps.

The Logs tab lists entries captured through createProfilerLogger(). Each row shows the message first - with structured payloads rendered as a JSON block under it - then the logger context name. See the Log capture page for the supported logger conventions.

The Exceptions tab lists what the profile captured, each with its message and stack trace — here the InternalServerErrorException behind a 500. A captured exception is not automatically an error, though: a BadRequestException answering 400 means the application did its job, so it appears here and under the Exception filter, but not under the Errors checkbox. See What counts as an error.

Collectors
The Timeline collector displays spans created with startSpan() as synchronized bars.

The Database collector shows SQL queries (TypeORM or MikroORM) with their SQL type and duration, plus a metadata line per query — rows affected/returned and the connection, rendered as a chip (localhost:5432 / shop). The panel header sums the rows read.

A zero-row UPDATE/DELETE is a silent failure — the query ran but changed nothing (a mismatched WHERE). It is highlighted, its 0 rows count turns amber, and the zero-rows tag lights the Performance banner and colours the Database tab:

The MongoDB collector (requires @eleven-labs/nest-profiler-mongoose) shows Mongoose queries and aggregations with their operation, collection, duration, result/affected count, and connection.

The HTTP Client collector shows outgoing requests triggered by HttpService.

The Cache collector shows GET_HIT, GET_MISS, SET operations and the hit rate.

The Command collector (requires @eleven-labs/nest-profiler-commander) profiles nest-commander CLI runs. With file storage, commands get their own Commands view — a CLI badge and the command line in place of the URL, with a Status filter for successful vs failed runs — and the Command tab details the command name, arguments, options, and exit code.

The RabbitMQ collector (requires @eleven-labs/nest-profiler-rabbitmq) profiles messages consumed via @RabbitSubscribe. Each delivery becomes its own profile: a dedicated RabbitMQ view, and a Message detail tab showing the exchange, routing key, handler, delivery metadata and JSON payload.


The Security collector shows the authenticated user, roles, and decoded JWT claims.

The Validator collector shows validated DTOs and failing class-validator constraints.

The Config collector is global — it describes the application, not one request — so it is a sidebar view of its own, exposing the runtime and the flattened configuration with secrets masked.

Example application
Full-featured NestJS application demonstrating every profiler collector, organized into one module per collector package.
Tutorials
Step-by-step NestJS profiler tutorials - enable collectors for SQL, HTTP, GraphQL, cache and auth, and build your own custom collector and entrypoint types.