Kubernetes Cost Optimization for SMBs: Practical Wins Without Enterprise Overhead

Published 9 min read
kubernetescost optimizationsmbautoscalingfinops

Kubernetes cost optimization for small and medium businesses starts with understanding that most SMB clusters waste 40-60% of their compute budget on overprovisioned workloads. Unlike enterprise teams with dedicated FinOps departments, SMBs need lightweight, repeatable practices that fit into existing engineering workflows. This guide covers the five highest-impact optimization levers: rightsizing, autoscaling, resource governance, observability cost control, and review cadence.

Why SMB Kubernetes Costs Get Out of Control

Small teams adopt Kubernetes for its deployment benefits but rarely invest in cost governance. The result is predictable: resource requests based on guesses rather than data, no autoscaling, no namespace quotas, and observability infrastructure that costs more than the workloads it monitors.

Cost ProblemRoot CauseTypical Waste

Overprovisioned podsResource requests based on "safe" guesses40-60%
Always-on non-prodDev/staging running 24/765-75%
No autoscalingFixed replica counts sized for peak30-50%
Observability bloatHigh-cardinality metrics, verbose logging20-40%
Unused PVCsOrphaned volumes from deleted workloads100%
Node over-provisioningCluster autoscaler not configured20-40%

The good news: fixing these problems does not require enterprise tooling or a dedicated FinOps team. It requires discipline and a repeatable review process.

Strategy 1: Rightsize Workloads First

Rightsizing is the highest-impact optimization for any Kubernetes cluster. It means aligning resource requests and limits with actual usage rather than developer estimates.

How to Rightsize

  • Collect baseline data: Run workloads for 2-4 weeks and collect CPU and memory utilization data using Prometheus and cAdvisor metrics.
  • Identify waste: Compare resource requests to actual P95 utilization. Any workload with requests more than 2x its P95 usage is a rightsizing candidate.
  • Prioritize by cost: Sort workloads by total resource allocation (requests x replicas). Start with the top 10 cost drivers.
  • Apply conservative changes: Set requests to 1.3x the P95 utilization and limits to 2x. This provides headroom without gross over-allocation.
  • Monitor after changes: Watch for OOMKill events and CPU throttling for 7 days after any rightsizing change.
  • <h1>Find pods with high resource waste</h1>
    

    <h1>Compare requests to actual usage using kubectl top</h1>

    kubectl top pods --all-namespaces --sort-by=cpu

    <h1>Check resource requests for a namespace</h1>

    kubectl get pods -n production -o json | jq -r \

    '.items[] | .metadata.name + " cpu_req:" +

    (.spec.containers[0].resources.requests.cpu // "none") +

    " mem_req:" +

    (.spec.containers[0].resources.requests.memory // "none")'

    <h1>Install VPA for automated recommendations</h1>

    kubectl apply -f https://github.com/kubernetes/autoscaler/releases/latest/download/vertical-pod-autoscaler.yaml

    Vertical Pod Autoscaler (VPA) for Recommendations

    VPA can automatically recommend resource settings based on observed usage. Use it in "Off" or "Initial" mode first to get recommendations without automatic pod restarts.

    apiVersion: autoscaling.k8s.io/v1
    

    kind: VerticalPodAutoscaler

    metadata:

    name: api-server-vpa

    spec:

    targetRef:

    apiVersion: apps/v1

    kind: Deployment

    name: api-server

    updatePolicy:

    updateMode: "Off" # Recommendations only, no auto-update

    resourcePolicy:

    containerPolicies:

    - containerName: api-server

    minAllowed:

    cpu: 50m

    memory: 64Mi

    maxAllowed:

    cpu: 2

    memory: 4Gi

    For platform options that simplify resource management, review Services Overview.

    Strategy 2: Autoscale Intentionally

    Static replica counts waste money during low-traffic periods and risk outages during traffic spikes. Horizontal Pod Autoscaler (HPA) and Cluster Autoscaler work together to match capacity to demand.

    HPA Configuration

    apiVersion: autoscaling/v2
    

    kind: HorizontalPodAutoscaler

    metadata:

    name: api-server-hpa

    spec:

    scaleTargetRef:

    apiVersion: apps/v1

    kind: Deployment

    name: api-server

    minReplicas: 2

    maxReplicas: 10

    metrics:

    - type: Resource

    resource:

    name: cpu

    target:

    type: Utilization

    averageUtilization: 70

    behavior:

    scaleDown:

    stabilizationWindowSeconds: 300 # Wait 5 min before scaling down

    policies:

    - type: Percent

    value: 25

    periodSeconds: 60 # Remove max 25% of pods per minute

    scaleUp:

    stabilizationWindowSeconds: 30

    policies:

    - type: Percent

    value: 100

    periodSeconds: 60 # Can double pods per minute

    HPA tuning guidelines for SMBs:

    • Set minReplicas to handle your baseline traffic with moderate headroom
    • Set maxReplicas to your budget ceiling, not theoretical maximum
    • Use scale-down stabilization windows (300 seconds) to avoid flapping
    • Scale up aggressively (short stabilization) to handle traffic spikes
    • Use custom metrics (request rate, queue depth) when CPU is not a good proxy for load

    Cluster Autoscaler

    Cluster Autoscaler adds and removes nodes based on pending pod scheduling. Configure it to match your budget constraints:

    ParameterSMB RecommendationWhy

    Min nodes2-3Minimum for HA
    Max nodes5-8Budget ceiling
    Scale down delay10 minutesPrevent thrashing
    Scale down utilization threshold50%Remove underused nodes
    Expanderleast-wastePick node size that wastes least

    Scheduled Scaling

    For workloads with predictable traffic patterns (business hours, weekday peaks), use CronJobs to adjust HPA min/max replicas on a schedule.

    <h1>Scale down at night (10 PM UTC)</h1>
    

    kubectl patch hpa api-server-hpa -p \

    '{"spec":{"minReplicas":1,"maxReplicas":3}}'

    <h1>Scale up for business hours (7 AM UTC)</h1>

    kubectl patch hpa api-server-hpa -p \

    '{"spec":{"minReplicas":2,"maxReplicas":10}}'

    Strategy 3: Govern Resource Requests and Limits

    Without governance, individual developers set resource requests based on habit or copy-paste from examples. Namespace-level controls prevent cost spikes from oversized requests.

    LimitRange: Set Defaults and Caps

    apiVersion: v1
    

    kind: LimitRange

    metadata:

    name: default-limits

    namespace: production

    spec:

    limits:

    - default:

    cpu: 500m

    memory: 512Mi

    defaultRequest:

    cpu: 100m

    memory: 128Mi

    max:

    cpu: 2

    memory: 4Gi

    type: Container

    ResourceQuota: Set Namespace Budgets

    apiVersion: v1
    

    kind: ResourceQuota

    metadata:

    name: namespace-budget

    namespace: production

    spec:

    hard:

    requests.cpu: "8"

    requests.memory: 16Gi

    limits.cpu: "16"

    limits.memory: 32Gi

    persistentvolumeclaims: "10"

    pods: "50"

    Governance enforcement checklist:

    • Every namespace has a LimitRange with sensible defaults
    • Every namespace has a ResourceQuota aligned to its budget
    • CI pipelines reject deployments without explicit resource requests
    • OPA/Gatekeeper policies block pods that request more than the service-level cap

    Compare platform plans that include built-in resource governance at Pricing.

    Strategy 4: Control Observability Cost

    Monitoring infrastructure is often the second-largest cost in a Kubernetes cluster, after compute. High-cardinality metrics, verbose logging, and full-fidelity tracing are the main drivers.

    Metrics Cost Reduction

    • Drop unused metrics with Prometheus relabeling rules (typically 30-50% of metrics are never queried)
    • Reduce high-cardinality labels (user IDs, request IDs, full URLs as labels)
    • Use recording rules to pre-compute frequently queried aggregations
    • Set appropriate scrape intervals: 15s for application metrics, 60s for infrastructure

    Log Cost Reduction

    Log TierRetentionCost LevelContent

    Hot7 daysHighAll logs, full search
    Warm30 daysMediumError/warn logs, sampled info
    Cold90 daysLowError logs only, archived

    • Filter health check logs and other noise at the collection layer
    • Use structured logging to enable efficient filtering
    • Set per-namespace log retention based on service criticality

    Trace Cost Reduction

    • Sample 100% of errors and slow requests (P99)
    • Sample 5-10% of successful requests
    • Use head-based sampling at the ingress point for consistency
    • Reduce trace storage retention to 7 days (most traces are only useful during incident investigation)

    For architecture patterns that include cost-efficient observability, review Cloud Computing.

    Strategy 5: Maintain a Review Cadence

    Optimization without cadence degrades. Resources drift back to overprovisioned states as teams ship new features and forget to revisit allocations.

    Weekly (15 minutes)

    • Review cost anomaly alerts from the past week
    • Check for new orphaned resources (unattached PVCs, unused ConfigMaps)
    • Verify autoscaler behavior (any unexpected scaling events?)

    Biweekly (30 minutes)

    • Rightsizing pass on top 10 cost-driving workloads
    • Review VPA recommendations and apply where safe
    • Check non-production environment scheduling compliance

    Monthly (1 hour)

    • Full cost review by team/namespace with owners present
    • Review and update namespace quotas based on actual usage trends
    • Evaluate committed-use discount opportunities for stable workloads
    • Set optimization action items with owners and due dates

    Quarterly (2 hours)

    • Review overall cluster efficiency and architecture decisions
    • Evaluate node types and instance families against current workload profiles
    • Plan capacity for upcoming product launches or traffic events
    • Benchmark costs against previous quarter and set targets

    Quick Wins Checklist

    Start with these actions for immediate savings:

  • Delete all unattached PersistentVolumeClaims (PVCs)
  • Scale non-production namespaces to zero outside business hours
  • Add LimitRange defaults to every namespace
  • Configure HPA on your top 5 CPU-consuming deployments
  • Drop health check and debug logs at the collection layer
  • Set a ResourceQuota on every namespace
  • Enable cluster autoscaler with conservative max-node limits
  • Review and remove any unused Helm releases
  • For implementation details and tooling alignment, review Cloud Computing and Documentation. For guided planning, use Contact.

    Frequently Asked Questions

    Q: What tools do SMBs need for Kubernetes cost optimization?

    At minimum: Prometheus + Grafana for visibility, kubectl top for quick checks, and VPA in recommendation mode. Kubecost (free tier) adds cost attribution per namespace and workload. You do not need enterprise FinOps platforms at the SMB stage.

    Q: How much can we realistically save with rightsizing alone?

    Rightsizing alone typically reduces compute costs by 25-40% for teams that have never done it. The savings come from closing the gap between resource requests (what you pay for) and actual utilization (what you use). Even modest adjustments yield significant results at scale.

    Q: Is it safe to use VPA in production?

    Use VPA in "Off" mode (recommendations only) for production workloads. VPA in "Auto" mode restarts pods to apply new resource settings, which causes brief disruption. For production, review VPA recommendations manually and apply during maintenance windows.

    Q: How do we prevent cost regressions after optimization?

    Governance is the key: LimitRange defaults, ResourceQuotas, CI policy checks, and a monthly review cadence. Without these guardrails, costs creep back up within 2-3 months as teams ship new features with default resource allocations.

    Q: Should SMBs consider managed Kubernetes to save costs?

    Managed Kubernetes (EKS, GKE, AKS) eliminates control plane management costs but adds per-cluster fees. For SMBs running 1-3 clusters, managed services usually save money by reducing operational overhead. The optimization strategies in this guide apply regardless of whether you self-manage or use managed Kubernetes.