Aviary
Reference

Configuration

The full TelescopeModule.forRoot() options reference — capture, storage, the gate, retention, alerts, AI, CPU profiling, the MCP server, and overload protection.

Every option below is passed to TelescopeModule.forRoot({ … }). All are optional — the defaults give you a zero-config SQLite store, request/exception capture, a production-deny gate, and overload protection. This page is the consolidated reference; each option links out to the concept or recipe that covers it in depth.

Capture & correlation

OptionDefaultDescription
enabledtrueMaster switch. Compute inline (e.g. NODE_ENV !== 'production').
watchers[]Built-in + custom watchers (queries, jobs, mail, cache, …). Request and exception capture wire automatically. See Capture.
extensions[]Installable extensions (TelescopeExtension[]) that bundle watchers, a navigable entry type, dashboard pages, and server-side data providers. Additive — extension watchers merge into watchers. See Extensions.
samplingnonePer-type keep-fractions for high-volume streams (e.g. { cache: 0.1 }).
redactsensible defaultsDeep-redaction of headers / query / body paths plus content bounds (maxDepth, maxStringLength, …). See Performance.
resolveUserreads request.userResolves the authenticated user recorded on a request entry.
exceptions{ captureHttp4xx: false }How thrown exceptions become entries. By default 4xx control flow is not recorded as an exception. See Exception capture.
exceptions.processCrashesoffOpt-in capture of unhandledRejection / uncaughtException as exception entries. Attaching these listeners changes whether your process dies, so read the exit contract before enabling. See Process-level crashes.
requestCapture128 KiB cap + binary content-types skippedGates a request body before record() sees it — maxBodyBytes, skipBodyContentTypes, skipBody(request). See Request body capture gate.
registerRequestMiddlewaretrueAuto-register request-capture middleware. Set false when using setGlobalPrefix(...) and register capture in bootstrap instead — also exclude Telescope's own routes with telescopeMountPaths() (app.setGlobalPrefix('api', { exclude: telescopeMountPaths() })), or the dashboard/API/assets get shifted under the prefix too. See Request context for your routes.

Storage & retention

OptionDefaultDescription
storageembedded SQLiteA StorageProvider. Swap for Redis / MikroORM / in-memory. See Storage.
prunenoneRetention window driving the scheduled pruner (e.g. { after: '24h' }); perType for per-type cutoffs.
archivenoneExport a type's entries to a sink before the pruner deletes them. See Archiving before prune.
prune.batchSize1000Rows per bounded DELETE. A lock-duration knob — see Bounded batched deletes.
prune.maxBatchesPerCycle50Hard ceiling on batches per scope per cycle, so a backlog cannot turn one tick into an hour-long loop.
prune.batchPauseMs50Pause between batches. Only paid when a second batch is needed, so a healthy store never waits.
prune.lockstorage leaseCross-process prune lock, so a fleet prunes once per cycle rather than once per pod. false to opt out, or your own TelescopePruneLock. See Pruning once per fleet.
prune.lockTtlMsmax(intervalMs * 3, 60s)Lease TTL — how long the fleet may go unpruned after a holder is killed mid-cycle.

The gate

OptionDefaultDescription
authorizerdeny in productionGates the read API. Denies in production by default until you supply one.
authorizeActiondenySeparate, default-deny gate for mutations — queue actions, Prune now, and request replay. Throwing denies (fails closed).
dashboardAuthnoneSigned-cookie login for the dashboard. See Dashboard auth.
guardsnoneBring-your-own CanActivate guard(s) fronting the console's API controllers — appended to (not replacing) the built-in gate above. Pass the SAME guards to TelescopeUiModule.forRoot to also gate the page. See Securing the console.
imports[]Extra Nest imports resolving a class passed to guards' own dependencies.
clientErrors{ enabled: false }Public frontend error ingestion. See Reporting frontend errors.

Health, alerts & AI

OptionDefaultDescription
pulsenoneHealth-snapshot tuning; slowRouteMs (default 1000) is the p99 a route must reach to count as a slow-request hotspot.
alertsnonePluggable-channel alerting (Slack / webhook / custom) + rules. See Alerts.
ainoneAI exception diagnosis. See AI diagnosis.
profiling{ enabled: false }On-demand V8 CPU flamegraphs — strictly opt-in. enabled, sampleRate, maxConcurrent, minDurationMs, samplingIntervalMicros. See below and CPU profiling.
traceContext / traceLinknoneOpenTelemetry trace stamping + deep-link template. See -otel.
explainQuerynoneHost hook that runs an engine EXPLAIN for a captured query. See Explain slow queries.

Queues & schedules

OptionDefaultDescription
queueManagers[]Live queue managers (BullMQ / SQS). A watchers entry that structurally implements the QueueManager SPI (driver, init, listQueues, counts, listJobs, getJob) is auto-registered — this array is only needed for standalone managers that aren't also watchers. See queue managers.
scheduleManagers[]Schedule managers (@nestjs/schedule). Same auto-registration: a watchers entry implementing the ScheduleManager SPI (listTasks) — e.g. ScheduleWatcher — is picked up automatically; listing it in both arrays is safe (deduped by identity, inited once). See the schedule watcher.

Agents & resilience

OptionDefaultDescription
mcpdisabledMCP server for coding agents. true (dev-only, refused in production), { token } (Bearer-gated everywhere), or omitted/false to disable. See MCP server.
overloadProtectiontrue (200ms)Pause capture under event-loop pressure. See below.

overloadProtection

overloadProtection?: boolean | { maxEventLoopLagMs?: number; startupGraceMs?: number };

Telescope samples the process event-loop delay (perf_hooks.monitorEventLoopDelay) on a 1s interval and, when the p99 lag crosses the threshold, pauses the Recorder (record() becomes a no-op) until the lag recovers — so a telescope under load can never amplify an incident.

  • true (the default) — protect with a 200ms p99 threshold.
  • false — disable.
  • { maxEventLoopLagMs } — tune the threshold (defaults to 200 when omitted).
  • { startupGraceMs } — grace window (default ~5000ms) after the guard arms during which it samples but never pauses or logs, so the synchronous bootstrap stall (DI wiring, migrations, codegen blocking the loop) can't trip the guard on a transient. Set 0 to arm immediately; ignored when protection is off.
TelescopeModule.forRoot({
  overloadProtection: { maxEventLoopLagMs: 100, startupGraceMs: 0 }, // pause sooner, arm at once
});

The sampling timer is unref'd (it never keeps the host's loop alive), and the guard degrades to a no-op when perf_hooks.monitorEventLoopDelay is unavailable. See Performance → Overload protection.

profiling

profiling?: {
  enabled?: boolean;                // default false — master switch
  sampleRate?: number;              // default 0 — fraction (0–1) auto-captured
  maxConcurrent?: number;           // default 1 — max simultaneous captures
  minDurationMs?: number;           // default 0 — discard captures shorter than this
  samplingIntervalMicros?: number;  // default 1000 — V8 sampling interval
};

On-demand V8 CPU flamegraph profiling. Strictly opt-in and OFF by default — while disabled no profiler is constructed, node:inspector is never loaded, and the request path is untouched beyond one boolean check. Enable it for manual "profile the next N requests" captures (via the POST /api/profiles/arm endpoint / the dashboard's Profiles tab), and/or set sampleRate to auto-capture a uniform fraction of traffic.

TelescopeModule.forRoot({
  profiling: { enabled: true, sampleRate: 0.01, minDurationMs: 50 },
});

Captures are aggregated into a bounded cpu_profile entry (a flame tree, not the raw .cpuprofile) that inherits the profiled request's batch/trace context. Arming is a mutation — behind the default-deny authorizeAction gate. See CPU profiling.

On this page