Static assets
How the files your build produces are uploaded, addressed at the edge, and served without invoking a Function.
Everything your build writes into the assets directory is uploaded to object storage during the deployment and served by the edge. No invocation is involved, so a page of images and scripts costs nothing in compute.
What gets published
A framework project publishes its build output directory automatically. Without a framework, name the directory yourself:
version: 4
assets: publicThe directory is walked recursively and every regular file inside it becomes an asset, addressed at its path with the directory prefix removed. public/css/app.css is served at /css/app.css.
Unchanged files do not upload again. A deployment that changes one file transfers one file, so redeploying an application with a large asset directory stays fast.
Some files are never published, whichever way the directory was chosen:
- Anything that is also a Function entrypoint, or whose path is used verbatim as a route
source. Apublic/index.phpthat yourfunctionsblock declares stays a Function. node_modules/andvendor/.package.json,package-lock.json,pnpm-lock.yaml,.gitignore,.git/and.github/.- The
gigadrive.yamlfile itself. - Files ending in
.htaccessor.htpasswd. - Anything matching a pattern in the Function's
excludeFiles.
Symbolic links are rejected rather than followed, and a path that resolves outside the project directory fails the build with a clear error. Assets covers the configuration keys.
Immutable prefixes
A content-hashed build directory can hold tens of thousands of files, and registering each one individually makes the deployment record enormous for no benefit. Frameworks that produce such a directory register it as a single prefix instead: the whole .next/static tree becomes one entry serving /_next/static/, and the edge derives the object key from the part of the request path that follows the prefix.
Prefix lookup is case-sensitive, unlike the route table, because it maps directly onto object keys. A remainder containing ., .., a backslash or a null byte is rejected before any storage read.
Files under a hashed prefix are the ones that benefit most from long cache lifetimes, which is why the per-deployment hostname serves them with a one-year immutable lifetime. See Caching for the full header matrix.
Serving semantics
| Behaviour | What the edge does |
|---|---|
| Methods | GET, HEAD and OPTIONS. Anything else returns 405 with an Allow header. |
| Range requests | accept-ranges: bytes is always set. A single range returns 206, a malformed one 416. |
If-None-Match | Returns 304. It takes precedence over If-Modified-Since. |
If-Match | Returns 412 when the entity tag does not match, as does a failed If-Unmodified-Since. |
| Unknown path | Returns 404 with cache-control: no-store. |
| Missing content type | Falls back to application/octet-stream. |
Directory requests
A request path that nothing else answers is retried as a directory before the edge gives up. /about and /about/ both resolve to a published about/index.html or about/index.htm, the way a static host serves a directory, and / resolves the same way at the root.
This runs only once every route your configuration declares has already missed, so a catch-all Function route still answers every path it matches, and publishing public/ unchanged alongside a server Function keeps serving those files at their own paths. A directory with no published index file returns 404 instead of falling back to a page from elsewhere in the site.
Assets from a replaced deployment
Promoting a new deployment does not delete the old one's objects, and that matters more than it sounds. An HTML document already sitting in a browser tab or a CDN cache still points at the previous build's hashed filenames, and those filenames do not exist in the new deployment's index.
So when a request for a hashed asset misses, the edge looks for it in recently replaced deployments of the same environment before returning 404. Eligibility is narrow on purpose: GET and HEAD only, and the path either sits under _next/static/ or has a content-hash-shaped filename ending in .js, .mjs, .css, .map, .woff, .woff2, .json or .wasm. Up to three prior deployments are consulted.
Nothing in your application has to opt in. A rollback is covered the same way, since the deployment it moves away from is one of the candidates.
Warming
After a promotion, the platform requests a sample of the deployment's fully prerendered pages so the first real visitor does not pay for a cold CDN. Only pages that were rendered at build time are warmed, because warming must never invoke a Function.
Warming traffic is identifiable in Request logs by its user agent, Gigadrive-CacheWarmer/1.0.
populateAssetCache has no effect
gigadrive.yaml accepts a populateAssetCache key and the build parses it, but nothing in the platform reads the
result. Warming selects fully prerendered pages as entry points, then also requests Next.js static assets referenced
by those pages, whether you set it or not.
