Skip to main content
Declare Postgres in floo.app.toml; the next deploy provisions it and injects the connection values. Managed services covers the shared lifecycle: declaring, attaching credentials, and removal.
floo.app.toml

What gets injected

Default Postgres provides DATABASE_URL plus PGHOST, PGPORT, PGDATABASE, PGUSER, and PGPASSWORD. DATABASE_URL is a direct TLS PostgreSQL URI ending in ?sslmode=require (postgresql://user:password@host:port/database?sslmode=require), so Rails and Active Record, Django, SQLAlchemy, Prisma, pg, and libpq consume it directly. The PG* variables are for libraries that prefer separate connection parameters. Dev and prod use separate databases with separate credentials. Each database, including dev and every preview, runs its own compute, and all of it is billed as Postgres usage.

Compute and limits

Reuse connections with a pool and avoid N+1 queries. There are no floo connection or statement-timeout tiers. The --tier flag is ignored.

Vector search with pgvector

Managed Postgres supports pgvector, off by default. Enable it in your first migration:
After the migration runs, the vector type resolves unqualified:
Framework migrations use the bare type name too: Rails t.vector :embedding, limit: 1536 (or the neighbor gem), Django, pgvector.sqlalchemy, and Prisma all work without a schema prefix.

Schema portability across dev and prod

Both environments use the app database, the app role, and the standard public schema. floo db schema reports public; there is no custom search_path, so migrations and queries use unqualified table names. config.active_record.schema_format = :sql produces a structure.sql for the same public schema in both environments. Push deploys, CLI promotion, and GitHub-release promotion run each declared migrate_command before shifting traffic to the new revisions. A failed migration fails the deploy and leaves the previous live revision serving. Old code serves the migrated schema until cutover. If a later rollout step fails, it keeps serving that schema, so migrations must remain compatible with the previous code. A failed migration can also leave partial changes; floo does not reverse database writes. Use expand-then-contract migrations:
  1. Expand: add nullable columns or new tables while preserving the schema the serving code uses. Keep both old and new code compatible with this schema.
  2. Backfill: populate the new fields, keeping old and new representations in sync while writes continue; deploy code that can read both during the transition.
  3. Contract later: remove or rename old fields in a later release, only after backfill is complete and no serving code or intended rollback version depends on them.

Backups

Managed Postgres keeps change history. The CLI has no backup or restore command; support handles restores on request.

Preview database branches

Each preview with managed Postgres gets its own database branch. Migrations and writes there are isolated from dev, prod, and other previews.
Set mode in [preview.data] to empty, seed, or clone-dev to choose how a preview branch starts; see Preview environments.

Debug a connection issue

Check that the service needing data has env.managed including the Postgres handle, that DATABASE_URL and PGHOST appear in floo env list, and that the app reads env vars rather than a hard-coded local connection string.

Managed services

The shared lifecycle: declare, attach, inspect, remove.

Redis

Cache and queue instances, and how handles map to databases.