Static deploys
When the runtime VM is skipped entirely.
A deploy takes the static (no-VM) path when all three of these are true at build time:
manifest.static === true(set byvibes-buildwhen!hasDb && functions.length === 0)- The deploy's schema has zero collections (
hasDb === false) - Zero functions discovered by the scanner
The orchestrator re-derives all three signals server-side; the build flag alone is never trusted.
Storage layout
static-deploys/{slug}/v{N}/
index.html
assets/index-<hash>.js
assets/index-<hash>.css
...Per-file uploads run in parallel (16-wide) directly from the in-memory
tar walker (Manager.packAndUploadStaticAssets).
Cache-Control
Assigned per-directory at upload time so the bytes carry the right header out of S3 and CF edge can cache the right way:
| Path | Cache-Control |
|---|---|
assets/* | public, max-age=31536000, immutable |
index.html, root | public, max-age=60, must-revalidate |
Vite hashes filenames under dist/assets/ by default; if assetsDir
is ever pinned elsewhere, update staticAssetsCacheControl in
manager.go to match.
Serving
DeployProxy.ServeHTTP branches on dep.Static:
GET https://{slug}.apps.omg.dev/<path>
─→ DeployProxy.serveStatic
─→ tigris.GetStaticAsset(slug, dep.StaticVersion, path)
hit: stream body + meta headers (CT, Cache-Control, ETag)
miss with extension:
try v{N-1} ← cached-HTML fallback
still miss → 404
miss without extension or Accept: text/html:
serve v{N}/index.html ← SPA fallbackThe v:N-1 fallback for hashed-asset misses is what makes redeploys
zero-downtime for clients holding a max-age=60 cached old HTML. Combined
with the 90s-deferred DeleteStaticVersion(N-1) GC, the window where a
stale-pointer asset can 404 is closed.
What this saves
Per-deploy, vs the serverful path:
- No fork / no VM scheduling
- No bun runtime memory (~80-150 MB)
- No litestream replicate process
- No SQLite WAL traffic
- Cold-start latency for a static deploy is the time to fetch the closest CF edge cache hit (~ms)
Trade-off: a static deploy can't grow into a serverful one without a redeploy. The build pipeline detects the transition automatically the moment a function or schema collection appears.