Sign In

Curriculum 27: Performance & Optimization

API Server Load

18 min · 35 XP

Reducing API Server Load

The Kubernetes API server is the central control plane component. Excessive API calls from controllers, scripts, or monitoring tools can degrade cluster performance. Understanding how to minimize load is critical for production clusters.

The Problem with Polling

Repeatedly listing resources puts significant pressure on etcd and the API server:

# Bad: polling every 5 seconds in a script
while true; do
  kubectl get pods -A
  sleep 5
done

Each list call forces the API server to read from etcd and serialize the full response. In large clusters with thousands of pods, this is expensive.

Using Informers

Client-go informers maintain a local cache that stays synchronized via the watch API. Instead of repeatedly querying the API server, informers receive incremental updates:

// Informer establishes a single watch connection
// and maintains a local cache
factory := informers.NewSharedInformerFactory(clientset, 30*time.Second)
podInformer := factory.Core().V1().Pods().Informer()

podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
    AddFunc:    func(obj interface{}) { /* handle new pod */ },
    UpdateFunc: func(old, new interface{}) { /* handle update */ },
    DeleteFunc: func(obj interface{}) { /* handle deletion */ },
})

factory.Start(stopCh)

Watch vs List

# Good: use watch to stream changes
kubectl get pods --watch

# Efficient: use field selectors to narrow results
kubectl get pods --field-selector=status.phase=Running

# Use label selectors to reduce response size
kubectl get pods -l app=myapp

# Use resourceVersion to only get changes since last query
kubectl get pods --resource-version=12345 --watch

Best Practices

  • Replace polling loops with --watch or informers.
  • Use label and field selectors to limit response sizes.
  • Set appropriate resync periods in controllers (not too frequent).
  • Use server-side filtering instead of client-side filtering.