Skip to main content
Preview environments are short-lived deploys with their own URL and their own preview-owned managed resources. Turn previews on, open a pull request, and floo deploys that branch to a preview URL. Agents can also create the same kind of sandbox from the CLI for a pushed remote branch. Push again, and the same preview updates in place. Delete the preview, close the PR, or let the TTL expire, and floo tears it down. The important part: a preview does not reuse floo-managed dev or prod Postgres credentials. When a preview has managed Postgres attached, floo creates a preview database branch for that preview.

Turn Previews On

Previews are off until you turn them on. There are two controls, and the per-PR one wins.

The app default, in floo.app.toml

Commit and push the config. The next pull request creates or refreshes a preview environment when GitHub sends the PR webhook. preview_ttl_hours controls how long an idle preview stays around, and defaults to 72. Closing or merging the PR tears it down earlier. A missing preview_environments key means previews are off, and preview_environments = false turns them back off for future PRs.
[preview] enabled and [preview] ttl_hours are deprecated aliases for these keys. They still work for one migration window and each deploy that uses them emits a legacy_preview_toml warning. Move the values into [github] and delete them from [preview]. [preview.data] is unaffected and remains the hydration surface.

The per-PR override, from a pull request comment

Comment on the pull request to override the app default for that one PR:
The platform deploys the preview within a normal deploy cycle. You do not need to push another commit. To turn a preview off for one PR when the app default is on:
The rules: This is the control to reach for when most PRs on a repo do not need a preview. Leave preview_environments = false and opt in the changes that want a live URL. It is also how you skip previews for a noisy PR when the app default is on. If the PR is already closed or merged when the command lands, floo tears the preview down instead of deploying one.

Create A Sandbox From The CLI

Use floo previews up when an agent needs an isolated sandbox for a feature branch before opening or relying on a pull request preview:
The command deploys GitHub source only. It never uploads local dirty files or an archive from your checkout, so push the branch or pass a remote ref before creating the sandbox. Useful lifecycle commands:
The preview argument can be the exact slug, a preview URL, the source branch, or #123 when that PR number resolves to one preview. Agents should use --json for stable output:
JSON output includes the app, preview slug, source_branch, deploy_id, status, URL, expiry, database_branches, and dev_prod_untouched: true. --wait exits non-zero when the deploy fails. Managed-resource isolation failures surface as PREVIEW_MANAGED_SERVICE_ISOLATION_UNAVAILABLE; fix the attached managed service state and retry after pushing a new commit or rerunning the command. Deleting a preview sandbox tears down only preview-owned Cloud Run services, managed resources, gateway routes, and env vars. Dev and prod resources are untouched.

Preview Database Branches

A preview database branch is preview-owned managed Postgres state. It is isolated from dev, prod, and other previews. Migrations, reviewer changes, and agent experiments land in that preview branch only. V1 preview database branches are branch-like isolation on floo’s managed-resource substrate. They are not raw production clones, arbitrary point-in-time clones, or provider-native copy-on-write branches. True provider-backed branching is tracked separately in getfloo/floo#733. Use the CLI to inspect the branch behind a preview:
The preview argument can be the preview slug, a preview URL, the source branch, or #123 when that PR number resolves to one preview. Use --json when an agent needs stable fields:
JSON includes the app, preview context, database_branches, source_environment, hydration_mode, resource_status, schema_name, reset eligibility, and expiry. It never includes plaintext database credentials.

Reset A Preview Branch

Reset drops and recreates only the selected preview database branch. Dev and prod are untouched.
In automation, confirm explicitly:
Preview reset is tier 2. It destroys preview-only data, but it does not touch durable dev or prod data. Dry-run shows the same scope without calling the API:
Reset works for ready preview-owned managed Postgres, Redis, and Storage branches. Use floo previews resources reset for the generic form:
Postgres reset drops and recreates the preview schema and role. Redis reset flushes only the preview Redis database. Storage reset deletes only live objects inside the preview bucket and keeps the bucket name and its STORAGE_BUCKET / STORAGE_URL values stable, so running preview revisions keep working. Each one then reapplies the preview data policy. Reset is blocked when the preview has no matching managed attachment, when the branch is not ready, when a deploy is in flight for that preview, or when the data belongs to dev, prod, or an external resource.

Choose Preview Data

Use [preview.data] to choose how a new preview branch starts.

Empty

empty is the default. floo creates a fresh preview database branch and copies no data.
Use this for apps that can boot from migrations alone.

Seed

seed runs your seed command once after migrations and before the preview is marked live.
The command runs in a preview-scoped one-off job with preview env vars. Pushing another commit to the same PR reuses the preview data unless you change the preview data policy.

Clone Dev

clone-dev copies dev data from every attached managed resource into its preview branch.
Use this when a reviewer needs realistic dev data but must be isolated from the actual dev resources. The Redis clone runs its preflight before flushing the preview database, so an unsupported key type or an oversized keyspace fails closed with the preview left as it was rather than emptied. Hydration runs at most once per policy. Pushing another commit to the same PR reuses the preview data instead of overwriting reviewer-created state. Change the policy and the next deploy hydrates again.

Unsupported Modes

These are deliberately not V1 behavior:
  • Raw prod clone.
  • Sanitized prod clone until the admin-gated runner exists.
  • Merging preview branch changes back into dev or prod.
  • Instant copy-on-write branches from arbitrary points in time. Storage copy is explicit object copy, not provider-native branching.
If a config asks for unsupported data behavior, floo fails closed instead of silently using dev or prod credentials.

Multi-Service Apps

Preview branches follow the same managed credential attachment rules as dev and prod. Attach managed Postgres only to the services that need it:
If no service declares managed, legacy apps receive managed credentials in every service. Once any service declares managed, omitted services receive none.

Troubleshooting