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

# Robot Fleets

> Share managed model capacity across multiple robots with automatic scaling.

A fleet pools hosted model capacity across a cluster of robots, automatically scaling GPU compute based on the maximum number of robots active simultaneously (`peak_active`).

Each robot runs `servo daemon` locally and connects its sensors and motor controllers directly to the shared fleet.

> **Preview.** The `servo.connect` API is currently in developer preview and not yet shipped in general availability. Early feedback and testing are welcome. Code samples on this page import `connect`/`camera` explicitly from `servo.universal` — they don't yet resolve as `servo.connect` etc.

***

## 1. Assign stable robot identities

To connect a robot to a fleet, assign it a stable name (and optional site/labels) in `servo.connect()`:

```python theme={null}
from servo.universal import connect

session = connect(
    "allenai/MolmoAct2-BimanualYAM",
    robot="yam-cell-01",
    region="us-west-2",
    site="sf-lab",
    labels={"line": "assembly"},
    observe={...},
    act=...,
)
```

The first connection with a given name registers the robot in your organization; subsequent connections attach to that existing record. Registration derives a configuration digest from the robot's actual bound `observe`/`act` sources, so there's no CLI equivalent to pre-register a name before hardware and a driver exist — `connect(robot=...)` is the only registration path today.

List registered robots in your organization with:

```bash theme={null}
servo robot list
```

***

## 2. Deploy shared fleet capacity

From your central management script or developer machine, provision shared GPU capacity for your fleet:

```python theme={null}
import os
import servo

sv = servo.Servo(
    base_url=os.environ["SERVO_BASE_URL"],
    api_key=os.environ["SERVO_API_KEY"],
)
model = sv.models.get("pi0.5")

fleet = sv.fleets.deploy(
    model,
    robots=["yam-cell-01", "yam-cell-02"],
    name="yam-assembly",
    peak_active=2,
    readiness="always_ready",
)

print(f"Fleet deployed: {fleet.id}")
```

`peak_active` defines the maximum number of robots that run concurrently. Servo automatically manages GPU provisioning to guarantee 30 Hz control loop latency for all active sessions.

For larger deployments, you can dynamically select robots using site and label selectors:

```python theme={null}
fleet = sv.fleets.deploy(
    model,
    selector={"site": "sf-lab", "labels": {"line": "assembly"}},
    name="yam-assembly",
    peak_active=40,
    readiness="scheduled",
    schedule=[
        {
            "starts_at": "2026-09-03T06:00:00-07:00",
            "ends_at": "2026-09-03T14:00:00-07:00",
        }
    ],
)
```

### Readiness modes

| Mode           | Behavior                                                              |
| -------------- | --------------------------------------------------------------------- |
| `always_ready` | Keeps GPU capacity warm in the cloud for zero-latency rollout starts. |
| `scheduled`    | Automatically warms GPU instances before scheduled operating shifts.  |
| `on_demand`    | Provisions GPU capacity when robots initiate rollouts.                |

***

## 3. Run each robot locally

On each robot computer, install the Servo daemon as a supervised system service (which provides automatic restarts on reboot or failure):

```bash theme={null}
servo daemon --install-service
```

Run zero-motion preflight verification:

```bash theme={null}
servo check-rig rig.py
```

In `rig.py`, point `servo.connect` to your fleet name instead of a single standalone model:

```python theme={null}
from servo.universal import camera, connect
from my_robot import BimanualYam

arm = BimanualYam()

session = connect(
    fleet="yam-assembly",
    robot="yam-cell-01",
    region="us-west-2",
    observe={
        "top": camera(serial="250423122040"),
        "left": camera(serial="402323071792"),
        "right": camera(serial="402323071794"),
        "state": arm.get_joint_positions,
    },
    act=arm.apply_joint_targets,
)

# For automated cells, listen for remote start commands:
session.listen()
```

***

## 4. Roll out model updates without downtime

When a newly trained or fine-tuned checkpoint (`ckpt_...`) is ready, update the fleet without disrupting active robot operations:

```python theme={null}
fleet.update("ckpt_20260904_pi05_dexterity")
print(fleet.update_status)
```

* **Zero-Downtime Cutover**: Active episodes finish uninterrupted on the current release. Once the new model checkpoint is warm and verified, subsequent rollouts automatically route to it.
* **Instant Rollback**: If an issue occurs with a new checkpoint, call `fleet.rollback()` at any time to immediately revert to the prior healthy version:
  ```python theme={null}
  fleet.rollback()
  ```
