Managed Storage follows paygo spending restrictions: exhausted funds or a monthly hard limit block new spending, and a hard stop disables S3 keys.
Postgres and Storage hold persistent data. Declare Postgres, Redis, and Storage
with
[managed.<name>] blocks; a deploy provisions
what is missing.
Managed Redis is cache-only: treat its contents as disposable. floo makes no backup, restore, or durability guarantee for it; keep authoritative data in Postgres.
Auth holds no data of yours, so it is a property of the app rather than a
[managed] block. Turn it on with access_mode. The rest of this page covers
the lifecycle the three stateful services share.
Removing a deployed declaration is a tier-3 proposal. By default, the deploy
proceeds and the resource keeps working without a teardown schedule. An explicit
approval policy requires human review; approved Redis and Storage removals
receive a rescindable schedule. Postgres receives no schedule. Deploy does not delete data.
Completing deletion requires the explicit floo services remove
executor with confirmation for the exact resource.
Provision a service
Connection credentials never enter git or
floo.app.toml. floo synthesizes them at deploy time and injects them into the runtime environment. [managed.default] is the one service that receives the unsuffixed conventional keys. TOML block names are unique, so additional resources need names and receive suffixed keys. Only default Postgres receives the PG* component variables.
Operational provisioning for an existing app
floo services add is the operational lane for an app that already exists. It requires app context and is not the fresh-app workflow.
(app, type, name) already exists, the command reports the existing row instead of creating a duplicate. Prefer config declarations for normal desired-state authoring.
Attach credentials to services
Infloo.app.toml, put attachments under [services.NAME.env], including for single-service apps. The CLI rejects top-level [env] as an unknown key; the deploy parser ignores it with an unknown_manifest_key warning. Move [env] managed = [] under [services.NAME.env]. managed = [] opts that service out:
postgres gives DATABASE_URL plus PG*, redis gives REDIS_URL, and storage gives STORAGE_BUCKET plus the STORAGE_S3_* keys. Named services use type:name, such as postgres:analytics for DATABASE_URL_ANALYTICS. A named Postgres service receives only its suffixed URL, not the PG* component variables.
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 strips only 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
For a config-declared service, open a pull request that removes the matching[managed.<name>] block. floo preflight --json classifies it as to_deprovision, and the floo/infra-approval check follows the account’s effective approval policy, as described at the top of this page. Setting enabled = false makes the same removal proposal. Renaming a block proposes creation under the new name and removal of the old resource. Re-declaring a service cancels its scheduled teardown. No timer deletes data automatically.
Complete terminal deletion with floo services remove. For a CLI-added resource that was never declared in config, this is the direct deletion path.
--force.
Dev and prod isolation
Each service type isolates dev from prod differently. Read this before promoting to prod.
If your Storage service predates dev/prod Storage isolation and data separation matters, email team@getfloo.com. We can inspect the row and backfill a dedicated prod bucket. Redis needs no backfill: a legacy single-database Redis converges on its next prod preparation.
Preflight reconciliation
floo preflight shows the planner’s view of managed-service state:
to_provision: declared in config but no row exists. The next deploy creates it.to_retain: declared and present. Safe declared fields are reconciled.to_retry: declared and afailedrow exists. The next deploy retries the same row.to_deprovision: previously config-declared, now removed or disabled. This is tier-3. By default, the resource remains live without review or a schedule. An explicit policy requires review; approval schedules a rescindable teardown for Redis and Storage, but not Postgres. Deploy does not delete data.to_orphan: exists but was never config-declared, such as a CLI-added row. It remains live until explicitly removed.in_flight_deprovisioning: a terminal deletion is in progress and is excluded from retain/orphan classification.
to_deprovision separate from to_orphan preserves review history without inventing permission to destroy data.
Declare services in config ([managed.<name>])
<name> is a logical instance name, so you can declare more than one of a type, as in Provision a service. Removing a previously deployed block produces the to_deprovision flow above and never performs terminal deletion by itself. This replaces 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:
floo services add for each legacy service type declared in your app:
add provisions a missing resource. If the create endpoint returns a MANAGED_SERVICE_ALREADY_EXISTS 409, it resolves the existing row and reports it as already provisioned, with already_provisioned: true in JSON. Then replace the legacy sections with [managed.<name>] declarations in floo.app.toml.
After the sunset date, the parser will ignore the legacy sections entirely. Apps that haven’t migrated keep their managed services (floo services list shows them); only the authoring surface changes.
Usage metering
Managed Postgres compute and storage, managed Redis usage, file storage, and the CPU and memory your services use are metered. Postgres compute is billed for every database that runs, including dev and preview databases, not only prod. Overwritten and deleted object versions are kept for 30 days and count toward stored bytes. Rates and plans are on getfloo.com/pricing.Postgres
Connection values, pgvector, and preview database branches.
Storage
Read and write objects, and serve them through your app.
Cron jobs
Schedule recurring tasks inside your app’s containers.