Kubernetes Cost Optimization: Cutting Your Cloud Bill by 50%

by Ivan Ivanov kubernetescost-optimizationclouddevops

Practical strategies to reduce Kubernetes spending without sacrificing performance. Resource requests, auto-scaling, spot instances, and more.

Kubernetes is famously expensive. A default cluster with 10 nodes can easily cost $500-1000/month on major clouds. Here's how to cut that bill without breaking your applications.

The Problem: Overprovisioning

Most teams set resource requests/limits arbitrarily:

resources:
  requests:
    memory: "512Mi"
    cpu: "500m"
  limits:
    memory: "1Gi"
    cpu: "1000m"

This leads to:

  • Nodes running at 20-30% utilization
  • Paying for unused capacity
  • Poor bin packing (wasted resources)

Strategy 1: Right-Size with Metrics

Collect actual usage for 2 weeks, then adjust:

# Use kubectl top to see actual usage
kubectl top pods --sort-by=cpu
kubectl top pods --sort-by=memory

Set requests to ~50th percentile, limits to ~95th:

# After measuring:
resources:
  requests:
    memory: "128Mi"   # was 512Mi
    cpu: "100m"       # was 500m
  limits:
    memory: "256Mi"   # was 1Gi
    cpu: "500m"       # was 1000m

Strategy 2: Vertical Pod Autoscaler (VPA)

Let VPA automatically adjust requests:

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: myapp-vpa
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: myapp
  updatePolicy:
    updateMode: "Auto"  # or "Off" for recommendations only

VPA analyzes usage and can auto-update pod specs (requires pods to be restartable).

Strategy 3: Horizontal Pod Autoscaler (HPA)

Scale based on custom metrics:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

Strategy 4: Spot Instances (Preemptible VMs)

Use spot instances for fault-tolerant workloads:

  • Define node pools with spot instances (up to 90% cheaper)
  • Use pod tolerations and node selectors
  • Ensure application handles preemption gracefully
  • Use multiple instance types to maximize availability
tolerations:
- key: "kubernetes.io/spot-instance"
  operator: "Exists"
  effect: "NoSchedule"
nodeSelector:
  node-type: spot

Strategy 5: Right-Size Nodes

Don't use largest instance types for everything:

  • Use smaller instances for bursty workloads
  • Consider ARM-based instances (Graviton, Ampere) for 20-40% savings
  • Right-size cluster autoscaler min/max sizes

Strategy 6: Clean Up Unused Resources

  • Delete unused namespaces, ConfigMaps, Secrets
  • Implement TTL for test environments
  • Clean up old images: kubectl delete pods --field-selector=status.phase==Succeeded
  • Set up image garbage collection policies

Strategy 7: Namespace Quotas

Prevent team sprawl:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-team-quota
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi

Real Results

At a SaaS startup, implementing these strategies reduced monthly Kubernetes costs from $3,200 to $1,500 (53% reduction) while maintaining performance and reliability.

Conclusion

Cost optimization is an ongoing process. Measure, adjust, and continuously monitor. Your CFO will thank you.