Concepts / Versions & caching

Versions & caching

Editing never touches production until you say so, and shipped flows render instantly even on a dead network. Two mechanisms make that true: drafts with explicit deploys, and layered caching.

Drafts and deploys

Every change you make in the flow editor autosaves to a draft within seconds. The draft is yours alone — the live flow keeps serving untouched. When you're ready:

  • Deploy (or ⌘S) validates the draft, publishes it, and bumps the flow's version. The editor shows the flow going from draft to live.
  • Discard draft throws the draft away and returns the editor to the live version.

If validation fails, deploy is blocked and the errors are listed inline — a broken flow can't reach users.

Server caching

The API serves flows with an ETag and Cache-Control: max-age=60, plus an X-Uplift-Flow-Version header. Practically: a deploy is visible to new fetches within at most a minute, and clients that already have the current version get a tiny 304 Not Modified instead of a re-download.

Device caching

The Flutter SDK is cache-first:

  • Warm start — a previously fetched flow renders instantly from the on-device cache, while a background request revalidates against the server for next time.
  • Cold start — the first fetch awaits the network, then caches the result.
  • Offline — network errors silently fall back to the cached copy; the user still gets onboarded. Only a cold start with no cache surfaces an error state.

You can inspect which path served a flow via result.source (network, cache, or cacheRevalidated), and force a fresh fetch with forceRefresh: true. SDK details →