Request routing
How the edge matches a hostname and path to a static asset, a storage object or a Function.
The edge turns a hostname into a deployment, then matches the path and method against that deployment's route table. A request becomes an invocation only when nothing cheaper can answer it.
Hostnames
Gigadrive Network gives an application three kinds of system hostname on gigadrive.app, and the edge resolves all of them through one lookup.
| Hostname | Points at | Re-points |
|---|---|---|
| Production alias | The current production deployment | On every promotion |
| Branch alias | The newest deployment of one branch | On every deployment of that branch |
| Per-deployment hostname | Exactly one deployment | Never |
A hostname the platform does not know returns a branded 404 page carrying the error code EDGE_DEPLOYMENT_NOT_FOUND. A hostname that resolves to a deployment which is not active returns 503 with EDGE_DEPLOYMENT_INACTIVE, which is what you see while a first deployment is still building. Only generated hostnames resolve here, so a domain you own reaches nothing, as Custom domains explains.
Bucket hostnames are classified before any of this. A request whose host is a File storage delivery hostname is served straight from the bucket and never reaches a deployment's routes.
What the edge tries, in order
- Image optimization.
/_gigadrive/image/*and the/_next/imagealias are answered by the edge and never invoke a Function. See Image optimization. - Framework routing. A Next.js deployment is resolved with Next's own routing metadata, so its redirects, rewrites, middleware and prerendered pages behave as they do locally.
- The route table. Everything else matches against the flat table the build produced: one entry per configured Function route and method, plus
GET,HEADandOPTIONSentries for every published asset. - A directory index. If nothing in the route table matched, the edge retries the path as a directory and looks for a published index file, described in Static assets.
- A superseded deployment. Before giving up, the edge checks recently replaced deployments for content-hashed build assets, also described in Static assets.
- 404. No match returns a branded page with
EDGE_ROUTE_NOT_FOUND.
How a path matches a route
Matching runs against the request path without its query string, and a route only applies when its method equals the request method or is ANY.
| Route path form | Matches |
|---|---|
A literal path, for example /api/users | The same path, compared without regard to case |
A prefix ending in *, for example /assets/* | Any path starting with the text before the * |
A regular expression starting with ^ | Any path the expression matches |
/index, /index.html, /index.htm, /index.php | / only |
Two details decide ambiguous cases. Routes whose path is exactly the request path are tried first; after that the table is ordered with / first and then longer paths before shorter ones, so /api/webhooks/stripe wins over /api/*. And a regular expression is tested unanchored, so ^/api also claims /api-internal. Anchor both ends: ^/api(/.*)?$.
A route path that starts with / and contains a dot is compiled as a regular expression too, once a literal comparison has failed. /logo.png therefore also matches /logoXpng, and matches it anywhere in the path.
A nested index file is a separate mechanism from the table above: it does not match as a route path, but a published about/index.html still answers /about and /about/ once nothing in the table matches either form. Static assets covers that resolution.
Declaring routes
Routes live in gigadrive.yaml. Each entry maps a path pattern to a Function entrypoint you declared under functions, optionally narrowed by method.
version: 4
functions:
api/index.js:
runtime: node-22
memory: 512
routes:
- source: ^/api(/.*)?$
destination: /api/index.js
methods: [GET, POST]
headers:
cache-control: no-storeStatic assets do not need a route. Every file the build publishes is registered automatically, so routes is only for the paths your code answers. Adding your own routes block replaces the whole route table a detected framework would have generated, so a framework project that needs one custom route has to restate the framework's routes as well. Routes covers the full key reference.
Response headers
The headers map on a route is applied to the response after the handler returns. Route config cannot overwrite x-request-id, content-length, or any hop-by-hop header. A cache-control from route config is also skipped on any response with a status of 400 or above, so an error page is never cached because of a rule meant for the happy path.
The edge adds x-request-id to every response and echoes it into the forwarded request, which is the id you search for in Request logs.
Long-lived streams are cut at 60 seconds
The CDN closes an origin response that stays open longer than 60 seconds, which ends server-sent events and long-polling connections mid-stream. Use WebSockets for connections that need to outlive that window.
