Relevant source files
The following files were used as context for generating this wiki page:
- packages/next/src/server/lib/trace/request-insights.ts
- packages/next/src/next-devtools/dev-overlay/components/request-insights/request-insights-panel.tsx
- packages/next/src/cli/next-request-insights.ts
- packages/next/src/server/dev/hot-reloader-webpack.ts
- packages/next/src/next-devtools/dev-overlay/components/request-insights/request-insights-panel.css
- packages/next/src/next-devtools/dev-overlay/components/instant-navs/instant-navs-panel.tsx
- packages/next/src/server/mcp/tools/get-request-insights.ts
- packages/next/src/server/dev/hot-reloader-turbopack.ts
- packages/next/src/client/components/segment-cache/navigation-testing-lock.ts
- packages/next/src/server/dev/next-dev-server.ts
- packages/next/src/server/lib/patch-fetch.ts
- packages/next/src/next-devtools/dev-overlay/components/request-insights/request-list.ts
- packages/next/src/next-devtools/dev-overlay/components/request-insights/trace-viewer.ts
- packages/next/src/next-devtools/dev-overlay.browser.tsx
- packages/next/src/server/dev/log-requests.ts
- packages/next/src/server/lib/router-server.ts
- packages/next/src/next-devtools/dev-overlay/dev-overlay.tsx
- packages/next/src/server/lib/dev-bundler-service.ts
- packages/next/src/server/client-component-renderer-logger.ts
- packages/next/src/server/lib/trace/span-store.ts
- packages/next/src/server/lib/trace/local-span-recorder.ts
- packages/next/src/next-devtools/shared/request-insights.ts
- packages/next/src/client/dev/debug-channel.ts
- packages/next/src/server/lib/trace/request-insights-identity.ts
- packages/devlow-bench/src/browser.ts
- packages/next/src/next-devtools/userspace/pages/hydration-error-state.ts
- packages/next/src/shared/lib/request-insights.ts
Overview
Request Insights provides diagnostic telemetry for App Router requests and server fetches in development, capturing span trees, timing data, and cache behaviors without requiring an external OpenTelemetry collector. Activated via experimental.requestInsights in next.config.js, the subsystem records spans through local recorders and async context binding, aggregating them into an in-memory store that distributes real-time updates over HMR WebSockets to the developer overlay and exposes snapshot endpoints for CLI and Model Context Protocol (MCP) tool inspection.
Sources: packages/next/src/server/mcp/tools/get-request-insights.ts:9-19, packages/next/src/server/lib/trace/request-insights.ts:50-112, packages/next/src/server/lib/dev-bundler-service.ts:47-55
Data Model and Trace Types
Kinds, Identity, and Helpers
Request insights categorize telemetry using specific types defined in shared library modules. The RequestInsightKind union type supports two literal values: 'request' and 'instant-insights'. An insight's identity is represented by RequestInsightIdentity, which holds a requestId string and an optional kind property. Two utility functions govern identity resolution: getRequestInsightKind inspects an object picking its kind property and defaults to 'request' when undefined, while getRequestInsightKey formats a composite string combining the resolved kind and requestId separated by a colon.
Sources: packages/next/src/shared/lib/request-insights.ts:1-16
Note
getRequestInsightKind falls back to 'request' when an insight record omits the kind field.
Sources: packages/next/src/shared/lib/request-insights.ts:8-12
Attribute Values and Snapshot Structures
The devtools extension layer defines primitive and array value types for telemetry attributes, along with comprehensive data models for spans, fetches, requests, and snapshots. RequestInsightAttributeValue accepts strings, numbers, booleans, or homogeneous arrays containing optional null or undefined values.
| Type Name | Key Properties / Structure | Purpose |
|---|---|---|
RequestInsightSpan | name, startTime, durationMs?, status? ('ok' | 'error'), traceId?, spanId?, parentSpanId?, attributes?, links?, events?, error? | Represents a single traced operation span with hierarchical links, events, and attributes. |
RequestInsightFetch | url?, method?, statusCode?, startTime?, durationMs?, cacheStatus?, cacheReason?, index? | Captures network fetch telemetry, timing, and caching metadata. |
RequestInsight | requestId, kind?, htmlRequestId, route?, url?, startTime, durationMs?, status ('ok' | 'error' | 'pending'), spans, fetches | Aggregates all spans and fetches associated with a specific request lifecycle. |
RequestInsightsSnapshot | requests: RequestInsight[] | Top-level container holding an array of all collected request insights. |
Sources: packages/next/src/next-devtools/shared/request-insights.ts:10-68
Request Identity and Span Recording
Local Span Capture and Environment Control
Local span recording is governed by environment checks and test recorder hooks. The function isLocalSpanRecordingEnabled checks whether process.env.__NEXT_DEV_SERVER is active and ensures that either a test span recorder is defined or isRequestInsightsEnabled returns true. isRequestInsightsEnabled inspects process.env.__NEXT_REQUEST_INSIGHTS, accepting values '1', 'true', or the boolean true.
Sources: packages/next/src/server/lib/trace/span-store.ts:45-92
Warning
Local span recording and request insights are strictly disabled unless process.env.__NEXT_DEV_SERVER is explicitly set, preventing diagnostic overhead in production runtimes.
Sources: packages/next/src/server/lib/trace/span-store.ts:70-85
When recordSpan executes, it attaches a high-resolution timestamp via performance.timeOrigin + performance.now(), dispatches to any registered spanRecorderForTest, and forwards the record to recordRequestInsightSpan if request insights are enabled and a requestId is present.
Sources: packages/next/src/server/lib/trace/span-store.ts:45-62
Async Context Binding and Request Identity Resolution
Request identity propagation bridges early server initialization and App Router execution layers using global AsyncLocalStorage stores. Early request handling in BaseServer stores request metadata in an isolated context via runWithRequestInsightsIdentity, which can be retrieved through getRequestInsightsIdentity.
Sources: packages/next/src/server/lib/trace/request-insights-identity.ts:12-30
During span creation, getCurrentRequestIdentity aggregates context across multiple async storage providers to assemble the active request attributes.
Sources: packages/next/src/server/lib/trace/local-span-recorder.ts:551-576
Note
getCurrentRequestIdentity falls back gracefully, returning an empty object if async storage reads throw outside of an active request or render context.
Sources: packages/next/src/server/lib/trace/local-span-recorder.ts:573-575
| Context Source | Storage / Helper Module | Resolved Properties |
|---|---|---|
| Early Request Identity | request-insights-identity.ts (getRequestInsightsIdentity) | requestId, kind, htmlRequestId, url |
| Work Store | work-async-storage.external.ts (workAsyncStorage) | requestId, htmlRequestId, route |
| Work Unit Store | work-unit-async-storage.external.ts (workUnitAsyncStorage) | url (pathname and search query) |
Sources: packages/next/src/server/lib/trace/local-span-recorder.ts:555-572, packages/next/src/server/lib/trace/request-insights-identity.ts:19-30
Fetch Interception and Cache Telemetry
Server-Side Fetch Instrumentation and Metric Aggregation
Next.js intercepts native global fetch calls on the server to measure performance metrics, record cache behavior, and link individual network requests to active request insights. When a fetch executes within a tracked work store, trackFetchMetric computes duration and increments workStore.nextFetchId to assign a sequential index (idx) to each operation.
Sources: packages/next/src/server/lib/patch-fetch.ts:171-188
Tip
If request insights are enabled via isRequestInsightsEnabled(), trackFetchMetric resolves the active request identity from getRequestInsightsIdentity() or the work store and immediately dispatches telemetry using recordRequestInsightFetch.
Sources: packages/next/src/server/lib/patch-fetch.ts:189-215
In addition to dispatching telemetry to the in-memory insights store, trackFetchMetric populates workStore.fetchMetrics when workStore.shouldTrackFetchMetrics is true.
Sources: packages/next/src/server/lib/patch-fetch.ts:217-224
Cache Status Recording and Configuration Processing
Before executing origin fetches, Next.js evaluates work unit configuration via shouldProcessFetchConfigForWorkUnit. This determines whether dynamic access tracking or cache policies apply based on the active work unit store type.
| Work Unit Type | Process Fetch Config | Context / Behavior |
|---|---|---|
prerender, prerender-client, prerender-legacy | true | Static prerender stores use it for dynamic access tracking. |
cache, private-cache, unstable-cache | true | Cache scopes apply it to their own cache policy regardless of outer units. |
request | Conditional (true when development and __NEXT_CACHE_COMPONENTS and staged rendering are active) | Coordinates dynamic fetches with the dynamic render stage in development. |
prerender-runtime, validation-client, build-time-generator | false | Bypasses fetch configuration processing for these runtime units. |
Sources: packages/next/src/server/lib/patch-fetch.ts:52-80
Warning
Attempting to pass invalid revalidate options or tags to a fetch call triggers runtime warnings or errors during validation in validateRevalidate and validateTags, which check type boundaries and enforce maximum tag length and item constraints.
Sources: packages/next/src/server/lib/patch-fetch.ts:96-169
Insights In-Memory Store Synchronization
Store Architecture and Request Aggregation
The InMemoryRequestInsightsStore coordinates span ingestion, timing updates, and deduplication through internal maps and queues. It maintains a maximum capacity of 100 requests using a FIFO trim policy managed by MAX_REQUEST_INSIGHTS and requestOrder.
Sources: packages/next/src/server/lib/trace/request-insights.ts:15-58
When a span or fetch arrives via recordSpan or recordFetch, the store locates or initializes a RequestInsight record using getOrCreateRequest. Timing calculations differentiate between request-level root spans (BaseServer.handleRequest) and nested child spans to compute total duration and start time boundaries accurately.
Sources: packages/next/src/server/lib/trace/request-insights.ts:59-125
Tip
Deduplication of fetch records within recordFetchForInsight prevents duplicate entries by comparing URL and either index or start time properties on existing items.
Sources: packages/next/src/server/lib/trace/request-insights.ts:217-234
Subscription Management and Snapshot Distribution
The store provides subscription capabilities via the subscribe method, which registers listener callbacks of type RequestInsightsListener and returns an unsubscription function to remove them from the internal listeners set.
Sources: packages/next/src/server/lib/trace/request-insights.ts:126-146
The DevBundlerService utilizes this subscription mechanism during development when request insights are enabled. It listens for updates and broadcasts them to connected browser clients through the hot reloader using the HMR_MESSAGE_SENT_TO_BROWSER.REQUEST_INSIGHTS_UPDATE message type.
Sources: packages/next/src/server/lib/dev-bundler-service.ts:20-55
Warning
Failing to call close() on the DevBundlerService leaves the request insights subscription active, preventing cleanup of the listener reference and causing memory leaks during server teardown.
Sources: packages/next/src/server/lib/dev-bundler-service.ts:57-60
Trace Viewer and Waterfall Construction
Span and Fetch Normalization
The trace viewer processes raw span hierarchies and fetch records into unified waterfall items through getTraceItems. It first indexes fetch-related spans by their fetch index and extracts distinct fetch identifiers from request.fetches.
Sources: packages/next/src/next-devtools/dev-overlay/components/request-insights/trace-viewer.ts:74-91
Unnested trace items are constructed by evaluating each span via getSpanTraceItem and deduplicating network calls where a matching AppRender.fetch span already exists. Fetch items combine timing and status attributes with their corresponding span data using getFetchTraceItem.
Sources: packages/next/src/next-devtools/dev-overlay/components/request-insights/trace-viewer.ts:92-118
Note
getFetchTraceItem falls back to matching span start times and durations when fetch-specific timing properties are absent from the insight payload.
Sources: packages/next/src/next-devtools/dev-overlay/components/request-insights/trace-viewer.ts:170-195
Hierarchy Nesting and Positioning
The nestTraceItems function sorts unnested items and constructs a hierarchical forest using spanId and parentSpanId relationships. Circular references and duplicate identifiers are tracked via visited sets and parent lookup maps during recursive traversal.
Sources: packages/next/src/next-devtools/dev-overlay/components/request-insights/trace-viewer.ts:197-240
Waterfall layout positioning is calculated by getTracePosition, which derives percentage-based offsets and widths relative to the total request trace range.
| Function | Return Type | Purpose |
|---|---|---|
getTraceItems | TraceItem[] | Filters, normalizes, and nests spans and fetches for viewer rendering. |
getTraceRange | TraceRange | Computes the overall start time and minimum duration bounds for a request. |
getTracePosition | { left: number; width: number; offsetMs: number } | Calculates CSS left percentage, width percentage, and millisecond offset for waterfall bars. |
Sources: packages/next/src/next-devtools/dev-overlay/components/request-insights/trace-viewer.ts:74-148
Warning
getTraceRange enforces a minimum duration floor of 0.1 milliseconds to prevent division-by-zero layout calculations when rendering instantaneous requests.
Sources: packages/next/src/next-devtools/dev-overlay/components/request-insights/trace-viewer.ts:120-125
Developer Overlay Panel Presentation
Request List Filtering and Execution Walkthrough
The RequestInsightsPanel coordinates the rendering of captured request insights inside the development overlay UI. When constructing the sidebar and main inspection panes, it evaluates request list entries through a specific utility call chain to determine visibility and categorization.
The execution flows through a precise sequence of filter and type checks:
RequestInsightsPanelinvokesgetRequestListEntrieswith the current request array andshowInternalconfiguration flag.getRequestListEntriesiterates over requests, callingisInternalRequestInsightfor items when internal records are evaluated or filtered.isInternalRequestInsightdelegates togetRequestInsightKindto verify if the insight category differs from standard requests.getRequestInsightKindinspects the insight object'skindproperty, defaulting to'request'if undefined.
| Step | Function | File | Purpose |
|---|---|---|---|
| 1 | RequestInsightsPanel | packages/next/src/next-devtools/dev-overlay/components/request-insights/request-insights-panel.tsx | Main panel container component driving state and render layout. |
| 2 | getRequestListEntries | packages/next/src/next-devtools/dev-overlay/components/request-insights/request-list.ts | Filters and groups standard and internal request entries. |
| 3 | isInternalRequestInsight | packages/next/src/next-devtools/dev-overlay/components/request-insights/request-list.ts | Checks whether an insight kind is non-standard. |
| 4 | getRequestInsightKind | packages/next/src/shared/lib/request-insights.ts | Resolves the primary kind string from an insight identity. |
Sources: packages/next/src/next-devtools/dev-overlay/components/request-insights/request-insights-panel.tsx:31-40, packages/next/src/next-devtools/dev-overlay/components/request-insights/request-list.ts:25-84, packages/next/src/shared/lib/request-insights.ts:8-12
Note
When showInternal is enabled, getRequestListEntries groups internal records by their requestId and attaches them as nested children underneath matching parent page requests, while orphaned internal records remain top-level.
Sources: packages/next/src/next-devtools/dev-overlay/components/request-insights/request-list.ts:46-82
Overview and Cache Diagnostics
The panel extracts summary metrics through getRequestOverview, computing HTTP methods, status codes, RSC flags, error summaries, and cache distribution counters across all associated fetches. Cache counts aggregate items categorized as hit, miss, skip, or unknown.
Diagnostic insights are generated by getDiagnosis, which compares the duration of the slowest network fetch against nested critical trace items. If a fetch operation exceeds or matches the longest-running server trace span, it surfaces as the slowest recorded operation alongside its URL path, duration, and cache status reason.
Warning
getActiveRequestKey guarantees selection stability by falling back to the first request containing active fetch records if the currently selected key is missing or invalid.
Sources: packages/next/src/next-devtools/dev-overlay/components/request-insights/request-list.ts:7-23
CLI and MCP Insights Inspection
CLI Inspection Tool
External inspection of captured App Router request insights is supported via the next-request-insights CLI utility and the Model Context Protocol (MCP) server tool get_request_insights. These interfaces allow developers to query server span data and fetch timelines without relying on an external OpenTelemetry collector or browser dev overlay.
The nextRequestInsights entry point coordinates connection discovery and output formatting. It locates a running development server by reading the lockfile inside config.distDir or accepting an explicit --url option.
Sources: packages/next/src/cli/next-request-insights.ts:31-65
| Option / Parameter | Type | Default | Purpose |
|---|---|---|---|
options.url | string | undefined | Explicit development server HTTP/HTTPS URL override. |
options.json | boolean | false | Outputs the raw JSON snapshot directly to stdout. |
options.limit | number | 20 | Maximum number of recent requests displayed in table mode. |
directory | string | undefined | Project root directory path used for lockfile discovery. |
Sources: packages/next/src/cli/next-request-insights.ts:16-28
Warning
Dev server discovery enforces a strict timeout of 1000 milliseconds with 50 millisecond retry intervals against the project lockfile before exiting with an error code.
Sources: packages/next/src/cli/next-request-insights.ts:18-19, packages/next/src/cli/next-request-insights.ts:105-129
MCP Server Tool
The MCP server registers the get_request_insights tool to expose recent span snapshots to AI models and external debugging clients. It requires experimental.requestInsights to be enabled in configuration.
Sources: packages/next/src/server/mcp/tools/get-request-insights.ts:9-45
Note
If request insights are disabled, the MCP tool returns a JSON error instructing the developer to set experimental.requestInsights = true in next.config.js and restart the development server.
Sources: packages/next/src/server/mcp/tools/get-request-insights.ts:23-35
Related
On This Page
OverviewData Model and Trace TypesKinds, Identity, and HelpersAttribute Values and Snapshot StructuresRequest Identity and Span RecordingLocal Span Capture and Environment ControlAsync Context Binding and Request Identity ResolutionFetch Interception and Cache TelemetryServer-Side Fetch Instrumentation and Metric AggregationCache Status Recording and Configuration ProcessingInsights In-Memory Store SynchronizationStore Architecture and Request AggregationSubscription Management and Snapshot DistributionTrace Viewer and Waterfall ConstructionSpan and Fetch NormalizationHierarchy Nesting and PositioningDeveloper Overlay Panel PresentationRequest List Filtering and Execution WalkthroughOverview and Cache DiagnosticsCLI and MCP Insights InspectionCLI Inspection ToolMCP Server ToolRelated