Spot Instances vs Savings Plans for EKS
What AWS says each discount is, how to split Spot, Savings Plans and On-Demand, and a Karpenter v1 NodePool that falls back safely.
If you run EKS, you've probably debated Spot versus Savings Plans. The honest answer is that they solve different problems, and most clusters want both. Here's how I split the decision, with AWS's own numbers.
What AWS actually says
| Spot Instances | Compute Savings Plans | EC2 Instance Savings Plans | |
|---|---|---|---|
| Discount vs On-Demand | Up to 90% | Up to 66% | Up to 72% |
| Commitment | None | $/hour for 1 or 3 years | $/hour for 1 or 3 years |
| Flexibility | Can be reclaimed with a 2-minute notice | Any instance family, size, region, plus Fargate and Lambda | One instance family in one region |
Sources: Amazon EC2 Spot Instances and Savings Plans pricing. “Up to” is doing real work in every one of those numbers. Your discount depends on instance type, region, term and payment option.
How I split it
- Savings Plans for the floor. Look at your lowest steady compute usage over the last 30 to 60 days. That baseline (databases on EC2, system pods, the minimum production traffic) is what a Savings Plan should cover. Committing above the floor means paying for hours you don't use.
- Spot for what can be interrupted. Stateless web pods with several replicas, queue workers, CI runners, dev and staging environments.
- On-Demand for the rest. Anything stateful or singleton that can't survive a 2-minute notice.
There's no universal ratio. The right mix comes from your workloads and your usage history, which is why the first step is always reading the bill.
Making Spot safe on EKS
The risk with Spot is the interruption, not the price. Diversify across many instance types so one capacity pool running dry doesn't take all your nodes, and let your provisioner pick the price-capacity-optimized option. With Karpenter, a NodePool can allow both Spot and On-Demand and fall back automatically:
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: general
spec:
template:
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot", "on-demand"]
- key: karpenter.k8s.aws/instance-category
operator: In
values: ["c", "m", "r"]
- key: karpenter.k8s.aws/instance-generation
operator: Gt
values: ["5"]
nodeClassRef:
group: karpenter.k8s.aws
kind: EC2NodeClass
name: default
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 1mAdd arm64 to the architecture options if your images support it. AWS positions Graviton as offering better price performance than comparable x86 instances. Measure it on your own workload before you commit to it.
More on handling interruptions: Stop losing money on Spot interruptions in EKS.
The order I'd do it in
- Right-size pod requests first. Savings Plans on oversized nodes just lock in waste.
- Move interruption-tolerant workloads to Spot with diversity and PodDisruptionBudgets.
- Buy a Savings Plan for the new, lower baseline. Start with a 1-year term if you're unsure.
Want this done against your real bill? The AWS Cost Review gives you a ranked list of savings, each priced in dollars a month with effort and risk.