DEV Community

Cover image for Kubernetes cost optimization for startups
Abhishek Jaiswal
Abhishek Jaiswal

Posted on Originally published at ownkube.io

Kubernetes cost optimization for startups

What surprises people first about a startup's Kubernetes bill is how predictable the leaks are. Across the small-team AWS and GCP bills we audit, the same seven patterns drive 70 to 90% of the waste, and they're all fixable in a single quarter.

This post is the consolidated playbook. It covers the seven patterns, the realistic savings on each, and the structural change that keeps them from drifting back: making the platform carry the defaults.

Skim answer:

  • The seven highest-leverage patterns: right-sizing, spot capacity, idle environment sleep, namespace quotas, image-pull traffic reduction, NAT-routing audits, and storage class right-sizing.
  • Combined impact: typically cuts a small-team Kubernetes bill by 40 to 65%.
  • Timeline: all seven are fixable in a single quarter.

Why startup K8s bills are usually 2x what they should be

The math behind the typical waste:

  • Most teams set resource requests at 2x to 4x what the workload actually uses, "to be safe". Cluster autoscaler then provisions nodes for the inflated request rather than the real usage.
  • Idle preview environments and staging clusters run 24/7 even though they're used 30 hours a week.
  • Container images get pulled from public registries through NAT gateways, racking up data-processing fees nobody sees.
  • EBS volumes are provisioned at default gp2 sizes that exceed real I/O needs by an order of magnitude.

Each of these is a small, steady bleed. Add up enough of them and the cluster bill is double what it should be.

Pattern 1: Right-size every workload

This is the largest lever. Most workloads we see have resource requests set during initial deployment and never revisited. A typical web pod might have a 1 vCPU / 1 GB RAM request and a 95th-percentile usage of 0.18 vCPU / 240 MB RAM, so the other 80% of the request is reservation paid for and unused.

To fix it, run Vertical Pod Autoscaler in recommendation mode for one to two weeks, then apply the recommendations. For long-tail workloads with bursty traffic, use VPA in Auto mode with sensible min/max bounds.

Expect to save 25 to 45% of cluster compute. It's the biggest line-item improvement on every audit.

Pattern 2: Spot capacity for the workloads that tolerate it

Stateless web pods, queue consumers, build runners, batch jobs, and preview environments are excellent candidates for spot. Database primaries, control plane nodes, and single-replica stateful services should stay on-demand. We covered the full pattern in AWS spot instances in production.

To fix it, use mixed instance pools with an on-demand base and spot for the rest. Karpenter or Cluster Autoscaler with mixed ASGs handles the orchestration. Set PodDisruptionBudgets and 30 to 120 second graceful shutdown windows.

Expect 50 to 70% off the spot-eligible portion of the compute bill. For a typical small-team workload, that's roughly 30 to 50% off the total cluster compute.

Pattern 3: Sleep idle environments

Staging, preview, and developer sandbox environments sit idle most of the week. A preview environment created on Monday for a PR that merges Friday runs for ~120 hours while being used for maybe 4. The other 116 hours are waste.

To fix it, add an idle-detection loop that scales preview deployments to zero after N hours of no traffic, then scales back up on the next request. Tools like KEDA, scaler-controller, or platform-layer features handle this.

Expect to save 50 to 75% of preview environment cost. For teams with 5 to 20 active previews at any time, this can be the second-biggest single-pattern saving.

Pattern 4: Namespace quotas and request governance

Without ResourceQuota on each namespace, any service team can ship a deployment that requests more than it needs. Quotas force the conversation: "you want 8 vCPU for this worker, defend it."

To fix it, pin a ResourceQuota per namespace to a realistic budget, add a LimitRange to set sensible default requests for pods without explicit requests, and revisit the quotas in a monthly review.

Expect 10 to 20% in indirect savings through culture change. The bigger win is preventing future drift.

Pattern 5: Pull images from a private registry

Most teams pull container images from Docker Hub, GitHub Container Registry, or Quay through a NAT gateway. Each pull is a few hundred MB. With a busy CI fleet plus rolling production deploys, that's tens of GB per day routed through NAT at $0.045 per GB.

To fix it, mirror your base images to a private Amazon ECR registry (or GCP Artifact Registry), enable the ECR VPC interface endpoint, and configure your image pull policy to use the mirror. Image pulls then stay on the AWS backbone at near-zero per-GB cost.

Expect to save $50 to $400 per month for a typical small team, and more for orgs that deploy often.

Pattern 6: Audit NAT routing

NAT gateway data-processing fees are the most under-noticed cost on AWS bills. We covered the full pattern in our NAT gateway cost guide. The short version:

  • Enable S3 and DynamoDB gateway endpoints (free) on every VPC.
  • Add interface endpoints for high-volume AWS services (Secrets Manager, STS, CloudWatch Logs).
  • Dual-stack your VPC and route IPv6 traffic through a free egress-only IGW.
  • Reduce NAT topology from 3 AZs to 2 if availability tolerates.

Expect to save $200 to $1,500 per month depending on cluster traffic.

Pattern 7: Storage class right-sizing

EBS gp3 has replaced gp2 as the sensible default for most cluster volumes. It's cheaper and faster, and you pay only for the IOPS you provision (on gp2, IOPS scale with volume size).

To fix it, migrate from gp2 to gp3 across your cluster and right-size volume capacity (most workloads provision 100 GB when they use 12 GB). For workloads with very low I/O, consider sc1 or st1 for cold data.

Expect to save 20 to 35% on EBS line items.

The structural change that compounds them all

Each of the seven patterns above is a one-time engineering project, and implementing them all takes 2 to 4 weeks of focused work for a small team. The harder question is what stops the drift from coming back six months later.

Without an explicit owner, nothing does. Request inflation creeps back in, new services get deployed without quotas, new environments forget the sleep schedule, new container pulls go through NAT, and the cluster bill returns to its old shape within two quarters.

The structural fix is to have the platform carry these decisions instead of leaving them to tribal memory. On Ownkube, running inside your own cloud account, the platform ships with the primitives that keep these patterns from drifting:

  • Managed Postgres, so database sizing and backups aren't a manual task per environment.
  • Horizontal autoscaling on every workload, so requests track real traffic instead of a number set at first deploy and never revisited.
  • Built-in logs and metrics, so a right-sizing pass is a five-minute look at a dashboard instead of a new observability rollout.
  • One-command rollbacks, so a bad change costs you a rollback instead of an incident.

You still own the architectural decisions. Ownkube keeps the primitives in place so the drift has fewer places to hide.

A worked example

Take a typical 2026 SaaS running Kubernetes on AWS: 1 cluster, ~24 vCPU production fleet, 8 vCPU staging, 10 active preview environments, RDS Postgres, ElastiCache.

Before optimization, it pays ~$2,400/month cluster compute + $180 NAT + $90 EBS = $2,670/month. Here is what each pattern saves:

Pattern Saving
Right-sizing (Pattern 1) -$840
Spot capacity (Pattern 2) -$520
Idle environment sleep (Pattern 3) -$280
Namespace quotas + governance (Pattern 4) -$120
Private image registry (Pattern 5) -$140
NAT routing audit (Pattern 6) -$110
Storage class right-sizing (Pattern 7) -$30
Total saved -$2,040

After all seven, the bill is ~$630/month, about a 76% reduction on the cluster bill.

These numbers come from the workload defined above, so your savings will differ with yours.

Decision checklist

Before you start, confirm:

  • [ ] Do you have a way to measure current per-workload resource usage (Prometheus, CloudWatch, Datadog)?
  • [ ] Is your cluster on Kubernetes 1.27+ (so VPA and Karpenter work cleanly)?
  • [ ] Do you have at least one engineer with a couple of weeks of focused time?
  • [ ] Is anyone going to own ongoing cost vigilance after the initial pass, or do you need that on autopilot?

If you ticked all four, you're set up to do the work in-house. If you ticked three or fewer, consider a platform layer that runs these patterns by default.

Closing

Kubernetes cost optimization at a small startup comes down to seven well-understood patterns plus one structural change to stop the drift from coming back: making the platform itself carry the defaults instead of leaving them to memory.

If you'd rather skip the initial work and start with a platform that ships those defaults, Ownkube runs inside your own AWS account. Starter is free forever on one instance, and Production is $5 per vCPU plus $1 per GiB RAM per month once you scale. Deploy my first app.

Top comments (0)