Kubernetes resource planner

Enter the size of a node and your workloads (replicas, CPU and memory requests and limits), or paste their manifests. You get the number of nodes, how full they are, what is placed on each one and the pods that do not fit, with every overhead shown and its source.

Node size
The machine type of the node pool, for example 4 vCPU.
Its memory in GiB, for example 16.

Workloads

Per pod. 1000 millicores = 1 vCPU; 0 means not set.

Workload 1: web
Workload 2: api
Workload 3: worker
Workload 4: postgres

Up to 50 workloads.

Import from manifests

Paste Kubernetes YAML: Deployments, StatefulSets, DaemonSets, ReplicaSets, Jobs and Pods, several documents separated by ---. Only the kind, the name, the replicas and the containers' CPU and memory requests and limits are read.

The rows you import become ordinary inputs: their names and numbers go into the share link like anything you type. The YAML itself is not kept.

Stays in your browser. What you paste or choose is read on this page only. It is not sent to a server, not saved in the link or in browser storage, and never part of analytics.

Paste the text, or choose a file from your computer. Up to 256 KiB.

0 of 256 KiB

Result

Nodes
4
CPU requested of allocatable
67.2%
Memory requested of allocatable
29.7%
Allocatable CPU per node
3.72 vCPU
Allocatable memory per node
12.91 GiB
Pods placed
8
Pods that fit on no node
0
Breakdown
LineValueAssumptions used
Node CPU4 vCPU
    CPU: kubelet and system reservation0.08 vCPU
    • Kubelet and system reservation
    CPU: system DaemonSets0.2 vCPU
    • System DaemonSets, CPU (Assumption)
    CPU: your per-node workloads0 vCPU
      CPU allocatable to pods, per node3.72 vCPU
      • Kubelet and system reservation
      • System DaemonSets, CPU (Assumption)
      Node memory16 GiB
        Memory: kubelet and system reservation2.6 GiB
        • Kubelet and system reservation
        Memory: eviction threshold0.1 GiB
        • Memory eviction threshold
        Memory: system DaemonSets0.39 GiB
        • System DaemonSets, memory (Assumption)
        Memory: your per-node workloads0 GiB
          Memory allocatable to pods, per node12.91 GiB
          • Kubelet and system reservation
          • Memory eviction threshold
          • System DaemonSets, memory (Assumption)
          Pod slots per node110
          • Pods per node, at most
          CPU requested by the pods7.5 vCPU
            Memory requested by the pods11.5 GiB
              Nodes the pods need (first-fit decreasing)3
              • Kubelet and system reservation
              • Memory eviction threshold
              • System DaemonSets, CPU (Assumption)
              • System DaemonSets, memory (Assumption)
              • Pods per node, at most
              Spare nodes for HA1
              • Spare nodes for HA (N+k) (Assumption)

              Calculator kubernetes-resource-planner 1.0.0 · engine @anaroq/calc 1.4.0 · data snapshot 2026.10.4 · How the calculators work

              Assumptions

              Every number the result uses that you didn't enter. Change any of them to match your case.

              • %

                The tiers GKE publishes for node pools created on 1.36 or earlier: CPU 6% of the first core, 1% of the second, 0.5% of the next two, 0.25% above four; memory 255 MiB under 1 GiB, else 25% of the first 4 GiB, 20% of the next 4, 10% of the next 8, 6% up to 128 GiB, 2% above. 100% applies them as published; other platforms reserve differently, 0% reserves nothing (upstream's default).

                Source ·
              • MiB

                The kubelet's default hard eviction threshold on Linux, memory.available<100Mi: pods are evicted before the node's free memory goes below it, so it is not allocatable.

                Source ·
              • Assumption
                millicores

                What the cluster's own agents request on every node: the network plugin (CNI), kube-proxy, a log shipper and a metrics agent. It varies by platform and add-ons: read it with kubectl describe node.

                No source: this is our own assumption. Change it if you know your case.
              • Assumption
                MiB

                The memory the same agents request on every node.

                No source: this is our own assumption. Change it if you know your case.
              • Kubernetes is designed for no more than 110 pods per node, the kubelet's default maxPods. Some managed platforms set another number.

                Source ·
              • Assumption

                One node more than the pods need (N+1): when a node fails or is drained for an upgrade, its pods have somewhere to go. 0 plans for no failure.

                No source: this is our own assumption. Change it if you know your case.

              What you enter and the assumptions you change are kept in this page's link, after the #.

              Warnings

              • worker: a CPU limit without a request. Kubernetes uses the limit as the request, so it is counted at the limit.

              Nodes

              Each node with the pods first-fit decreasing placed on it, and how much of its allocatable CPU and memory they request.

              1. Node 1CPU 3.5 vCPU of 3.72 vCPU · memory 6.5 GiB of 12.91 GiB · 3 podsweb × 1, api × 1, postgres × 1
              2. Node 2CPU 3.5 vCPU of 3.72 vCPU · memory 4.5 GiB of 12.91 GiB · 4 podsweb × 1, api × 1, worker × 2
              3. Node 3CPU 0.5 vCPU of 3.72 vCPU · memory 0.5 GiB of 12.91 GiB · 1 podsweb × 1
              4. Spare node 1 (HA)Empty: room for the pods of a node that fails or is drained.

              Take the plan with you

              The plan as a Markdown file: the node size, the workloads, the result, the warnings, each node, every assumption with its source or its mark, and the link that reproduces it.

              kubernetes-resource-plan.md
              # Kubernetes resource planner
              
              An estimate from the assumptions listed below, not a measurement or a guarantee.
              
              No source: this is our own assumption. Change it if you know your case.
              
              ## What you entered
              
              - vCPU per node: 4
              - Memory per node (GiB): 16
              - web: Replicas 3, CPU request (millicores) 500, CPU limit (millicores) 1000, Memory request (MiB) 512, Memory limit (MiB) 1024
              - api: Replicas 2, CPU request (millicores) 1000, CPU limit (millicores) 2000, Memory request (MiB) 2048, Memory limit (MiB) 2048
              - worker: Replicas 2, CPU request (millicores) 0, CPU limit (millicores) 1000, Memory request (MiB) 1024, Memory limit (MiB) 0
              - postgres: Replicas 1, CPU request (millicores) 2000, CPU limit (millicores) 0, Memory request (MiB) 4096, Memory limit (MiB) 4096
              
              ## Result
              
              - Nodes: 4
              - CPU requested of allocatable: 67.2%
              - Memory requested of allocatable: 29.7%
              - Allocatable CPU per node: 3.72 vCPU
              - Allocatable memory per node: 12.91 GiB
              - Pods placed: 8
              - Pods that fit on no node: 0
              
              ## Warnings
              
              - worker: a CPU limit without a request. Kubernetes uses the limit as the request, so it is counted at the limit.
              
              ## Nodes
              
              - Node 1: CPU 3.5 vCPU of 3.72 vCPU · memory 6.5 GiB of 12.91 GiB · 3 pods (web × 1, api × 1, postgres × 1)
              - Node 2: CPU 3.5 vCPU of 3.72 vCPU · memory 4.5 GiB of 12.91 GiB · 4 pods (web × 1, api × 1, worker × 2)
              - Node 3: CPU 0.5 vCPU of 3.72 vCPU · memory 0.5 GiB of 12.91 GiB · 1 pods (web × 1)
              - Spare node 1 (HA): Empty: room for the pods of a node that fails or is drained.
              
              ## Breakdown
              
              | Line | Value | Assumptions used |
              | --- | --- | --- |
              | Node CPU | 4 vCPU | – |
              | CPU: kubelet and system reservation | 0.08 vCPU | Kubelet and system reservation |
              | CPU: system DaemonSets | 0.2 vCPU | System DaemonSets, CPU |
              | CPU: your per-node workloads | 0 vCPU | – |
              | CPU allocatable to pods, per node | 3.72 vCPU | Kubelet and system reservation, System DaemonSets, CPU |
              | Node memory | 16 GiB | – |
              | Memory: kubelet and system reservation | 2.6 GiB | Kubelet and system reservation |
              | Memory: eviction threshold | 0.1 GiB | Memory eviction threshold |
              | Memory: system DaemonSets | 0.39 GiB | System DaemonSets, memory |
              | Memory: your per-node workloads | 0 GiB | – |
              | Memory allocatable to pods, per node | 12.91 GiB | Kubelet and system reservation, Memory eviction threshold, System DaemonSets, memory |
              | Pod slots per node | 110 | Pods per node, at most |
              | CPU requested by the pods | 7.5 vCPU | – |
              | Memory requested by the pods | 11.5 GiB | – |
              | Nodes the pods need (first-fit decreasing) | 3 | Kubelet and system reservation, Memory eviction threshold, System DaemonSets, CPU, System DaemonSets, memory, Pods per node, at most |
              | Spare nodes for HA | 1 | Spare nodes for HA (N+k) |
              
              ## Assumptions
              
              - Kubelet and system reservation: 100%. The tiers GKE publishes for node pools created on 1.36 or earlier: CPU 6% of the first core, 1% of the second, 0.5% of the next two, 0.25% above four; memory 255 MiB under 1 GiB, else 25% of the first 4 GiB, 20% of the next 4, 10% of the next 8, 6% up to 128 GiB, 2% above. 100% applies them as published; other platforms reserve differently, 0% reserves nothing (upstream's default). Source: https://docs.cloud.google.com/kubernetes-engine/docs/concepts/plan-node-sizes (read 16 Oct 2026)
              - Memory eviction threshold: 100 MiB. The kubelet's default hard eviction threshold on Linux, memory.available<100Mi: pods are evicted before the node's free memory goes below it, so it is not allocatable. Source: https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/ (read 16 Oct 2026)
              - System DaemonSets, CPU: 200 millicores. What the cluster's own agents request on every node: the network plugin (CNI), kube-proxy, a log shipper and a metrics agent. It varies by platform and add-ons: read it with kubectl describe node. **Assumption**
              - System DaemonSets, memory: 400 MiB. The memory the same agents request on every node. **Assumption**
              - Pods per node, at most: 110. Kubernetes is designed for no more than 110 pods per node, the kubelet's default maxPods. Some managed platforms set another number. Source: https://kubernetes.io/docs/setup/best-practices/cluster-large/ (read 16 Oct 2026)
              - Spare nodes for HA (N+k): 1. One node more than the pods need (N+1): when a node fails or is drained for an upgrade, its pods have somewhere to go. 0 plans for no failure. **Assumption**
              
              Calculator kubernetes-resource-planner 1.0.0 · engine @anaroq/calc 1.4.0 · data snapshot 2026.10.4
              
              Open this calculation: https://anaroq.com/tools/kubernetes-resource-planner#k=eyJhc3N1bXB0aW9ucyI6e30sImNhbGMiOiJrdWJlcm5ldGVzLXJlc291cmNlLXBsYW5uZXIiLCJpbnB1dCI6eyJub2RlQ3B1Ijo0LCJub2RlTWVtb3J5R2liIjoxNiwid29ya2xvYWRzIjpbeyJjcHVMaW1pdE0iOjEwMDAsImNwdVJlcXVlc3RNIjo1MDAsIm1lbW9yeUxpbWl0TWkiOjEwMjQsIm1lbW9yeVJlcXVlc3RNaSI6NTEyLCJuYW1lIjoid2ViIiwicGVyTm9kZSI6ZmFsc2UsInJlcGxpY2FzIjozfSx7ImNwdUxpbWl0TSI6MjAwMCwiY3B1UmVxdWVzdE0iOjEwMDAsIm1lbW9yeUxpbWl0TWkiOjIwNDgsIm1lbW9yeVJlcXVlc3RNaSI6MjA0OCwibmFtZSI6ImFwaSIsInBlck5vZGUiOmZhbHNlLCJyZXBsaWNhcyI6Mn0seyJjcHVMaW1pdE0iOjEwMDAsImNwdVJlcXVlc3RNIjowLCJtZW1vcnlMaW1pdE1pIjowLCJtZW1vcnlSZXF1ZXN0TWkiOjEwMjQsIm5hbWUiOiJ3b3JrZXIiLCJwZXJOb2RlIjpmYWxzZSwicmVwbGljYXMiOjJ9LHsiY3B1TGltaXRNIjowLCJjcHVSZXF1ZXN0TSI6MjAwMCwibWVtb3J5TGltaXRNaSI6NDA5NiwibWVtb3J5UmVxdWVzdE1pIjo0MDk2LCJuYW1lIjoicG9zdGdyZXMiLCJwZXJOb2RlIjpmYWxzZSwicmVwbGljYXMiOjF9XX0sInYiOjF9
              How the calculators work: https://anaroq.com/methodology#calculators
              

              What it does

              It plans the nodes of one Kubernetes node pool for a set of workloads: how many nodes of the size you choose the pods need, how full the nodes are, and which pods go where. It counts what the scheduler counts (requests, not limits) and what each node keeps for itself, and adds spare nodes for failures.

              How it works

              1. Allocatable per node = the node's CPU and memory − the kubelet and system reservation (the tiers GKE publishes) − the memory eviction threshold (100 MiB, the kubelet default) − the system DaemonSets − your own workloads marked to run on every node.
              2. Each pod is counted at its request; a pod with a limit and no request at its limit, as Kubernetes does. A pod with neither counts as 0 but still takes one of the pod slots (110 a node by default).
              3. Bin-packing, first-fit decreasing: the pods are sorted by the largest share of a node they take (CPU or memory) and each one goes to the first node it fits on, or to a new node. The same input always gives the same plan.
              4. Nodes = the nodes the pods need (at least one) + the spare nodes for HA (one by default, N+1). Utilization is what the placed pods request of the allocatable of the nodes they use.
              5. Every overhead is listed under Assumptions: the reservation, the eviction threshold and the pod slots with their published source, the system DaemonSets and the spare nodes with the Assumption mark.

              Example

              Four workloads on nodes of 4 vCPU and 16 GiB, with every assumption at its default:

              web 3 × 500m/512Mi · api 2 × 1000m/2Gi · worker 2 × limit 1000m/1Gi · postgres 1 × 2000m/4Gi

              Nodes
              4
              CPU requested of allocatable
              67.2%
              Memory requested of allocatable
              29.7%
              Allocatable CPU per node
              3.72 vCPU
              Allocatable memory per node
              12.91 GiB
              Pods placed
              8
              Pods that fit on no node
              0

              Limits

              • A plan from requests, not a measurement: if your requests are far from what the pods use, the plan is too. Set them from real use (kubectl top, your metrics).
              • One node pool, one node size. Taints, affinity, topology spread, zones and storage are not modelled; they can need more nodes than packing alone.
              • No autoscaling: the replicas you enter are fixed. Plan for the peak number of replicas of a HorizontalPodAutoscaler.
              • Reservations differ by platform: EKS, AKS, k3s and kubeadm reserve differently from the GKE tiers. Read the allocatable of a real node (kubectl describe node) and set the reservation to match.
              • No price: the plan gives the nodes; the cost of a managed cluster is not computed here.

              Methodology: how the numbers are worked out

              Sources

              1. ANAROQ calculator methodology: assumptions, units and rounding
              2. Kubernetes Documentation: Resource Management for Pods and Containers
              3. Kubernetes Documentation: Node-pressure Eviction
              4. Kubernetes Documentation: Considerations for large clusters
              5. Google Kubernetes Engine: Plan node sizes

              Updated

              Next step

              Docker Compose to Kubernetes converter

              A free public tool by ANAROQ, a company building compute infrastructure. What ANAROQ is building