How a request is served
The path from a browser to your code, what the edge answers on its own, and what never reaches your Function.
Every request to a Gigadrive Network application arrives at the edge before it reaches anything you wrote. What happens next depends on what the URL matches, and most URLs never reach your code at all.
Matching the request
The edge resolves the hostname to a deployment first. An application has a production hostname, one
hostname per branch, and a permanent hostname per deployment, so the hostname alone decides which
build answers. A hostname that resolves to nothing returns 404. A hostname pointing at a deployment
that is not active returns 503.
The deployment's route table is then matched against the request path. Exact paths are tried first,
then /, then longer paths before shorter ones. A route only matches when the request method is one
the route declares, or the route accepts any method. Exact path matching is case-insensitive; static
asset lookup is case-sensitive, so /Logo.png and /logo.png are different files.
The winning route names one of four things: an object in storage, a redirect, another origin to proxy to, or one of your Functions. Request routing covers the matching rules in detail.
What the edge answers on its own
| Request | Served by |
|---|---|
| A file published as a static asset | Edge, from object storage |
| A hashed asset belonging to a deployment you have since replaced | Edge, from that older deployment's object |
| An optimized image, on a deployment with image optimization enabled | Edge and the image optimizer |
| A redirect route | Edge, as a 308 |
| Server rendering, route handlers, middleware, server actions, WebSockets | Your Function |
Only the last row starts an invocation. The other rows never reach your code, so they cost nothing
in compute and do not count against your concurrency limit. One prefix entry covers a whole immutable
subtree such as /_next/static/, so publishing forty thousand hashed files produces one entry rather
than forty thousand. Static assets explains how a file gets
published this way.
File Storage buckets are served on their own hostnames, not through your application's, so a public object is answered from storage without touching a deployment. See File storage.
Caching sits in front of all of it, and the CDN does not guess: it caches exactly what the response's
Cache-Control header says. A Function response that sets none is stamped no-store. See
Caching.
What reaches your Function
The request your code receives is not byte-identical to the one the browser sent.
- The original
Hostsurvives, so your application sees its real domain. - The client address arrives as a single
x-forwarded-forvalue, resolved at the CDN. Anyx-forwarded-*,true-client-ip,x-real-iporx-http-method-overrideheader the client sent is removed first, so the value you read cannot be forged. accept-encodingis not forwarded. Compression is negotiated between the browser and the CDN.- Request headers are capped at 64 KiB in total and a request body at 6 MiB. A response body is capped at 32 MiB per invocation.
Your response streams back progressively, with every chunk flushed as it arrives rather than buffered
to completion, which is what makes server-sent events and streamed server rendering visible
immediately. Every response carries x-request-id, the id you search for in Request
logs, and x-gigadrive-deployment-id, naming the build that
answered.
Streaming responses are cut at 60 seconds
The CDN closes an origin response it has held open for 60 seconds. A long-lived server-sent-events or long-polling connection is severed at that point even though your Function is still running. Use WebSockets for anything that needs to stay open longer.
When a request is refused
A refusal is answered by the edge with a branded page carrying a stable error code, so you can tell the cause from the response alone.
| Status | Error code | Cause |
|---|---|---|
404 | EDGE_DEPLOYMENT_NOT_FOUND | The hostname does not resolve to a deployment |
404 | EDGE_ROUTE_NOT_FOUND | No route matched the path and method |
503 | EDGE_DEPLOYMENT_INACTIVE | The deployment exists but is not active |
429 | EDGE_FUNCTION_CONCURRENCY_LIMIT | The Function is already at the plan's concurrency limit |
503 | EDGE_FUNCTION_AT_CAPACITY | Every warm copy is busy and a new one is not ready yet |
504 | EDGE_FUNCTION_TIMEOUT | The invocation ran past its maximum duration before sending headers |
502 | EDGE_FUNCTION_UNREACHABLE | Your code could not be reached |
The 429 and the capacity 503 both carry Retry-After: 2, because both clear on their own. A
429 is a plan limit rather than a platform fault, and raising it means changing the plan; see
Concurrency.
