Static
Anything with an index.html. Served straight from storage — no image, no pod, no cold start.
A static function serves files directly from an immutable snapshot. Nothing is built, no container runs, and there is no cold start at all.
Finding the site root
Unless you set a static directory in settings, the root is found in this order:
dist/,build/,public/,_site/orout/— but only if that directory contains anindex.html. The check exists so a Go project'sbuild/is not mistaken for a built site.index.htmlat the source root.
If neither is found the deploy fails saying so. An explicit static directory must exist in the tree and must be inside it — a path escaping the source root is refused.
Nothing is compiled. If your site is generated by a build step, run that step
yourself and deploy the output — either by committing it, or by uploading the
built directory. A static function will not run your build script.
How requests are served
| Request | Served |
|---|---|
/ | index.html |
/docs/ | docs/index.html |
/docs | docs, then docs/index.html |
/app.css | app.css |
| nothing matches | 404.html with a 404 status, or a plain 404 |
A path with no extension tries the file first and then a directory index, so a link written without a trailing slash behaves the way you expect.
Only GET and HEAD are answered; anything else gets a 405. Path traversal is
resolved away before the lookup, so ../ cannot escape the site root.
Caching
Every response carries an ETag — the file's content hash, which is exact
rather than heuristic because the snapshot is immutable. A matching
If-None-Match gets a 304 before any body is written.
| Content | Cache-Control |
|---|---|
.html, .htm, extensionless | public, max-age=0, must-revalidate |
| everything else | public, max-age=3600 |
HTML revalidates on every request because it is the entry point a deploy must be able to change immediately. Sub-resources are usually fingerprinted and are cheap to revalidate against the ETag regardless.
What a static function cannot have
Environment variables, secrets, a port, an entrypoint and system packages are all refused — there is no process for them to act on. Scaling settings are ignored for the same reason.
If you need any of those, you need a Node.js or Go function, and kind is fixed at creation.