floo services remove — never a side effect of editing or deleting config. You can provision either imperatively with floo services add (below) or declaratively with [managed.<name>] blocks in floo.app.toml; a deploy provisions anything declared-but-missing, but never destroys.
Provision a service
Usefloo services add for any managed service. The command is idempotent on (app, type, name), so re-running it is safe.
- Provisions the underlying resource (a Postgres schema + role on the shared instance, an Upstash Redis database, or a GCS bucket).
- Synthesizes the matching env vars and injects them into your app’s environment scope.
- Writes
.floo/services.lock— commit it alongside other changes.
Connection credentials are never stored in
floo.app.toml or .floo/services.lock. They’re synthesized at deploy time and injected directly into the runtime environment. Postgres DATABASE_URL is a standard PostgreSQL URI that mainstream frameworks can parse directly; the PG* vars expose the same default connection as separate fields for tools that prefer them.
Attach Credentials To Services
For single-service apps, managed credentials go to the only runtime service unless top-level[env] managed = [] opts out. For multi-service apps, put the attachment next to the service that needs it:
postgres gives DATABASE_URL plus PG*, redis gives REDIS_URL, and storage gives STORAGE_BUCKET plus STORAGE_URL. Named services use type:name, such as postgres:analytics for DATABASE_URL_ANALYTICS.
If no service declares managed, floo keeps legacy all-service injection. Once any service declares it, services without managed receive no managed-service credentials. floo only strips keys owned by managed-service records, so an external user-managed DATABASE_URL is not swept up by this filter. floo preflight --json shows the exact per-service plan in env_injection_plan.
Inspect
Remove
floo services remove is the only path that destroys managed-service data. Deploy never destroys, regardless of what’s in floo.app.toml.
--force.
The lock file
Everyadd, remove, and migrate updates .floo/services.lock atomically. The file is auto-generated, committed to the repo, and never hand-edited. It’s a record of state, not a source — the platform DB is authoritative. Same model as package-lock.json or Cargo.lock.
floo services command re-syncs the file from platform truth.
Dev and prod isolation
Each service type isolates dev from prod differently. Read this before promoting to prod.
If your app was created before Redis or Storage dev/prod isolation landed and data separation matters, email team@getfloo.com. We can inspect the row and backfill dedicated prod resources when needed.
Preview Database Branches
Preview environments get their own managed resources too. For managed Postgres, the preview-owned resource is called a preview database branch. It is isolated from dev, prod, and other previews, and it is the branch the preview app uses for migrations and runtime writes. Inspect branches from the CLI:dev_prod_untouched, but never plaintext credentials.
V1 supports empty preview branches, seeded preview branches, and clone-dev for every attached managed Postgres, Redis, and Storage resource. It does not support raw prod clone, sanitized prod clone, or provider-native copy-on-write branching; Storage copy is explicit object copy. See Preview Environments for the full contract.
Preflight reconciliation
floo preflight shows the planner’s view of managed-service state across five bins:
to_provision— declared (via CLI or legacy TOML) but no row exists. Will be created on the next deploy orfloo services add.to_retain— declared and exists. No-op.to_retry— declared and afailedrow exists. The next deploy retries provisioning into the same row.to_orphan— exists, not declared anywhere. Will NOT be deprovisioned. Surfaced as a non-blocking warning telling you to runfloo services removeif you actually want destruction.in_flight_deprovisioning— adeprovisioningrow is mid-flight. Excluded fromto_retain/to_orphanuntil it completes.
remove.
Declare services in config ([managed.<name>])
If you’d rather keep managed-service intent in floo.app.toml alongside the rest of your app shape, declare each one as a [managed.<name>] block. <name> is a logical instance name, so you can declare more than one of a type:
floo preflight, and you destroy it explicitly with floo services remove. This is the modern replacement for the legacy top-level [postgres] / [redis] / [storage] sections below. Full field reference: config spec.
Legacy TOML sections (deprecated)
Earlier versions of floo accepted[postgres], [redis], and [storage] top-level sections in floo.app.toml as a declarative shortcut:
migrate is idempotent and has zero data impact — it records the existing managed-service rows in .floo/services.lock and prints instructions to remove the legacy TOML sections. After migration, your authoring surface is the CLI alone; the underlying managed services are untouched.
After the sunset date, the parser will ignore the legacy sections entirely. Apps that haven’t migrated keep their managed services (the CLI sees them via floo services list); only the authoring surface changes.
Capacity
Every managed Postgres service ships with the same defaults — there are no self-serve tiers to choose between:
The
--tier flag on floo services add postgres is accepted for backwards-compatibility but ignored — every value maps to the same defaults.
Redis uses Upstash. Storage uses GCS buckets. Neither has tier choices.
Redis health and capacity
Upstash meters Redis commands and can reject data-plane traffic when a database reaches a request-rate limit, daily allowance, or account budget cap. A TCP connection or RedisPING does not prove application commands are available.
floo runs one billed EVAL canary command per ready Redis database every
minute. Its Lua script writes a random token under a reserved key, reads it
back, and sets a two-minute expiry atomically. It never reads, lists, overwrites,
or deletes a customer key. This adds 43,200 billed commands per database in a
30-day month. Upstash currently includes 500,000 monthly commands on its
free database allowance, so the canary uses 8.64% of that allowance before
application traffic. Provider limits and prices can change. See
Upstash pricing for the current provider
contract.
Run the doctor when Redis work or cron coordination fails:
throttle_request_rate means requests are arriving faster than the database
allows. Reduce request concurrency or batch commands, then contact
team@getfloo.com
to raise managed throughput.
throttle_daily_limit means the database exhausted its daily or monthly command
allowance. Reduce command volume, then contact
team@getfloo.com
for paid capacity. throttle_temporary is provider-imposed throttling without
a more specific published reason. Retry later and contact the same address if
it persists.
Authentication, permission, configuration, missing, or stale-canary failures
need floo intervention. The doctor gives the matching action. Its output never
contains credentials or raw provider responses.
Need more than 25 connections? Email team@getfloo.com — for sustained higher concurrency we provision dedicated Postgres instances rather than a self-serve performance tier.
Connection usage
floo tracks live Postgres connection usage and warns you before you hit the limit:- Dashboard — the managed-Postgres panel shows
N / 25 connections in useand surfaces a warning when you cross 75%. - CLI —
floo db connections --app my-app [--env dev|prod]prints the same data, with a--jsonmode for agents. - Email — the org owners and admins get an email at 75% sustained, with a one-click
mailto:team@getfloo.comfor capacity requests. One email per app per 24h max.
Usage metering
Your plan includes compute credits — 5 lifetime (Free), 5 / month (Hobby), 20 / month (Pro), 200 / month (Team) — and one credit equals $1 of metered app usage. Usage beyond your credits is billed as overage up to your spend cap.
Databases
Code examples and debugging for Postgres and Redis.
Cloud Storage
Upload, download, and signed URL patterns.
Cron Jobs
Schedule recurring tasks inside your app’s containers.