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

# Node Pools

> Manage groups of Nodes as a single entity with Node Pools

This page explains how CKS uses Node Pools to manage groups of Nodes as a single entity. Read this to understand the relationship between instances, Nodes, and Node Pools before you create or scale a Node Pool, and to learn how CKS handles cordoning, scale-down, image pulls, and reboots.

Instances are specific hardware configurations defined by CoreWeave, and each [GPU](/platform/instances/gpu-instances) and [CPU](/platform/instances/cpu-instances) instance type has its own [hourly price](https://www.coreweave.com/pricing).

A Node Pool in CKS represents one or more instances that share a common configuration, such as the same labels, taints, and annotations. To configure a Node Pool, select the instance type to use and how many of that instance type you want to run for your cluster. Deploy a Node Pool either [with a Kubernetes manifest](/products/cks/nodes/create#create-a-node-pool-using-kubernetes) or [from the Cloud Console](/products/cks/nodes/create#create-a-node-pool-using-the-cloud-console).

Once a Node Pool is deployed to a cluster, CKS continuously monitors it to ensure that the number of running Nodes matches the number specified in the Node Pool's manifest.

You can deploy multiple Node Pools within a single cluster, where each Node Pool contains any number of Nodes. This lets you run different types of workloads on different types of Nodes, or scale different parts of your application independently.

<Info>
  View pricing for instance types on [CoreWeave's pricing page](https://www.coreweave.com/pricing).
</Info>

## Availability

Node Pools are available in all [General Access Regions](/platform/regions/about-regions-and-azs).

## Sizing your Node Pools

Because you can run multiple Node Pools in a single cluster, you decide how to divide your Nodes among them. There is no single correct layout. The right structure depends on how many distinct workloads you run, how you want to scale them, and how much management overhead you can absorb. Use the trade-offs and recommendations in this section to plan a layout, then [create](/products/cks/nodes/create) and [autoscale](/products/cks/nodes/autoscaling) your Node Pools to match.

A Node Pool maps to Nodes through its target. For most instance types, `spec.targetNodes` sets the number of Nodes CKS provisions and keeps running. For [rack-based instance types](/products/cks/nodes/create#rack-based-node-pools) such as GB200 and GB300, `spec.targetRacks` sets the number of racks, and each rack contains 18 Nodes. Every Node in a Node Pool shares that pool's instance type, labels, taints, and annotations, so a Node Pool is the unit where you set Node configuration and capacity together.

### Recommendations by workload type

Use these recommendations as a starting point, then adjust based on how your workloads schedule and scale.

* **A single large training job**: Use one Node Pool sized to the job. Training jobs run across many Nodes of the same instance type, so a single pool matches the workload and keeps management simple. Set the [scaling strategy](#scaling-strategies) to `IdleOnly` so that lowering `targetNodes` doesn't remove Nodes that are still running the job. The Cluster Autoscaler ignores the scaling strategy, so if the pool autoscales, also [prevent Node removal](/products/cks/nodes/autoscaling#prevent-pod-eviction-or-node-removal) with an annotation. Consider [Node Pool prefill](#node-pool-prefill) to avoid a capacity gap if a Node is replaced mid-run.

* **Multiple independent inference endpoints**: Use a separate Node Pool per endpoint, or per group of endpoints with the same instance type and scaling needs. Separate pools let you scale each endpoint independently in response to its own demand and isolate one endpoint's Nodes from another's. The `PreferIdle` strategy scales these pools down faster when demand drops. See [Autoscale Node Pools](/products/cks/nodes/autoscaling) for how the autoscaler selects a pool based on a Pod's `nodeSelector` and `affinity`.

* **Mixed instance types**: Use one Node Pool per instance type. Because every Node in a pool shares one instance type, you need a distinct pool for each GPU or CPU type your workloads require.

* **Bursty or intermittent workloads**: Put these workloads in their own Node Pool and configure [scale-to-zero](/products/cks/nodes/autoscaling#scale-to-zero) so the pool drops to zero Nodes when there's no demand.

### Node Pool sizing considerations

The following table summarizes the trade-offs between consolidating Nodes into fewer, larger Node Pools and splitting them across more, smaller Node Pools.

| Consideration | Fewer, larger pools | More, smaller pools |
| - | - | - |
| **Management** | Simpler. Fewer manifests to maintain and fewer pools to monitor and scale. | More overhead. Each pool is a separate manifest with its own labels, taints, and scaling settings to maintain and monitor. |
| **Workload matching** | Harder to match heterogeneous workloads, because every Node in a pool shares the same instance type and configuration. | Easier. Each pool can target a different instance type and configuration for a specific workload. |
| **Scaling control** | Coarser. [Autoscaling](/products/cks/nodes/autoscaling) is available at any pool size, but a single pool scales as a unit between `minNodes` and `maxNodes`. | Finer. You can set independent `minNodes`, `maxNodes`, and [scaling strategy](#scaling-strategies) per workload. |
| **Isolation** | Lower. Workloads share Nodes and the pool's configuration, so a configuration change or a disruptive Node affects more workloads. | Higher. A change or a disruptive Node is contained within one pool, isolating its effect on other workloads. |

In short, fewer large Node Pools reduce management overhead at the cost of increased impact scope and less flexibility, while more smaller Node Pools give you workload isolation and finer scaling control at the cost of more pools to manage.

## Node cordoning

CKS sometimes cordons Nodes to ensure that workloads are only scheduled to healthy Nodes. In most cases, CKS eventually removes the cordon, which makes the Node schedulable again. CoreWeave manages this kind of Node cordoning entirely, though you can also manually cordon Nodes for your own reasons.

<Note>
  CoreWeave-managed Node conditions, labels, states, and events can change without notice. Don't use them for your own automation or change them except through documented procedures, such as [cordoning a Node yourself](/products/cks/nodes/cordon#cordon-a-node-yourself) or [requesting a Node reboot](/products/cks/nodes/reboot#request-a-node-reboot). You can still add your own custom Node conditions and labels.
</Note>

A Node may be cordoned for several reasons, such as:

* **Maintenance**: If a Node requires maintenance, updates, or hardware fixes, CKS cordons it to ensure no new workloads are placed on it during that time. This lets CoreWeave's [Node lifecycle automation](/platform/fleet-management/node-lifecycle) make necessary changes without disrupting running tasks.
* **Node draining for removal**: If a Node must be removed from the cluster, CKS cordons the Node before draining it. CKS automatically reschedules workloads onto healthy Nodes, and no new workloads are scheduled to the cordoned Node.
* **InfiniBand or Ethernet link flaps**: Link flaps are intermittent, unpredictable up-down transitions in a network connection, which can result in networking or communication failures. If an InfiniBand or Ethernet link is flapping, a Node can experience inconsistent or unreliable connectivity. In this case, CKS cordons the Node to ensure no workloads are scheduled to a Node with an unreliable network connection.
* **Temporary health check failures**: Kubernetes uses health checks to assess the state of a user's system. A temporary check failure might indicate transient issues that could degrade Node performance. CKS cordons the Node until the issue is resolved.

<Warning>
  Don't assume that cordoned Nodes have serious or permanent issues. If a cordoned Node has a fault that can't be resolved quickly, CKS moves it out of production and into triage.
</Warning>

Cordoning Nodes in these cases lets CKS prevent disruptions. To manually cordon a Node, see [Cordon a Node yourself](/products/cks/nodes/cordon#cordon-a-node-yourself). If you have questions about Node cordoning, [contact Support](/support).

## Node Pool prefill

Node Pool prefill helps maintain capacity while individual Nodes are replaced. For Nodes selected for prefill, CKS provisions replacement capacity before draining and removing the existing Node. Replacement capacity depends on [availability](#prefill-availability). You aren't billed for both Nodes during the prefill overlap.

Prefill is enabled by default for supported new Node Pools.

<Note>
  Node Pools created before October 8, 2026, retain their existing prefill settings. See the [prefill changelog entry](/changelog#october-8-2026).
</Note>

When you omit the `spec.prefill` field, CKS uses [prefill default values](/products/cks/nodes/manage#enable-node-pool-prefill).

### When to use prefill

Use prefill for Node Pools whose workloads are sensitive to capacity loss during Node replacement, such as long-running training jobs or latency-sensitive inference.

* **Without prefill enabled**: CKS replaces a Node only after the old Node is removed, so the Node Pool is below its target Node count until the replacement is delivered and ready. This leaves a capacity gap that can last 20 to 40 minutes.

* **With prefill enabled**: CKS provisions a replacement Node before draining and removing the old Node, reducing the risk of a capacity gap. Workloads can continue on the existing Node while CKS provisions its replacement.

### Prefill availability

Prefill provisions replacement Nodes from [on-demand capacity](/platform/capacity-plans#on-demand), so a replacement Node is not guaranteed. If on-demand capacity is unavailable, prefill keeps retrying, and the Node stays in the prefill flow until a replacement can be provisioned. Account for this when you rely on prefill for time-sensitive replacements.

**Prefill requirements**

| Setting | Requirement |
| - | - |
| Instance type | Use a non-rack-based instance type. Rack-based instances, such as GB200 and GB300, don't support prefill. |
| Autoscaling | Set `autoscaling: false`. With autoscaling enabled, CKS doesn't start new prefill operations. Operations already in progress continue. |
| Compute class | Use `computeClass: default`. Spot Node Pools don't support prefill. |

If prefill is enabled on an unsupported Node Pool, CKS sets `PrefillEnabled` to `False` and doesn't mark new Nodes for prefill. This also applies when prefill is enabled by default. See [Prefill status](/products/cks/reference/node-pool#condition-prefillenabled).

### How prefill works

A Node is marked unschedulable as soon as it enters triage, so no new workloads are scheduled onto it. If a replacement Node can't be provisioned, CKS keeps retrying until one is available or the Node is no longer marked for prefill.

After the replacement joins the Node Pool, CKS waits up to the idle timeout (`spec.prefill.timeout`) for the old Node to become idle, then removes it. If the Node hasn't become idle when the timeout expires, CKS starts draining it. CKS removes the Node once it becomes idle.

### Prefill Node conditions

When prefill is enabled, CKS sets a `Prefill` condition on Nodes that are in the prefill flow. The condition's `reason` field indicates the current state. You can use `LastTransitionTime` on the condition to see when the reason last changed.

| Reason | Meaning |
| - | - |
| `AwaitingReplacement` | The Node is marked for prefill and a replacement Node is being provisioned. |
| `AwaitingIdleTimeout` | The replacement Node is in the cluster. CKS waits up to the idle timeout (`spec.prefill.timeout`) for this Node to become idle, then removes it. |
| `TimeoutExceeded` | The Node did not become idle within the idle timeout (`spec.prefill.timeout`) period, so CKS drains the Node and removes it once it becomes idle. <br /> <Danger>Monitor Nodes nearing their <code>timeout</code> period, so CKS doesn't drain critical workloads.</Danger> |

### Prefill flow

The following diagram shows how a Node moves through the prefill flow, including the two paths CKS can take depending on whether the Node becomes idle within the default 24 hour idle timeout (`spec.prefill.timeout`) period.

```mermaid theme={"system"}
%%{init: {'themeVariables': {'fontSize': '16px', 'edgeLabelBackground': '#ffffff'}, 'flowchart': {'padding': 10}}}%%
flowchart TD
  A[CKS marks a Node <br/>for triage.<br/>The Node is now<br/> unschedulable.] -->|CKS sets the triaged Node's condition<br/>to <code>AwaitingReplacement</code>.| C[A replacement Node<br/> joins the Node Pool.]
  C -->|CKS sets the triaged Node's condition<br/>to <code>AwaitingIdleTimeout</code>.| D[To replace<br/> the triaged Node,<br/>CKS waits for the<br/> Node to become idle.]
  D -->|The Node becomes idle<br/> within the <br/><code>spec.prefill.timeout</code><br/> period.| G[The Node is now idle.]
  D -->|The Node doesn't become <br/>idle within the<br/> <code>spec.prefill.timeout</code> <br/>period.<br/>CKS sets the triaged<br/> Node's condition to<br/> <code>TimeoutExceeded</code>.| F[CKS drains the Node<br/>and waits for it<br/>to become idle.]
  G --> E[CKS replaces<br/> the triaged Node.]
  F --> E
```

For details on configuring or disabling prefill, see [Configure Node Pool prefill](/products/cks/nodes/manage#enable-node-pool-prefill). For the prefill reference specification, see [Prefill reference](/products/cks/reference/node-pool#prefill).

## Scaling strategies

A Node Pool has two scale-down strategies, which control how CKS chooses Nodes to remove when you lower `targetNodes`. The Cluster Autoscaler doesn't use them. To protect active Nodes from the autoscaler, see [Prevent Pod eviction or Node removal](/products/cks/nodes/autoscaling#prevent-pod-eviction-or-node-removal). Set `spec.lifecycle.scaleDownStrategy` to one of the following values:

| Strategy | Description |
| - | - |
| `IdleOnly` | Default strategy. CKS only selects [idle Nodes](#idle-nodes) for removal. When you lower `targetNodes`, CKS removes only Nodes that aren't actively running workloads. |
| `PreferIdle` | CKS prioritizes idle Nodes for removal, but if there aren't enough idle Nodes to meet the desired scale, CKS can also select non-idle Nodes. This allows faster scale-down when necessary. |

## Idle Nodes

A Node is idle when it has no Pods in the `Running` or `Pending` phase. When determining a Node's idle status, CKS ignores Pods with any of the following conditions:

| Condition | Description |
| - | - |
| `qos.coreweave.com/graceful-interruptible` is set to `true` and the Pod's `DeletionGracePeriodSeconds` has elapsed | CKS ignores graceful interruptible Pods only if they're being deleted and the deletion grace period has elapsed. |
| The Pod is part of a `DaemonSet` | CKS ignores Pods managed by a `DaemonSet` when determining Node idleness. |
| `qos.coreweave.cloud/interruptable` label set to `true` | CKS ignores interruptible Pods when determining Node idleness. |
| `ns.coreweave.cloud/org` label set to `control-plane` | CKS ignores Control Plane Pods when determining Node idleness. |

You can determine a Node's idle status by inspecting the `CWActive` condition. `CWActive = False` means the Node is idle.

### Node idle status and maintenance

CKS defers certain maintenance operations, such as moving a Node out of production after detecting elevated InfiniBand link flaps, until the Node becomes idle. A long-running Pod without an interruptible label keeps the Node active indefinitely, preventing those deferred operations from completing. For Pods that run continuously but can tolerate interruption, apply the `qos.coreweave.cloud/interruptable` label so that deferred maintenance doesn't wait for them. For stateful Pods that need cleanup time, use `qos.coreweave.com/graceful-interruptible`, which makes deferred maintenance wait only for the Pod's termination grace period. Gracefully interruptible Pods still count toward `CWActive` until they finish terminating, as the preceding table shows. See [Pod interruption and eviction policies](/products/cks/clusters/scheduling/workload-scheduling#pod-interruption-and-eviction-policies). To learn how deferred maintenance operations behave, see [Node state transitions in CKS](/platform/fleet-management/node-lifecycle/state-transitions).

Once CKS selects a Node for removal, CKS removes the Node by first cordoning it to prevent any new Pods from being scheduled onto it. Then, CKS drains the Node to perform a graceful cleanup. Once the Node is fully drained, CKS removes it from the Node Pool.

<Note>
  `DeletionGracePeriodSeconds` defaults to 30 seconds unless the Pod's `spec.terminationGracePeriodSeconds` is set to a different value.
</Note>

<Warning>
  During the drain process, to prevent being stopped by Pods stuck in a `Terminating` state, CKS waits up to 5 minutes before more forcibly removing a draining Node.
</Warning>

## Scale down a Node Pool

To scale down a Node Pool:

1. Set `spec.targetNodes` to the desired number of Nodes, or `spec.targetRacks`, depending on the target type set on the Node Pool. For instructions on doing this with Cloud Console or the Kubernetes CLI, see [Manage Node Pools](/products/cks/nodes/manage).
2. Set `spec.lifecycle.scaleDownStrategy` to the preferred [scaling strategy](#scaling-strategies).

### How CKS selects Nodes to remove

When a Node Pool scales down, CKS picks which Nodes to remove based on the configured [scale-down strategy](#scaling-strategies) and Node [idleness](#idle-nodes). There is no Node Pool field or Node label that lets you single out a specific Node for removal during scale-down. CKS chooses among eligible Nodes automatically.

If you need a particular Node to be the one removed during the next scale-down, do one of the following before lowering `targetNodes`:

* **Drain the Node yourself.** Use standard Kubernetes tooling (`kubectl cordon` and `kubectl drain`) to evict workloads from the target Node. With the default `IdleOnly` strategy, an empty Node becomes eligible for removal first.
* **Reschedule workloads off the Node.** Delete or move the Pods running on the target Node so the Node becomes idle. CKS ignores Pods that are part of a DaemonSet, control-plane Pods, and Pods labeled as interruptible when determining idleness (see [Idle Nodes](#idle-nodes)).

If the Node you want to remove is unhealthy and you can't drain it, [contact Support](/support) to request manual removal.

If a scale-down stalls and the Node Pool's events repeat `No nodes eligible for removal right now`, see [Current is above target](/products/cks/nodes/nodepool-status#current-is-above-target) for how to find the Pods blocking it.

## Node Pool types

CKS uses the `default` Node Pool type to manage Reserved and On-Demand instances. The following section describes when to use the default type and how to configure it.

### Default Node Pools

CKS uses the default Node Pool type (`spec.computeClass: default`) for Reserved and On-Demand instances. Billing for default Node Pools depends on Reservation and utilization.

<Info>
  You don't need to specify default Node Pools.

  If you don't specify a `computeClass`, the Node Pool defaults to the `default` type.
</Info>

```yaml title="Example default Node Pool manifest" theme={"system"}
apiVersion: compute.coreweave.com/v1alpha1
kind: NodePool
metadata:
  name: default
spec:
  computeClass: default
  # ...
```

For more information on Node Pool manifests, see [Node Pool reference](/products/cks/reference/node-pool#node-pool), or learn how to [Create a Node Pool](/products/cks/nodes/create).

## Manage Node Pools with Terraform

The [CoreWeave Terraform provider](/platform/terraform) manages clusters, VPCs, and Object Storage, but it doesn't include a Node Pool resource. Deploy Node Pools through the [Cloud Console or the Kubernetes API](/products/cks/nodes/create) instead. A Terraform-only workflow typically combines the CoreWeave provider for the cluster and VPC with a separate mechanism, such as the Kubernetes provider, to apply Node Pool manifests. See [How do I use Terraform to manage clusters and Node Pools?](/support/cks/articles/how-do-i-use-terraform-to-manage-clusters-and-node-pools).

## Image pull best practices

CoreWeave operates a region-level registry proxy that accelerates container image pulls and reduces exposure to public registry rate limits for your cluster's Nodes. To ensure predictable and fast rollouts when scaling Node Pools, use immutable tags, or pin by digest, for production workloads. This ensures every Node pulls the same artifact and avoids stale results from proxy metadata caching.

Avoid mutable tags like `:latest`. With metadata caching enabled, the proxy can continue serving a cached manifest until the cache expires, which can lead to inconsistent versions across Nodes. For more information, see the [region-level image proxy](/products/cks/clusters/introduction#region-level-image-proxy) documentation.

## Reboot methods

You can manually reboot Nodes in the following two ways:

| Reboot method | When to use | Typical duration |
| - | - | - |
| [Reboot only](/products/cks/nodes/reboot) | Maintenance, troubleshooting, or applying changes that don't require reconfiguration | Approximately 10 minutes or more |
| [Reconfigure reboot](/products/cks/nodes/apply-updates) | Applying OS images, GPU driver updates, or other Node Pool modifications that require reconfiguration | Approximately 1 hour or more |

### Node conditions for reboots (deprecated)

CoreWeave's Node conditions are visible when you manage reboots. You previously set these Node conditions with the [Conditioner Kubectl plugin](https://github.com/devbytes-cloud/conditioner). The [CoreWeave Intelligent CLI](https://github.com/coreweave/cwic) doesn't set them. It requests reboots through the `PhaseState` and `PendingPhaseState` lifecycle conditions instead. See the [Reboot Nodes](/products/cks/nodes/reboot#reboot-request-reference) and [Apply Node Pool updates](/products/cks/nodes/apply-updates) guides for more information.

| Condition | Description | Deprecated equivalent |
| - | - | - |
| `AdminSafePowerCycle` | Marks the Node to reboot when it is idle, only after all running jobs are complete. | `AdminSafeReboot` |
| `AdminImmediatePowerCycle` | Marks the Node to reboot immediately, without waiting for running jobs to complete. | `AdminImmediateReboot` |

<Warning>
  **Don't use Node conditions for automation**

  CoreWeave-managed Node conditions, labels, states, and events can change without notice. Don't use them for your own automation or change them except through documented procedures, such as [cordoning a Node yourself](/products/cks/nodes/cordon#cordon-a-node-yourself) or [requesting a Node reboot](/products/cks/nodes/reboot#request-a-node-reboot). You can still add your own custom Node conditions and labels.
</Warning>

## Control Plane Node Pool (deprecated)

CoreWeave provisioned clusters created before July 7, 2025 with a `cpu-control-plane` Node Pool for CKS-managed components. Clusters created after this date don't have this Node Pool. The CKS Control Plane now manages the components out-of-band. See the [Control Plane Node Pool release notes](/release-notes/control-plane-node-pools) for more information.

#### Do not install the NVIDIA GPU Operator on CKS clusters

<Warning>
  CoreWeave manages the [NVIDIA GPU Operator](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/getting-started.html) on your behalf. Do not install the NVIDIA GPU Operator on CKS clusters. Doing so conflicts with the platform-managed deployment and is not supported.
</Warning>
