Guía9 min

Desplegar un agente IA en Vercel Functions: guía práctica

Resumen

Tutorial paso a paso para correr un agente de IA en Vercel: Route Handler con maxDuration, Cron Jobs con CRON_SECRET, límites Hobby vs Pro (300s / 800s / 30 min beta) y cuándo Functions alcanza frente a Workers, Railway o un VPS.

Vercel
Diagrama de una función en la nube que recibe un webhook y dispara un cron diario

Qué resuelve

Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.

La comparativa Vercel vs Workers vs VPS te dice dónde. Esta guía es el cómo cuando eliges Vercel Functions: un Route Handler con maxDuration, un cron en vercel.json y secretos por entorno. Para un agente de webhook o un job diario, Functions cubre el caso sin servidor que mantener. Las fuentes oficiales fueron consultadas el 3 de septiembre de 2026.

Si necesitas un proceso vivo con sqlite, ve a Railway o al VPS con Docker. Si el cobro por CPU del borde te conviene más, Workers. Aquí el foco es Functions.

Cuándo sí y cuándo no

Sí, si el agente:

  • Vive en un repo Next.js que ya despliegas en Vercel.
  • Responde webhooks y puede terminar en minutos, no en horas.
  • Corre un cron diario (Hobby) o por minuto (Pro).

No, si el agente:

  • Mantiene estado en RAM entre requests: cada invocación arranca de cero.
  • Ejecuta un sandbox de código pesado: mejor sandboxing dedicado fuera de la Function.
  • Necesita un job más frecuente que una vez al día en Hobby: el plan limita crons a una vez al día, con precisión de ±59 minutos.

La regla: Functions es un request con techo de tiempo, no un daemon.

Límites que sí importan

ConceptoHobbyPro
Duración default300 s (5 min)300 s
Máximo300 s800 s (GA); 1800 s / 30 min en beta
Cron jobs100, una vez al día, precisión ±59 min100, hasta una vez por minuto
Cómo se configura >800 sno aplicapor función (maxDuration o vercel.json), no a nivel de proyecto

En App Router:

export const maxDuration = 300;

En Pro, 800 es el techo GA. 1800 está en beta y hay que ponerlo en cada función: un default de proyecto por encima de 800 s no está soportado todavía.

Paso 1 — Route Handler del webhook

Flujo de un agente en Vercel Functions: webhook HTTP y cron

// app/api/agente/route.ts
export const maxDuration = 300;

export async function POST(request: Request) {
  const event = await request.json();
  const result = await runAgent(event);
  return Response.json({ ok: true, result });
}

export function GET() {
  return new Response("ok", { status: 200 });
}

El webhook espera la respuesta. Si el LLM tarda 40 s, la Function sigue viva: no hay el modelo de 10 ms de CPU de Workers. El techo es el maxDuration. Si el proveedor del webhook corta a 10 s, responde 202 y mueve el trabajo a un cron o a una cola — no alargues la Function esperando un cliente que ya se fue.

Paso 2 — Cron Jobs

En Hobby el cron corre una vez al día. En Pro, hasta una vez por minuto. Se declara en vercel.json:

{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "crons": [{ "path": "/api/agente/digest", "schedule": "0 14 * * *" }]
}

Vercel invoca el path con GET. Protege el endpoint con CRON_SECRET: crea la env var (mínimo 16 caracteres aleatorios) y Vercel la manda como header Authorization. Compara los dos valores antes de correr el digest. El header x-vercel-cron-schedule trae la expresión que disparó la invocación — útil si varios crons apuntan al mismo path.

Cambia el schedule, redespliega. Borrar la entrada y redesplegar elimina el cron. Desactivar sin borrar: el dashboard tiene un toggle.

Paso 3 — Secretos por entorno

Las API keys van en Environment Variables del proyecto, marcadas Sensitive, distintas para Production / Preview / Development. vercel env pull las baja a local. No las prefijes NEXT_PUBLIC_. El detalle de rotación y exposición está en secretos y variables de entorno.

Paso 4 — Deploy y verificar

pnpm dlx vercel --prod
curl -s https://tu-proyecto.vercel.app/api/agente

Criterio de éxito: el GET responde ok, un POST de prueba aparece en Runtime Logs, y el cron figura en Settings → Cron Jobs. El primer disparo en Hobby puede caer en cualquier minuto de esa hora (±59 min): no lo uses para un job a las 14:00:00 exactas.

Errores comunes

Errores típicos al operar un agente en Vercel Functions

SíntomaCausa típicaFix
Function timeout a los 300 sHobby no pasa de 5 min; Pro sin maxDurationSube de plan o baja el trabajo; en Pro pon export const maxDuration = 800
Cron no corre cada hora en HobbyHobby es una vez al díaSube a Pro o mueve el job a Workers
401 / digest vacíoFalta CRON_SECRET o no comparas AuthorizationCrea la env var y valida el header
Preview gasta la API key de prodVariable no separada por entornoProduction ≠ Preview en el dashboard
maxDuration = 1800 ignorado a nivel proyectoSolo por función, y en betaDecláralo en el Route Handler, no como default global

Relación con el resto del stack

Functions + Workers juntos funciona si el Worker es la puerta (2xx rápido) y la Function hace el trabajo con maxDuration. No clones el agente en los dos.

Checklist de producción

  • maxDuration explícito en el Route Handler, no el default a ciegas
  • Hobby vs Pro decidido por frecuencia de cron y techo de 5 vs 13 min
  • CRON_SECRET creado y validado en el endpoint
  • Secretos separados por entorno, sin NEXT_PUBLIC_
  • Runtime Logs abiertos el primer día de tráfico
  • Rollback: redeploy del deployment previo en el dashboard

Siguiente paso: si el agente ejecuta código, combina Functions con sandboxing. Si todavía no tienes runtime local, el curso gratuito deja un agente para portarlo al Route Handler.