Back to Blog
Tutorial9 min read2026-06-28

How to Deploy an Edge Function for an API Route

Edge functions give you low-latency API routes that run close to users. Here's when to use one, how to deploy it, and the constraints (no long connections, cold starts) to plan around.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

What an edge function is good for

An edge function is a small, stateless piece of code that runs on demand, close to your users, and returns a response. It's ideal for API routes that are lightweight and latency-sensitive: auth checks, redirects, form handlers, webhook receivers, lightweight JSON APIs, and personalization.

It's the wrong tool for: long-running jobs, persistent WebSocket connections, heavy CPU work, or anything that needs a big bundle of native dependencies. Those belong in a container app. Knowing the boundary saves you a lot of frustration.

Edge function vs. container app

PropertyEdge functionContainer app
LifecyclePer-request, statelessLong-running process
Best forLight API routes, webhooksFull backends, workers, sockets
Cold startPossible on first hitWarm (or scale-to-zero)
StateNone (use external store)In-memory + external
Long connectionsNoYes

A minimal edge function

Edge functions take a request and return a response. A simple JSON API route:

// hello.js
export default async function handler(req) {
  const { searchParams } = new URL(req.url);
  const name = searchParams.get("name") ?? "world";

  return new Response(JSON.stringify({ message: `hello, ${name}` }), {
    status: 200,
    headers: { "content-type": "application/json" },
  });
}

The Web Request/Response API is the common interface across edge runtimes, so code stays portable.

A webhook receiver

A very common edge use case — receive a webhook, verify its signature, do something light, return fast:

import { createHmac, timingSafeEqual } from "node:crypto";

export default async function handler(req) {
  const body = await req.text();
  const sig = req.headers.get("x-signature") ?? "";
  const expected = createHmac("sha256", process.env.WEBHOOK_SECRET)
    .update(body).digest("hex");

  if (!timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
    return new Response("invalid signature", { status: 401 });
  }

  // do the lightweight thing (enqueue, update a flag, etc.)
  return new Response("ok", { status: 200 });
}

Verify signatures with a constant-time comparison (timingSafeEqual) — a plain === leaks timing information.

Calling a database from the edge

Edge functions can hit a database, but be careful: many edge runtimes don't keep TCP pools warm between invocations, so a raw pg pool can exhaust connections fast. Options:

  • Use an HTTP-based / serverless database driver that connects per request over HTTP.
  • Put a connection pooler (e.g., PgBouncer) in front of Postgres.
  • For heavy DB work, call a container app from the edge function instead.

For light reads, a per-request HTTP query is fine; for anything write-heavy or transactional, route to a container backend.

Environment variables and secrets

Edge functions read secrets from env vars just like any other deploy. Never bake secrets into the bundle:

const apiKey = process.env.THIRD_PARTY_KEY;

Set these in the platform's environment settings, scoped to the function.

Deploying on PandaStack

PandaStack includes edge functions (available on all tiers, including free). To deploy an API route:

  1. 1In the dashboard, create a new Edge Function (or add one to your project).
  2. 2Point it at your handler file / repo.
  3. 3Set the route path (e.g., /api/hello) and any environment variables/secrets.
  4. 4Deploy. Edge functions support multiple runtimes (Node.js, Python, Go).
  5. 5Use function tokens for authenticated invocation where needed.

Functions can be invoked via their route or directly, and you get live logs for debugging.

Testing your route

curl "https://your-app.example.com/api/hello?name=ajay"
# {"message":"hello, ajay"}

# webhook with a signature header
curl -X POST https://your-app.example.com/api/webhook \
  -H "x-signature: <hmac>" \
  -d '{"event":"test"}'

Constraints to design around

  • Cold starts. The first invocation after idle may be slower. Keep handlers small to minimize this.
  • Execution time limits. Edge functions are meant to be fast; long work should be enqueued to a worker.
  • No persistent connections. No WebSockets, no holding a socket open — use a container app for that.
  • Stateless. Don't store anything in memory between invocations; use Redis or a database.
  • Bundle size. Big native dependencies often don't run at the edge — keep dependencies lean.

When to graduate to a container

If your "edge function" starts pulling in a heavy ORM, needs transactions, runs for seconds, or wants to hold connections, that's the signal to move it into a container app. Edge functions and containers complement each other: edge for the fast front door, containers for the heavy lifting behind it.

References

  • MDN Request interface: https://developer.mozilla.org/en-US/docs/Web/API/Request
  • MDN Response interface: https://developer.mozilla.org/en-US/docs/Web/API/Response
  • Web Crypto / HMAC (Node crypto): https://nodejs.org/api/crypto.html#cryptocreatehmacalgorithm-key-options
  • Serverless cold starts (overview): https://aws.amazon.com/blogs/compute/operating-lambda-performance-optimization-part-1/
  • Apache OpenWhisk (edge/serverless model): https://openwhisk.apache.org/documentation.html

---

Want low-latency API routes without standing up a whole backend? PandaStack includes edge functions on every tier, even free. Deploy one at https://dashboard.pandastack.io

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also