Son las 2 AM. Tu endpoint /api/checkout lleva 47 minutos devolviendo errores 500. Tu monitor de uptime externo? Muestra verde. El health check responde 200 OK cada 60 segundos, como si nada.
Mientras tanto, 340 requests reales de checkout fallaron. Te enteras a la manana siguiente por un backlog de webhooks de Stripe y tres emails de clientes enojados.
Este es el problema del monitoreo externo para APIs de Next.js. Revisa la puerta de entrada. No sabe que pasa adentro.
Por que el monitoreo externo no alcanza para Next.js
Herramientas como Pingdom, UptimeRobot e incluso los synthetic checks de Datadog funcionan igual: envian un request HTTP a una URL cada N segundos y verifican si la respuesta es 200. Eso es todo.
Para una aplicacion Next.js, este modelo tiene puntos ciegos fundamentales:
- Solo testea un endpoint a la vez. Si tenes 15 API routes, necesitas 15 monitores separados.
- No detecta fallos intermitentes. Si tu
/api/paymentsfalla en 3 de cada 100 requests por una race condition, un ping cada 60 segundos nunca lo va a capturar. - No mide latencia real. El round-trip desde Virginia incluye latencia de red, cache de CDN y routing de edge. Nada de eso refleja lo que experimentan tus usuarios.
- No funciona detras de firewalls. Si tu API es interna, los pings externos literalmente no la alcanzan.
- Los cold starts rompen las mediciones. Un health check que pega en una funcion warm mide 50ms. Un usuario real en cold start recibe 1800ms.
El Hook de Instrumentacion de Next.js
Desde Next.js 13.2, existe una forma nativa de ejecutar codigo cuando el servidor arranca: el hook de instrumentacion. Creas un archivo instrumentation.ts en la raiz de tu proyecto, y Next.js llama a su funcion register() una vez durante la inicializacion.
// instrumentation.ts
export async function register() {
// Se ejecuta una vez cuando arranca el servidor.
// Ideal para inicializar monitoreo, tracing o logging.
console.log('Servidor inicializado - monitoreo activo')
}Monitor basico de requests desde cero
Para entender como funciona el monitoreo interno, aca hay una implementacion minima usando middleware de Next.js:
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const start = Date.now()
const response = NextResponse.next()
const duration = Date.now() - start
const path = request.nextUrl.pathname
if (path.startsWith('/api/')) {
console.log(JSON.stringify({
path,
method: request.method,
duration,
timestamp: new Date().toISOString(),
}))
}
return response
}
export const config = {
matcher: '/api/:path*',
}Esto te da logs estructurados de cada API request. Pero es solo logging, sin alertas, sin agregacion, sin dashboards. Para produccion necesitarias una base de datos de series de tiempo, calcular percentiles, construir alertas y mantener esa infraestructura.
Monitoreo externo vs interno
| Capacidad | Externo (Pingdom, UptimeRobot) | Interno (Hook de instrumentacion) |
|---|---|---|
| Monitorea todos los API routes automaticamente | No, un monitor por URL | Si, intercepta cada request |
| Detecta errores intermitentes | No, samplea cada N segundos | Si, ve cada request |
| Mide latencia real del usuario | No, mide round-trip sintetico | Si, mide tiempo de procesamiento del servidor |
| Funciona detras de firewalls | No | Si |
| Detecta errores en menos de 10 segundos | No, intervalos de 1-5 minutos | Si, tiempo real |
El atajo práctico: OpenTelemetry en 5 líneas
No hace falta parchear internals de Node.js. Next.js trae soporte nativo de OpenTelemetry: cuando registrás un provider de OTel en el hook de instrumentación, Next.js emite spans de los requests y route handlers dentro de tu servidor.
npm install @vercel/otel// instrumentation.ts
import { registerOTel } from '@vercel/otel'
export function register() {
registerOTel({ serviceName: 'my-next-app' })
}Después exportás las trazas a cualquier backend compatible con OTLP, self-hosted o SaaS:
- Todas las rutas cubiertas: Los requests a tus API routes se trazan a medida que pasan.
- Métricas reales: Response time, status codes y errores de cada endpoint, medidos sobre requests reales.
- Alertas: Las configurás en tu backend (Slack, email, etc.) sobre tasa de errores o latencia por ruta.
- Sin lock-in: OTel es un estándar abierto, podés cambiar de backend sin re-instrumentar.
Empezá ahora
- Ejecutá
npm install @vercel/otel - Agregá las 5 líneas a
instrumentation.ts - Apuntá el exporter OTLP al backend que elegiste
- Hacé deploy
- Armá alertas de P95 y tasa de errores por ruta, y sumá un check de uptime externo para caídas totales
Tu /api/checkout a las 2 AM nunca mas va a fallar en silencio.
