> ## Documentation Index
> Fetch the complete documentation index at: https://getfloo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# services

> CLI reference: floo services — provision, inspect, and remove managed services on a floo app

`floo services` is the canonical surface for managed services (Postgres, Redis, Storage) and the place to inspect any service — managed or application — running in your app.

Managed services hold persistent state, so floo makes **destruction explicit**: removing a managed service is always a `floo services remove` command, never a side effect of editing config. You can *provision* with `floo services add` here, or declaratively with [`[managed.<name>]`](/docs/reference/config-spec) blocks — either way a deploy creates what's declared-but-missing and never destroys. Every `floo services` mutation updates an auto-generated `.floo/services.lock` file that's committed to your repo as a record of stateful changes.

<Note>
  The legacy `[postgres]`, `[redis]`, `[storage]` sections in `floo.app.toml` still auto-provision on first deploy during the deprecation window, and emit a warning telling you to run `floo services migrate`. Once migrated, those sections can be removed. See [Managed Services](/docs/guides/managed-services) for the full transition story.
</Note>

## list

List all services for an app — both application services (`web`, `api`, `worker`) and managed services (`postgres`, `redis`, `storage`).

```bash theme={null}
floo services list --app my-app
floo services list --app my-app --env prod
```

### Flags

| Flag        | Description                           | Default              |
| ----------- | ------------------------------------- | -------------------- |
| `--app APP` | App name or UUID                      | inferred from config |
| `--env ENV` | Environment to query: `dev` or `prod` | `dev`                |

### JSON output

```json theme={null}
{
  "success": true,
  "data": {
    "app_services": [
      {
        "id": "2d2895fc-0fc7-45d7-a18f-7c8795f76835",
        "name": "web",
        "type": "web",
        "port": 3000,
        "status": "running",
        "ingress": "public",
        "cloud_run_url": "https://my-app-web-abc123.run.app",
        "cpu": "2",
        "memory": "1Gi",
        "max_instances": 10,
        "min_instances": 1,
        "max_request_body_mb": 32
      }
    ],
    "managed_services": [
      {
        "id": "7b0890a0-0f53-46e4-b4e7-04fda184cd66",
        "app_id": "fb6e7446-2d02-4307-b05e-b00120620da5",
        "name": "default",
        "type": "postgres",
        "status": "ready",
        "env_var_keys": ["DATABASE_URL"]
      }
    ]
  }
}
```

Application-service resource fields preserve the values returned by the platform API. A `null` value means the resource was not explicitly configured. The CLI does not substitute platform defaults.

***

## show

Show details for one service. Branches automatically: managed services return status and injected env-var keys; application services return port, URL, ingress, and configured CPU, memory, scaling, and request-body limits. You don't need to know which type a name maps to.

```bash theme={null}
floo services show web --app my-app
floo services show default --app my-app    # the default postgres row
```

### Flags

| Flag        | Description      |
| ----------- | ---------------- |
| `--app APP` | App name or UUID |

Connection credentials are never returned by `show` in plaintext. Read `DATABASE_URL` / `REDIS_URL` / `STORAGE_BUCKET` via `floo env get` when you need the value.

***

## add

Provision a new managed service. Idempotent on `(app, type, name)` — running the same command twice returns the existing row, not an error.

```bash theme={null}
floo services add postgres --app my-app
floo services add redis --app my-app
floo services add storage --app my-app
```

### Arguments

| Argument | Description                                      |
| -------- | ------------------------------------------------ |
| `<type>` | Service type: `postgres`, `redis`, or `storage`. |

### Flags

| Flag          | Description                                                                                                                                                                                                                                                                                                                             | Default              |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `--app APP`   | App name or UUID                                                                                                                                                                                                                                                                                                                        | inferred from config |
| `--tier TIER` | **Deprecated.** Accepted for backwards-compatibility but ignored — every managed Postgres service now ships with the same defaults (25 connections, 60s statement timeout, 128 MB `work_mem`). For sustained higher concurrency, email [team@getfloo.com](mailto:team@getfloo.com?subject=Capacity%20request) for a dedicated instance. | `default`            |
| `--name NAME` | Logical name for this service row (lowercase, alphanumeric + underscores). Useful when you want more than one of the same type.                                                                                                                                                                                                         | `default`            |

### What it does

1. Calls `POST /v1/apps/{app_id}/managed-services` to provision the underlying resource (Postgres schema + role on the shared instance, Upstash Redis database, or GCS bucket).
2. Synthesizes the corresponding env var(s) — Postgres gets `DATABASE_URL` + `PG*`, Redis gets `REDIS_URL`, Storage gets `STORAGE_BUCKET` + `STORAGE_URL` — and injects them into your app's environment scope.
3. Updates `.floo/services.lock` atomically. Commit the lock file alongside your other changes.

For multi-service apps, runtime injection is controlled by `[services.<name>.env] managed = [...]`. Run `floo preflight --json` to see the exact `env_injection_plan`.

For Postgres, both dev and prod credentials are provisioned up front. Promote does not need to re-provision.

Preview environments use separate preview-owned managed resources. For managed Postgres, inspect or reset those preview database branches with [`floo db branches`](/docs/cli/database#branches-list).

***

## remove

**Permanently destroy a managed service and its data.** This is a tier-3 destructive operation: it drops the Postgres schemas / deletes the Redis databases / deletes the GCS buckets for the service.

```bash theme={null}
# Interactive: type the service name to confirm
floo services remove postgres --app my-app

# Non-interactive (CI, agents): explicit verbose flag
floo services remove postgres --app my-app --yes-i-know-this-destroys-data
```

### Arguments

| Argument | Description                                      |
| -------- | ------------------------------------------------ |
| `<type>` | Service type: `postgres`, `redis`, or `storage`. |

### Flags

| Flag                              | Description                                                                                                                                          | Default              |
| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `--app APP`                       | App name or UUID                                                                                                                                     | inferred from config |
| `--name NAME`                     | Service row name.                                                                                                                                    | `default`            |
| `--yes-i-know-this-destroys-data` | Skip interactive confirmation. Required in non-interactive contexts. Deliberately verbose because destroying user data must be an explicit decision. | off                  |

There is **no `--yes` or `--force`**. The flag name is not a bug.

`floo services remove` is the only path that destroys managed-service data. **Deploy never destroys.** Removing a `[postgres]` section from `floo.app.toml` and pushing leaves the service running and surfaces a `to_orphan` warning in `floo preflight`.

***

## migrate

One-shot conversion from the legacy `[postgres]` / `[redis]` / `[storage]` TOML sections to CLI-managed state. Idempotent — running it on an already-migrated app is a no-op. **Zero data impact**: the underlying managed-service rows already exist; migrate only changes how they're authored going forward.

```bash theme={null}
floo services migrate --app my-app
```

### Arguments

| Argument | Description                                  | Default |
| -------- | -------------------------------------------- | ------- |
| `PATH`   | Project directory containing `floo.app.toml` | `.`     |

### Flags

| Flag        | Description      |
| ----------- | ---------------- |
| `--app APP` | App name or UUID |

### What it does

1. Reads each `[postgres]` / `[redis]` / `[storage]` section from `floo.app.toml`.
2. Calls `floo services add` for each (idempotent — existing rows are recorded, not re-created).
3. Writes `.floo/services.lock`.
4. Prints instructions to delete the legacy TOML sections so the deprecation warning stops firing on every deploy.

***

## The lock file

Every successful `add`, `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`.

```json theme={null}
{
  "version": 1,
  "managed_services": [
    {
      "type": "postgres",
      "name": "default",
      "tier": "basic",
      "created_at": "2026-04-24T15:00:00Z"
    }
  ]
}
```

Hand-editing the lock file does nothing. Running any `floo services` command re-syncs it from platform truth.

***

## Errors

| Code                             | Meaning                                                                                                                                      |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `NOT_AUTHENTICATED`              | Run `floo auth login` first                                                                                                                  |
| `SERVICE_NOT_FOUND`              | No service with that name exists on the app                                                                                                  |
| `MANAGED_SERVICE_NOT_FOUND`      | No managed service of that type/name exists (raised by `remove`)                                                                             |
| `MANAGED_SERVICE_ALREADY_EXISTS` | Cannot create a duplicate (would never happen via `add`, which is idempotent — surfaces if you call the API directly with conflicting state) |
| `INVALID_TIER`                   | Tier value is not `basic`, `standard`, or `performance`                                                                                      |

## Related

* [Managed Services](/docs/guides/managed-services) — full lifecycle: lock file, deprecation, dev/prod isolation per service type.
* [`floo preflight`](/docs/cli/preflight) — see which managed services are `to_provision`, `to_retain`, `to_orphan`, or in flight.
* [`floo db`](/docs/cli/database) — query and migrate the managed Postgres database directly.
* [Preview Environments](/docs/guides/preview-environments) — preview database branches and supported data modes.
