omg/docs

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 by vibes-build when !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:

PathCache-Control
assets/*public, max-age=31536000, immutable
index.html, rootpublic, 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 fallback

The 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.