> ## 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 several robots.

A fleet binds one model to a fixed set of registered robots and reserves capacity for the maximum
number that will run at once. Each robot keeps its own sensors, actuators, identity, and action
session.

## 1. Register every robot

Run `servo robot setup` on each robot computer with a distinct stable name:

```bash theme={null}
# robot computer A
servo robot setup yam-cell-01 \
  --config /opt/yam/configs/yam_left.yaml \
  --config /opt/yam/configs/yam_right.yaml \
  --region us-west-2 \
  --site sf-lab \
  --label line=assembly

# robot computer B
servo robot setup yam-cell-02 \
  --config /opt/yam/configs/yam_left.yaml \
  --config /opt/yam/configs/yam_right.yaml \
  --region us-west-2 \
  --site sf-lab \
  --label line=assembly
```

`--config` accepts the hardware configuration files on each robot computer. Servo hashes these files
to establish an immutable hardware revision fingerprint; it does not parse or upload either file.

Run `servo robot list` from any signed-in computer to review the names and `rob_*` IDs.

For a large fleet, install `servo-client` and set `SERVO_BASE_URL` and `SERVO_API_KEY` through your
normal machine-provisioning system. `servo robot setup` accepts the API key, so robot computers do
not need an interactive login.

## 2. Create the fleet

Run this once from any signed-in computer:

```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(fleet.id)
```

`peak_active` is the maximum number of robots that run concurrently. Servo derives request rate
from the robot and model contracts and manages hosted capacity.

For a larger inventory, select a snapshot by site and labels:

```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",
        }
    ],
)
```

Servo fixes fleet membership when it creates the fleet.

## 3. Run each robot locally

Provide the fleet ID to each robot process. You can pass it via an environment variable or look it up
with `sv.fleets.list()`. Run this code on the computer wired to each robot:

```python theme={null}
import os

import servo
from my_robot_app import open_yam

sv = servo.Servo(
    base_url=os.environ["SERVO_BASE_URL"],
    api_key=os.environ["SERVO_API_KEY"],
)
robot = sv.robots.attach("yam-cell-01", runtime=open_yam)

# Pass the fleet ID printed during deployment or set via environment variable:
fleet_id = os.environ.get("SERVO_FLEET_ID", "fleet_...")
fleet = sv.fleets.get(fleet_id)

policy = fleet.policy(
    robot,
    instruction="place the red lid on the black box",
)
robot.check(policy)
robot.run(policy, seconds=120)
```

The fleet ID selects shared hosted capacity. The stable robot name selects the physical rig and its
isolated action session. `fleet.policy()` checks the local sensors, requests on-demand capacity,
waits for the fleet, and routes the robot to the active model. The customer starts the local process
on each robot computer.

## Readiness modes

| Mode           | Start behavior                              |
| -------------- | ------------------------------------------- |
| `always_ready` | Keeps declared capacity warm                |
| `scheduled`    | Warms capacity before each operating window |
| `on_demand`    | Starts preparation when requested           |

`fleet.policy()` handles each mode. Its `timeout_s` parameter defaults to 30 minutes.

## Roll out a new pi0.5 checkpoint

Pass the new checkpoint identifier (starting with `ckpt_...`) produced by your fine-tuning or evaluation
pipeline:

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

`fleet.update_status` reports the current migration phase (`pending`, `preparing`, `ready`, or
`failed`). Servo prepares and warms the new checkpoint on hosted compute while the active release
continues to serve. Active sessions finish on their current release, and new sessions cut over once
the checkpoint is ready. Calling `fleet.rollback()` safely restores the previous healthy release
through the same non-disruptive process.
