Device Groups
Segment your device fleet into targetable cohorts. Groups let you scope rollouts, experiments, and training to specific platforms, regions, or hardware capabilities instead of deploying to everything at once.
When to use
- Rolling out a model to iOS devices before Android
- Running an A/B test on a staging cohort before production
- Restricting federated training to devices with 8GB+ RAM
- Isolating a region for compliance or latency reasons
Quick start
- CLI
- Python
- cURL
octomil group create ios-17-plus \
--mode dynamic \
--rule "platform eq ios" \
--rule "os_version gte 17.0"
Group created: grp_x7y8z9
Name: ios-17-plus
Mode: dynamic
Rules: platform eq ios, os_version gte 17.0
Matched devices: 87
from octomil import OctomilClient
client = OctomilClient(api_key="edg_...")
group = client.device_groups.create(
name="ios-17-plus",
mode="dynamic",
rules=[
{"field": "platform", "operator": "eq", "value": "ios"},
{"field": "os_version", "operator": "gte", "value": "17.0"},
],
)
print(f"Group {group.id}: {group.matched_count} devices")
curl -X POST https://api.octomil.com/v1/device-groups \
-H "Authorization: Bearer edg_..." \
-H "Content-Type: application/json" \
-d '{
"name": "ios-17-plus",
"mode": "dynamic",
"rules": [
{"field": "platform", "operator": "eq", "value": "ios"},
{"field": "os_version", "operator": "gte", "value": "17.0"}
]
}'
Group modes
| Mode | Membership | Best for |
|---|---|---|
static | Manually add/remove devices | Hand-picked staging fleet, QA devices |
dynamic | Auto-assigned by rules on heartbeat | Platform/region/capability targeting |
hybrid | Rules + manual overrides | Dynamic base with manual exceptions |
Rule fields
| Field | Operators | Example |
|---|---|---|
platform | eq, neq, in | platform eq ios |
os_version | eq, gte, lte, gt, lt | os_version gte 17.0 |
locale | eq, in | locale in en_US,en_GB |
region | eq, in | region eq us-east-1 |
manufacturer | eq, in | manufacturer eq Apple |
model | eq, in | model in iPhone15,4,iPhone16,2 |
sdk_version | eq, gte, lte | sdk_version gte 2.0.0 |
app_version | eq, gte, lte | app_version gte 3.1.0 |
ram_gb | gte, lte, gt, lt | ram_gb gte 8 |
gpu_available | eq | gpu_available eq true |
npu_available | eq | npu_available eq true |
Rules are ANDed — a device must match all rules to join the group.
Using groups in rollouts
- CLI
- Python
- cURL
octomil deploy radiology-v1 --version 2.0.0 --rollout 10% --group ios-17-plus
rollout = client.rollouts.create(
model_id="radiology-v1",
version="2.0.0",
rollout_percentage=10,
target_percentage=100,
increment_step=10,
group="ios-17-plus",
)
curl -X POST https://api.octomil.com/v1/models/radiology-v1/rollouts \
-H "Authorization: Bearer edg_..." \
-H "Content-Type: application/json" \
-d '{
"version": "2.0.0",
"rollout_percentage": 10,
"target_percentage": 100,
"increment_step": 10,
"group": "ios-17-plus"
}'
Using groups in experiments
octomil experiment create staging-test \
--model radiology-v1 \
--control 1.0.0 \
--treatment 2.0.0 \
--traffic-split 50 \
--group staging-devices
Managing groups
- CLI
- Python
# List groups
octomil group list
# View group details and membership count
octomil group status ios-17-plus
# Add devices to a static/hybrid group
octomil group add ios-17-plus --devices device-abc,device-def
# Remove devices
octomil group remove ios-17-plus --devices device-abc
# Delete a group
octomil group delete ios-17-plus
# List groups
groups = client.device_groups.list()
# View group
group = client.device_groups.get("ios-17-plus")
print(f"Members: {group.matched_count}")
# Add devices (static/hybrid only)
client.device_groups.add_devices("ios-17-plus", ["device-abc", "device-def"])
# Remove devices
client.device_groups.remove_devices("ios-17-plus", ["device-abc"])
# Delete
client.device_groups.delete("ios-17-plus")
Group cards in dashboard
Group cards in the dashboard show:
- Membership count — total devices in the group
- Active rollouts — rollouts scoped to this group
- Active experiments — experiments targeting this group
- Model coverage — which model versions are deployed to group members
Filter groups by active rollouts or experiments to isolate affected cohorts.
Gotchas
- Dynamic membership updates on heartbeat — devices join/leave dynamic groups when they heartbeat. If a device hasn't checked in recently, its group membership may be stale.
- Rules are ANDed, not ORed — all rules must match. To target "iOS OR Android 14+", create two groups and use both in your rollout.
- Deleting a group doesn't affect rollouts — if a rollout targets a group you delete, the rollout continues for devices already assigned. New devices won't be added.
- Static groups have no auto-discovery — devices must be added manually. Use
dynamicorhybridif you want new devices to be automatically included. - Group names are unique per workspace — you can't have two groups with the same name.
Related
- Rollouts — target rollouts to specific groups
- Experiments — A/B test within a device cohort
- Monitoring — fleet readiness per group