Vercel Observability expert guidance — Drains (logs, traces, speed insights, web analytics), Web Analytics, Speed Insights, runtime logs, custom events, OpenTelemetry integration, and monitoring dashboards. Use when instrumenting, debugging, or optimizing application performance and user experience on Vercel.
Vercel Observability expert guidance — Drains (logs, traces, speed insights, web analytics), Web Analytics, Speed Insights, runtime logs, custom events, OpenTelemetry integration, and monitoring dashboards. Use when instrumenting, debugging, or optimizing application performance and user experience on Vercel.
metadata
{"priority":6,"docs":["https://vercel.com/docs/observability","https://vercel.com/docs/observability/otel-overview"],"sitemap":"https://vercel.com/sitemap/docs.xml","pathPatterns":["instrumentation.ts","instrumentation.js","src/instrumentation.ts","src/instrumentation.js","app/layout.*","src/app/layout.*","pages/_app.*","src/pages/_app.*","apps/*/instrumentation.ts","apps/*/instrumentation.js","apps/*/app/layout.*","apps/*/src/app/layout.*","apps/*/pages/_app.*","apps/*/src/pages/_app.*","sentry.client.config.*","sentry.server.config.*","sentry.edge.config.*"],"bashPatterns":["\\bvercel\\s+logs?\\b","\\bvercel\\s+logs?\\s+.*--follow\\b","\\bvercel\\s+logs?\\s+.*--level\\b","\\bvercel\\s+logs?\\s+.*--since\\b","\\bcurl\\s+.*deployments.*events\\b","\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/analytics\\b","\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/analytics\\b","\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/analytics\\b","\\byarn\\s+add\\s+[^\\n]*@vercel/analytics\\b","\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/speed-insights\\b","\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/speed-insights\\b","\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/speed-insights\\b","\\byarn\\s+add\\s+[^\\n]*@vercel/speed-insights\\b","\\bnpm\\s+(install|i|add)\\s+[^\\n]*@sentry/nextjs\\b","\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@sentry/nextjs\\b","\\bbun\\s+(install|i|add)\\s+[^\\n]*@sentry/nextjs\\b","\\byarn\\s+add\\s+[^\\n]*@sentry/nextjs\\b","\\bnpm\\s+(install|i|add)\\s+[^\\n]*@sentry/node\\b","\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@sentry/node\\b","\\bbun\\s+(install|i|add)\\s+[^\\n]*@sentry/node\\b","\\byarn\\s+add\\s+[^\\n]*@sentry/node\\b","\\bnpm\\s+(install|i|add)\\s+[^\\n]*@datadog/browser-rum\\b","\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@datadog/browser-rum\\b","\\bbun\\s+(install|i|add)\\s+[^\\n]*@datadog/browser-rum\\b","\\byarn\\s+add\\s+[^\\n]*@datadog/browser-rum\\b","\\bnpm\\s+(install|i|add)\\s+[^\\n]*\\bcheckly\\b","\\bpnpm\\s+(install|i|add)\\s+[^\\n]*\\bcheckly\\b","\\bbun\\s+(install|i|add)\\s+[^\\n]*\\bcheckly\\b","\\byarn\\s+add\\s+[^\\n]*\\bcheckly\\b","\\bnpm\\s+(install|i|add)\\s+[^\\n]*\\bnewrelic\\b","\\bpnpm\\s+(install|i|add)\\s+[^\\n]*\\bnewrelic\\b","\\bbun\\s+(install|i|add)\\s+[^\\n]*\\bnewrelic\\b","[Truncated]"],"promptSignals":{"phrases":["add logging","add logs","set up logging","setup logging","configure logging","structured logging","log drain","log drains","vercel analytics","speed insights","web analytics","opentelemetry","otel","instrumentation","monitoring","set up monitoring","add observability","track errors","error tracking","sentry","datadog","check the logs","show me the error","what went wrong","where did it fail","show me the logs","find the error","why did it fail","debug the error"],"allOf":["[Truncated]","[Truncated]","[Truncated]","[Truncated]","[Truncated]","[Truncated]","[Truncated]","[Truncated]"],"anyOf":["logging","monitoring","analytics","observability","telemetry","traces","metrics","debug","debugging","stuck","hanging","hung","waiting","stalled","spinning","timeout","slow","pending","unresponsive"],"minScore":6}}
validate
[{"pattern":"export (async )?function (GET|POST|PUT|PATCH|DELETE)","message":"API route handlers should include error logging — wrap in try/catch with console.error for production debugging","severity":"warn","skipIfFileContains":"console\\.error|logger\\.|captureException|Sentry"}]
retrieval
{"aliases":["monitoring","logging","analytics","performance tracking"],"intents":["add monitoring","set up logging","track performance","configure analytics"],"entities":["Web Analytics","Speed Insights","OpenTelemetry","Drains","runtime logs"]}
chainTo
[{"pattern":"console\\.log\\s*\\(\\s*['\"]error|catch\\s*\\(\\w+\\)\\s*\\{\\s*\\n\\s*console\\.log","targetSkill":"vercel-functions","message":"Console.log-only error handling detected in route handler — loading Vercel Functions guidance for structured error handling, proper logging, and function runtime configuration.","skipIfFileContains":"captureException|@sentry/|@opentelemetry/|logger\\.\\w+|Sentry\\.|reportError"},{"pattern":"from\\s+['\"]@sentry/(nextjs|node)['\"\"]","targetSkill":"nextjs","message":"Sentry SDK import detected — loading Next.js guidance for instrumentation.ts setup and Sentry config integration.","skipIfFileContains":"instrumentation\\.register|withSentryConfig"},{"pattern":"winston|pino|bunyan","targetSkill":"observability","message":"Third-party logger detected (winston/pino/bunyan) — Vercel provides native structured logging, runtime logs, and Drains for log export. Loading Observability guidance for Vercel-native logging.","skipIfFileContains":"@vercel/otel|@opentelemetry/|Sentry\\."}]
Vercel Observability
You are an expert in Vercel's observability stack — runtime logs, structured logging, Drains, Web Analytics, Speed Insights, and monitoring integrations. Always start with logging. When something is stuck, slow, or broken, the first step is always to check or add logs.
Structured Logging Baseline
Add this to every API route and server action as a minimum. If the user reports something stuck, hanging, or slow, verify this baseline exists first:
// instrumentation.ts (Next.js 16)exportasyncfunctionregister() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
// Initialize monitoring on server startupconst { initMonitoring } = awaitimport('./lib/monitoring')
initMonitoring()
}
}
Runtime Logs via REST API
Query deployment runtime logs programmatically. The endpoint returns application/stream+json — a streaming response where each line is a separate JSON object.
# Stream runtime logs for a deployment (returns application/stream+json)
curl -N -H "Authorization: Bearer $VERCEL_TOKEN" \
"https://api.vercel.com/v3/deployments/<deployment-id>/events" \
--max-time 120
Streaming guidance: The response is unbounded — always set a timeout (--max-time in curl, AbortController with setTimeout in fetch). Parse line-by-line as NDJSON. Each line contains { timestamp, text, level, source }.
// Programmatic streaming with timeoutconst controller = newAbortController()
const timeout = setTimeout(() => controller.abort(), 60_000) // 60s maxconst res = awaitfetch(
`https://api.vercel.com/v3/deployments/${deploymentId}/events`,
{
headers: { Authorization: `Bearer ${process.env.VERCEL_TOKEN}` },
signal: controller.signal,
}
)
const reader = res.body!.getReader()
const decoder = newTextDecoder()
let buffer = ''try {
while (true) {
const { done, value } = await reader.read()
if (done) break
buffer += decoder.decode(value, { stream: true })
const lines = buffer.split('\n')
buffer = lines.pop()! // keep incomplete line in bufferfor (const line of lines) {
if (!line.trim()) continueconst event = JSON.parse(line)
console.log(`[${event.level}] ${event.text}`)
}
}
} finally {
clearTimeout(timeout)
}
MCP alternative: Use get_runtime_logs via the Vercel MCP server for agent-friendly log queries without managing streams directly. See ⤳ skill: vercel-api.
Web Analytics
Privacy-friendly, first-party analytics with no cookie banners required.
Speed Insights attributes metrics to specific routes and pages, letting you identify which pages are slow and why.
Drains
Drains forward observability data from Vercel to external endpoints. They are the primary mechanism for exporting logs, traces, Speed Insights, and Web Analytics data to third-party platforms.
Plan requirement: Drains require a Pro or Enterprise plan. For Hobby plans, see the Fallback Guidance section below.
Data Types
Drains can forward multiple categories of telemetry:
Data Type
What It Contains
Use Case
Logs
Runtime function logs, build logs, static access logs
Ingestion tip: For NDJSON, process line-by-line as events arrive. This format is preferred for high-volume pipelines where batch parsing overhead matters.
Security: Signature Verification
Vercel signs every drain payload with an HMAC-SHA1 signature in the x-vercel-signature header. Always verify signatures in production to prevent spoofed data.
Critical: You must verify against the raw request body (not a parsed/re-serialized version). JSON parsing and re-stringifying can change key order or whitespace, breaking the signature match.
Secret management: The drain signing secret is shown once when you create the drain. Store it in an environment variable (e.g., DRAIN_SECRET). If lost, delete and recreate the drain.
OpenTelemetry Integration
Vercel exports traces in OpenTelemetry-compatible format via Drains. Configure an OTel-compatible drain endpoint at https://vercel.com/dashboard/{team}/~/settings/log-drains → Add Log Drain → select OTLP format, or via the REST API.
Upgrade path: When ready for centralized observability, upgrade to Pro and configure drains at https://vercel.com/dashboard/{team}/~/settings/log-drains or via REST API. The drain setup is typically < 5 minutes.
Deploy Preflight Observability
Before promoting to production, verify observability readiness:
Drains check: Query configured drains via MCP list_drains or REST API. If no drains are configured on a Pro/Enterprise plan, warn:
⚠️ No drains configured. Production errors won't be forwarded to external monitoring.
Configure drains via Dashboard or REST API before promoting. See ⤳ skill: observability.
Errored drains: If any drain is in error state, warn and suggest remediation before deploying:
⚠️ Drain "" is errored. Fix or recreate before production deploy to avoid monitoring gaps.
Error monitoring: Check that at least one of these is in place: configured drains, an error tracking integration (e.g., Sentry, Datadog via vercel integration ls), or @vercel/analytics in the project.
These are warnings, not blockers — the user may proceed after acknowledgment.
Post-Deploy Error Scan
For production deployments, wait 60 seconds after READY state, then scan for early runtime errors: