Quotas and Placement
Device quotas per project, priority classes, placement policies, and admission logic.
Quota is a ceiling on how many devices of one class a project may hold. Placement is the control plane’s choice of clusters for a workload and each cluster’s share of its scale. Together they decide where workloads land and whether they’re admitted.
Quotas
A quota sets a device limit per project and device class. You declare a quota with:
project: Which project this applies todevice_class: Which kind of device (e.g.,h100-80gb-sxm)scope:cluster(limit per cluster) orfleet(limit across all clusters)cluster_id: Required ifscope: clusterguaranteed_devices: The ceiling (how many devices this project may hold)floor_devices: Reserved minimum (recorded, not enforced yet)over_quota_weight: Priority when over the floor (recorded, not enforced yet)
Quota enforcement
When placement admits a deployment, it checks the project’s quota for the device class the workload needs:
- Count how many devices of that class the project currently holds (sum of all allocations).
- Add the devices this deployment would take.
- If the total exceeds
guaranteed_devices, refuse admission with reasoninsufficient_quota.
A refused deployment sits in pending phase until capacity frees up (another workload scales down or releases devices).
Cluster vs fleet quota
A cluster-scoped quota applies to one cluster only. If the project holds 16 H100s in iad-1 and the cluster quota is 16, the project can’t deploy more to iad-1 but can still use fra-1.
A fleet-wide quota applies across all clusters. If the fleet quota is 32 H100s and the project holds 16 in iad-1 and 16 in fra-1, it’s at the limit everywhere.
When both exist for the same project and device class, the cluster quota takes precedence in that cluster. Fleet quota is checked only if no cluster-specific quota exists.
Floor and over-quota weight
floor_devices and over_quota_weight are recorded but not enforced yet:
floor_devices: How many devices the project is guaranteed, reserved against other projects.over_quota_weight: When over the floor, priority for claiming additional capacity.
Today placement counts only free devices. A project’s floor doesn’t reserve capacity against others, and idle capacity isn’t shared out by weight. Both are on the roadmap.
Priority classes
A priority class is a named priority for workloads. Each class has:
name: Identifier (e.g.,high,standard,low)priority: Numeric value (higher wins)preemptible: Boolean, can this workload be evicted to make room
Every workload declares a priority_class. Placement records it, but doesn’t act on it yet: there’s no preemption, and priority doesn’t affect admission order. Both are on the roadmap.
When preemption is built, a high-priority workload will be able to evict a preemptible lower-priority one to claim its devices.
Placement
Placement is the control plane’s choice of clusters for a workload. It happens when you create a workload or scale it. Placement doesn’t pick devices; it picks clusters. The cluster’s own scheduler picks which cards.
Placement inputs
Placement considers:
- Device shape: What device class and how many devices the workload needs.
- Capacity: Which clusters have enough free devices of that class.
- Quota: Whether the project’s quota allows the allocation.
- Policy constraints: Region, residency, device class, allowed/denied clusters.
- Workload strategy:
pack(fill one cluster) orspread(distribute). - Cluster phase: Only
activeclusters are considered.
Placement flow
- Filter clusters by policy constraints (region, residency, allowed/denied lists).
- Check capacity in each cluster: does it have enough free
healthydevices of the needed class? - Check quota for the project and device class (cluster or fleet quota).
- Assign shares: Divide the workload’s total replica count across admitted clusters.
- Create deployments: One per chosen cluster, each with its share of
desired_replicas.
If no cluster passes all checks, the workload gets no deployments and you receive a verdict explaining why each cluster was rejected.
Pack vs spread
The default strategy is pack: fill one cluster before opening another. This minimizes cross-cluster routing and keeps workloads colocated.
If you declare strategy: spread, placement distributes replicas across clusters more evenly. Useful for fault tolerance or balancing load.
You can also set per-cluster floors (cluster_floors) to guarantee a minimum share in specific clusters, or cap the fan-out (max_clusters).
Pinning to a cluster
If you name a cluster when creating a workload, placement pins the entire workload to that cluster. It’s checked for existence but not for capacity. This is an override: you’re saying “run it here” and the scheduler obeys, even if the cluster is full.
A pinned workload has one deployment. If the cluster can’t admit it, the deployment stays pending with a reason.
Policies
A policy is a set of placement constraints you attach to a tenant, endpoint, workload, or cluster. Each policy can declare:
allowed_regions[]: Clusters must be in one of these regions.allowed_residencies[]: Clusters must have one of these residency labels.allowed_device_classes[]: Only devices of these classes may be used.allowed_clusters[]: Explicit allow-list of cluster names.denied_clusters[]: Explicit deny-list of cluster names.cost_ceiling: Maximum cost per hour (recorded, not enforced yet).
Policies are cumulative. If a policy is attached to a tenant and another to a workload in that tenant, both apply. A cluster must pass all constraints to be considered.
Attaching policies
Policies are attached via subject_type and subject_id:
{
"name": "us-only",
"allowed_regions": ["us-east", "us-west"],
"subject_type": "workload",
"subject_id": "wkl_01hq0v..."
}
When creating a workload, you can provide allowed_regions or allowed_clusters in the create request. The control plane auto-creates a policy named <workload>-placement and attaches it. This is a shortcut past POST /v1/policies.
The created policy is a real policy. You can read, edit, or delete it at GET /v1/policies?subject_type=workload&subject={ref}.
Admission phases
Each deployment moves through admission phases:
pending: Created, waiting for quota or capacity.admitted: Quota check passed, cluster has room.placed: Scheduler assigned devices, pods are being created.running: At least one replica is ready.
A deployment that can’t be admitted (insufficient quota, no free devices, policy constraints) stays in pending with a reason. Examples:
insufficient_quota: Project would exceed its quota.insufficient_capacity: Cluster has no free devices of the needed class.topology_constraint_not_met: Workload needs devices in one fabric; cluster has them scattered.policy_denied: Cluster is indenied_clustersor outsideallowed_regions.
Admission is per-cluster. A workload can be admitted in one cluster and pending in another.
Topology constraints
Some workloads need devices in a single topology domain (NVLink fabric, PCIe root, NUMA node). If a workload declares requires_single_topology_domain: true and optionally a topology_domain_kind: nvlink, placement only considers clusters where the needed device count fits inside one domain of that kind.
A cluster where the devices are scattered across multiple domains is rejected with topology_constraint_not_met.
Placement preview
Before creating a workload, you can dry-run placement via POST /v1/placement/preview. You provide either a workload ID or a device shape:
{
"project": "prj_...",
"shape": {
"device_class": "h100-80gb-sxm",
"device_count": 8
},
"replicas": 1
}
The response shows which clusters would be chosen, what shares each would get, and why any cluster was rejected. No state is written.
This answers “would this fit” before you commit. Use it in a create form to show a verdict panel.
Capacity checks
Placement counts only healthy and allocatable devices as capacity. A device is allocatable if:
- It’s
healthy(no throttling, no ECC errors). - It’s not allocated to a running replica.
- It’s not on a cordoned node.
An unhealthy device doesn’t count, even if it’s not allocated. A device allocated to a replica that’s terminating still counts as allocated until the allocation is removed.
Capacity is a snapshot at placement time. If a device goes unhealthy after a deployment is admitted, the deployment keeps running. Capacity checks only affect admission, not what’s already placed.
Re-placement and scaling
Scaling a workload re-runs placement. The control plane picks clusters again, divides the new replica count, and updates each deployment’s desired_replicas. If a cluster can’t admit the new share (quota or capacity), that deployment stays at its current count with a shortfall reported.
If you scale down, placement reduces shares proportionally. Deployments in multiple clusters each lose some replicas. The default is to rebalance across all clusters; you can pin shares with per-cluster floors.
A workload drained from one cluster (POST /v1/operations with type: workload.drain, payload: {"cluster": "clu_..."}) removes the deployment from that cluster and re-places the replicas elsewhere.