← VercelCONTENT HISTORY

Update to Vercel

Snapshot Sep 30, 2026 · 23:18 UTC · version 0.21.4

Collection source: not recorded for this historical snapshot. These snapshots do not have a confirmed matching collection source. Differences in file lists alone do not establish changes to the package.

WHAT CHANGED · RULE-BASED ANALYSIS

Supporting file metadata differs

Newly listed paths: agents/openai.yaml. This compares saved file lists, not package contents; a different collection source can change the list.

Observed in package metadata. These changes alone do not establish a new customer-facing feature.

Supporting files

Before

[]

After

[{"relative_path":"agents/openai.yaml","size_in_bytes":182}]

Compare saved observations

Download comparison JSON
Full technical diff · 1 changed fields

changed /included_files

BEFORE
[]
AFTER
[
  {
    "relative_path": "agents/openai.yaml",
    "size_in_bytes": 182
  }
]
Full snapshot data
{
  "name": "vercel-functions",
  "description": "Vercel Functions expert guidance — Serverless Functions, Edge Functions, Fluid Compute, streaming, Cron Jobs, and runtime configuration. Use when configuring, debugging, or optimizing server-side code running on Vercel.",
  "included_files": [
    {
      "relative_path": "agents/openai.yaml",
      "size_in_bytes": 182
    }
  ],
  "skill_md_contents": "---\nname: vercel-functions\ndescription: Vercel Functions expert guidance — Serverless Functions, Edge Functions, Fluid Compute, streaming, Cron Jobs, and runtime configuration. Use when configuring, debugging, or optimizing server-side code running on Vercel.\nmetadata:\n  priority: 8\n  docs:\n    - \"https://vercel.com/docs/functions\"\n    - \"https://vercel.com/docs/functions/runtimes\"\n    - \"https://vercel.com/docs/functions/websockets\"\n  sitemap: \"https://vercel.com/sitemap/docs.xml\"\n  pathPatterns:\n    - 'api/**/*.*'\n    - 'pages/api/**'\n    - 'src/pages/api/**'\n    - 'app/**/route.*'\n    - 'src/app/**/route.*'\n    - 'apps/*/api/**/*.*'\n    - 'apps/*/app/**/route.*'\n    - 'apps/*/src/app/**/route.*'\n    - 'apps/*/pages/api/**'\n    - 'vercel.json'\n    - 'apps/*/vercel.json'\n  bashPatterns:\n    - '\\bvercel\\s+dev\\b'\n    - '\\bvercel\\s+logs\\b'\n  importPatterns:\n    - 'ws'\n    - 'socket.io'\n    - 'socket.io-client'\n  promptSignals:\n    phrases:\n      - \"websocket\"\n      - \"websockets\"\n      - \"web socket\"\n      - \"socket.io\"\n      # Polling is the classic technique people reach for when they think Vercel\n      # lacks websockets. We intentionally do NOT trigger on named third-party\n      # services (Pusher, PubNub, Ably) — those are deliberate choices, not a\n      # signal that someone is working around a missing feature.\n      - \"long polling\"\n      - \"long-polling\"\n    allOf: []\n    anyOf:\n      - \"realtime\"\n      - \"bidirectional\"\n      - \"ws server\"\n      - \"polling\"\n      - \"server-sent events\"\n    noneOf: []\n    minScore: 6\n---\n\n# Vercel Functions\n\nYou are an expert in Vercel Functions — the compute layer of the Vercel platform.\n\n## Function Types\n\n### Serverless Functions (Node.js)\n- Full Node.js runtime, all npm packages available\n- Default for Next.js API routes, Server Actions, Server Components\n- Cold starts: 800ms–2.5s (with DB connections)\n- Max duration: 10s (Hobby), 300s (Pro default), 800s (Fluid Compute Pro/Enterprise)\n\n```ts\n// app/api/hello/route.ts\nexport async function GET() {\n  return Response.json({ message: 'Hello from Node.js' })\n}\n```\n\n### Edge Functions (V8 Isolates)\n- Lightweight V8 runtime, Web Standard APIs only\n- Ultra-low cold starts (<1ms globally)\n- Limited API surface (no full Node.js)\n- Best for: auth checks, redirects, A/B testing, simple transformations\n\n```ts\n// app/api/hello/route.ts\nexport const runtime = 'edge'\n\nexport async function GET() {\n  return new Response('Hello from the Edge')\n}\n```\n\n### Bun Runtime (Public Beta)\n\nAdd `\"bunVersion\": \"1.x\"` to `vercel.json` to run Node.js functions on Bun instead. ~28% lower latency for CPU-bound workloads. Supports Next.js, Express, Hono, Nitro.\n\n### Rust Runtime (Public Beta)\n\nRust functions run on Fluid Compute with HTTP streaming and Active CPU pricing. Built on the community Rust runtime. Supports environment variables up to 64 KB.\n\n### Node.js 24 LTS\n\nNode.js 24 LTS is now GA on Vercel for both builds and functions. Features V8 13.6, global `URLPattern`, Undici v7 for faster `fetch()`, and npm v11.\n\n### Choosing Runtime\n\n| Need | Runtime | Why |\n|------|---------|-----|\n| Full Node.js APIs, npm packages | `nodejs` | Full compatibility |\n| Lower latency, CPU-bound work | `nodejs` + Bun | ~28% latency reduction |\n| Ultra-low latency, simple logic | `edge` | <1ms cold start, global |\n| Database connections, heavy deps | `nodejs` | Edge lacks full Node.js |\n| Auth/redirect at the edge | `edge` | Fastest response |\n| AI streaming | Either | Both support streaming |\n| Systems-level performance | `rust` (beta) | Native speed, Fluid Compute |\n\n## Fluid Compute\n\nFluid Compute is the unified execution model for all Vercel Functions (both Node.js and Edge).\n\nKey benefits:\n- **Optimized concurrency**: Multiple invocations on a single instance — up to 85% cost reduction for high-concurrency workloads\n- **Extended durations**: Default 300s for all plans; up to 800s on Pro/Enterprise\n- **Active CPU pricing**: Charges only while CPU is actively working, not during idle/await time. Enabled by default for all plans. Memory-only periods billed at a significantly lower rate.\n- **Background processing**: `waitUntil` / `after` for post-response tasks\n- **Dynamic scaling**: Automatic during traffic spikes\n- **Bytecode caching**: Reduces cold starts via Rust-based runtime with pre-compiled function code\n- **Multi-region failover**: Default for Enterprise when Fluid is activated\n\n### Instance Sizes\n\n| Size | CPU | Memory |\n|------|-----|--------|\n| Standard (default) | 1 vCPU | 2 GB |\n| Performance | 2 vCPU | 4 GB |\n\nHobby projects use Standard CPU. The Basic CPU instance has been removed.\n\n### Background Processing with `waitUntil`\n\n```ts\n// Continue work after sending response\nimport { waitUntil } from '@vercel/functions'\n\nexport async function POST(req: Request) {\n  const data = await req.json()\n\n  // Send response immediately\n  const response = Response.json({ received: true })\n\n  // Continue processing in background\n  waitUntil(async () => {\n    await processAnalytics(data)\n    await sendNotification(data)\n  })\n\n  return response\n}\n```\n\n### Next.js `after` (equivalent)\n\n```ts\nimport { after } from 'next/server'\n\nexport async function POST(req: Request) {\n  const data = await req.json()\n\n  after(async () => {\n    await logToAnalytics(data)\n  })\n\n  return Response.json({ ok: true })\n}\n```\n\n## Streaming\n\nZero-config streaming on **both runtimes**, including Server-Sent Events (SSE). Essential for AI applications.\n\n> **You do NOT need `runtime = 'edge'` for streaming or SSE.** Streaming responses (`ReadableStream`, `text/event-stream`) work on the default Node.js runtime — this is a common misconception. Stay on Node.js (Fluid Compute) so you keep full Node.js APIs, npm packages, and longer durations; Edge offers no streaming advantage here.\n\n```ts\nexport async function POST(req: Request) {\n  const encoder = new TextEncoder()\n  const stream = new ReadableStream({\n    async start(controller) {\n      for (const chunk of data) {\n        controller.enqueue(encoder.encode(chunk))\n        await new Promise(r => setTimeout(r, 100))\n      }\n      controller.close()\n    },\n  })\n\n  return new Response(stream, {\n    headers: { 'Content-Type': 'text/event-stream' },\n  })\n}\n```\n\nFor AI streaming, use the AI SDK's `toUIMessageStreamResponse()` (for chat UIs with `useChat`) which handles SSE formatting automatically.\n\n## WebSockets\n\nVercel Functions can hold open bidirectional WebSocket connections — use them for realtime features like interactive AI streaming, chat, and collaborative apps. There is **no separate WebSocket-server product and no third-party service (Pusher, Ably, etc.) required** — it runs on Vercel Functions directly. Requires **Fluid Compute**, which is the default for new projects.\n\n**How it works**: a WebSocket starts as an HTTP `GET` with an `Upgrade` header, so it passes through the same Routing Middleware, rewrites, Firewall rules, and rate limits as any other request. After the upgrade, the connection is pinned to a single function instance for its lifetime; Fluid Compute lets one instance serve many concurrent connections. Active CPU pricing means you're billed while processing messages, not for idle open connections — the same limits and pricing as other Function invocations apply.\n\n### `ws` (no extra config)\n\nWebSockets work like any distributed WebSocket server — export an `http.Server` and use a library such as `ws`:\n\n```ts\n// api/ws.ts\nimport http from 'http'\nimport { WebSocketServer } from 'ws'\n\nconst server = http.createServer()\nconst wss = new WebSocketServer({ server })\n\nwss.on('connection', (ws) => {\n  ws.on('message', (data) => ws.send(data)) // echo\n})\n\nexport default server\n```\n\n### Socket.IO\n\nHigher-level realtime libraries like Socket.IO work too. Configure the **client** to use the WebSocket transport directly — Socket.IO defaults to HTTP long-polling, which won't work:\n\n```ts\n// api/socket-io.ts\nimport http from 'http'\nimport { Server } from 'socket.io'\n\nconst server = http.createServer()\nconst io = new Server(server)\n\nio.on('connection', (socket) => {\n  socket.on('message', (data) => socket.send(data))\n})\n\nexport default server\n```\n\n```ts\n// client.ts\nimport { io } from 'socket.io-client'\n\nconst socket = io('https://your-domain.com', {\n  // Socket.IO appends /socket.io, so the full path becomes /api/socket-io/socket.io\n  path: '/api/socket-io/socket.io',\n  transports: ['websocket'], // required — Socket.IO defaults to HTTP long-polling\n})\n```\n\nExpress, Hono, and Nitro (including Nuxt, via native WebSocket support) serve WebSockets the same way — export the HTTP server. Python frameworks work too: FastAPI handles the upgrade natively, and `python-socketio` is protocol-compatible with the JS Socket.IO client.\n\n### Next.js\n\nNext.js doesn't expose an API for handling WebSocket upgrades. Use `experimental_upgradeWebSocket()` from `@vercel/functions` inside a route handler:\n\n```ts\n// app/api/ws/route.ts\nimport { experimental_upgradeWebSocket, type WebSocketData } from '@vercel/functions'\n\nexport async function GET() {\n  return experimental_upgradeWebSocket((ws) => {\n    ws.on('message', (data: WebSocketData) => ws.send(data))\n  })\n}\n```\n\n### Reconnects and persistent state\n\n- **Connections close when the function reaches its max duration.** Clients must reconnect with backoff, then resubscribe to channels and reload any state they need.\n- **No instance affinity across connections.** A reconnect — or a new deployment — may land on a different instance, so never keep durable state, presence, rooms, or pub/sub coordination in memory. Use an external store such as [Redis from the Marketplace](https://vercel.com/marketplace/redis).\n\n```ts\n// client.ts — reconnect with exponential backoff\nlet socket: WebSocket\nlet delay = 1000\n\nfunction connect() {\n  socket = new WebSocket('wss://your-domain.com/api/ws')\n  socket.addEventListener('open', () => { delay = 1000 })\n  socket.addEventListener('message', (e) => console.log(e.data))\n  socket.addEventListener('close', () => {\n    setTimeout(connect, delay)\n    delay = Math.min(delay * 2, 30000)\n  })\n}\n\nconnect()\n```\n\n## Cron Jobs\n\nSchedule function invocations via `vercel.json`:\n\n```json\n{\n  \"crons\": [\n    {\n      \"path\": \"/api/daily-report\",\n      \"schedule\": \"0 8 * * *\"\n    },\n    {\n      \"path\": \"/api/cleanup\",\n      \"schedule\": \"0 */6 * * *\"\n    }\n  ]\n}\n```\n\nThe cron endpoint receives a normal HTTP request. Verify it's from Vercel:\n\n```ts\nexport async function GET(req: Request) {\n  const authHeader = req.headers.get('authorization')\n  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {\n    return new Response('Unauthorized', { status: 401 })\n  }\n  // Do scheduled work\n  return Response.json({ ok: true })\n}\n```\n\n## Configuration via vercel.json\n\n**Deprecation notice**: Support for the legacy `now.json` config file will be removed on **March 31, 2026**. Rename `now.json` to `vercel.json` (no content changes required).\n\n```json\n{\n  \"functions\": {\n    \"app/api/heavy/**\": {\n      \"maxDuration\": 300,\n      \"memory\": 1024\n    },\n    \"app/api/edge/**\": {\n      \"runtime\": \"edge\"\n    }\n  }\n}\n```\n\n## Timeout Limits\n\nAll plans now default to 300s execution time with Fluid Compute.\n\n| Plan | Default | Max |\n|------|---------|-----|\n| Hobby | 300s | 300s |\n| Pro | 300s | 800s |\n| Enterprise | 300s | 800s |\n\n## Common Pitfalls\n\n1. **Cold starts with DB connections**: Use connection pooling (e.g., Neon's `@neondatabase/serverless`)\n2. **Edge limitations**: No `fs`, no native modules, limited `crypto` — use Node.js runtime if needed\n3. **Timeout exceeded**: Use Fluid Compute for long-running tasks, or Workflow DevKit for very long processes\n4. **Bundle size**: Functions support up to 5 GB package size on Fluid Compute (up from 250 MB); request bodies up to 100 MB (up from 4.5 MB)\n5. **Environment variables**: Available in all functions automatically; use `vercel env pull` for local dev\n\n## Function Runtime Diagnostics\n\n### Timeout Diagnostics\n\n```\n504 Gateway Timeout?\n├─ All plans default to 300s with Fluid Compute\n├─ Pro/Enterprise: configurable up to 800s\n├─ Long-running task?\n│  ├─ Under 5 min → Use Fluid Compute with streaming\n│  ├─ Up to 15 min → Use Vercel Functions with `maxDuration` in vercel.json\n│  └─ Hours/days → Use Workflow DevKit (DurableAgent or workflow steps)\n└─ DB query slow? → Add connection pooling, check cold start, use Edge Config\n```\n\n### 500 Error Diagnostics\n\n```\n500 Internal Server Error?\n├─ Check Vercel Runtime Logs (Dashboard → Deployments → Functions tab)\n├─ Missing env vars? → Compare `.env.local` against Vercel dashboard settings\n├─ Import error? → Verify package is in `dependencies`, not `devDependencies`\n└─ Uncaught exception? → Wrap handler in try/catch, use `after()` for error reporting\n```\n\n### Invocation Failure Diagnostics\n\n```\n\"FUNCTION_INVOCATION_FAILED\"?\n├─ Memory exceeded? → Increase `memory` in vercel.json (up to 3008 MB on Pro)\n├─ Crashed during init? → Check top-level await or heavy imports at module scope\n└─ Edge Function crash? → Check for Node.js APIs not available in Edge runtime\n```\n\n### Cold Start Diagnostics\n\n```\nCold start latency > 1s?\n├─ Using Node.js runtime? → Consider Edge Functions for latency-sensitive routes\n├─ Large function bundle? → Audit imports, use dynamic imports, tree-shake\n├─ DB connection in cold start? → Use connection pooling (Neon serverless driver)\n└─ Enable Fluid Compute to reuse warm instances across requests\n```\n\n### Edge Function Timeout Diagnostics\n\n```\n\"EDGE_FUNCTION_INVOCATION_TIMEOUT\"?\n├─ Edge Functions have 25s hard limit (not configurable)\n├─ Move heavy computation to Node.js Serverless Functions\n└─ Use streaming to start response early, process in background with `waitUntil`\n```\n\n## Official Documentation\n\n- [Vercel Functions](https://vercel.com/docs/functions)\n- [Serverless Functions](https://vercel.com/docs/functions)\n- [Edge Functions](https://vercel.com/docs/functions)\n- [Fluid Compute](https://vercel.com/docs/fluid-compute)\n- [Streaming](https://vercel.com/docs/functions/streaming)\n- [WebSockets](https://vercel.com/docs/functions/websockets)\n- [Cron Jobs](https://vercel.com/docs/cron-jobs)\n- [GitHub: Vercel](https://github.com/vercel/vercel)\n"
}

SHA-256: eb38511bef0728978aaa2997367e13b9993e9c02544b8fd40930d765bbd7d5bb