Coding

Kubernetes v1.36: Server-Side Sharded List and Watch

As Kubernetes clusters balloon to tens of thousands of nodes, a scaling bottleneck emerges for controllers watching high-cardinality resources like Pods, with each replica incurring CPU, memory, and network costs to deserialize unnecessary events. Kubernetes v1.36 addresses this issue with an alpha feature: server-side sharded list and watch, which filters events at the source, reducing per-replica costs and enabling more efficient horizontal scaling. This innovation promises to alleviate a major pain point for large-scale Kubernetes deployments.

Kubernetes v1.36 introduces an alpha feature that moves event filtering from the client to the API server, reducing per-replica CPU, memory, and network costs for horizontally scaled controllers watching high-cardinality resources like Pods.

The problem

In large clusters with tens of thousands of nodes, controllers that watch high-cardinality resources face a scaling bottleneck. Every replica of a horizontally scaled controller receives the full stream of events from the API server. Each replica pays the CPU, memory, and network cost to deserialize every event, only to discard objects it is not responsible for. Scaling out the controller does not reduce per-replica cost — it multiplies it.

Some controllers, such as kube-state-metrics, already support client-side sharding. Each replica is assigned a portion of the keyspace and discards objects outside its range. This works functionally but does not reduce the volume of data flowing from the API server: N replicas still receive the full event stream, network bandwidth scales with replicas, and CPU spent on deserialization is wasted for the discarded fraction.

How server-side sharding works

Kubernetes v1.36 (KEP-5866) adds a shardSelector field to ListOptions. Clients specify a hash range using the shardRange() function, for example:

shardRange(object.metadata.uid, '0x0000000000000000', '0x8000000000000000')

The API server computes a deterministic 64-bit FNV-1a hash of the specified field and returns only objects whose hash falls within the range [start, end). This applies to both list responses and watch event streams. The hash function produces the same result across all API server instances, so the feature is safe to use with multiple API server replicas.

Currently supported field paths are object.metadata.uid and object.metadata.namespace.

Using sharded watches in controllers

Controllers typically use informers to list and watch resources. To shard the workload, each replica injects the shardSelector into the ListOptions used by its informers via WithTweakListOptions:

import (
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/informers"
)

shardSelector := "shardRange(object.metadata.uid, '0x0000000000000000', '0x8000000000000000')"

factory := informers.NewSharedInformerFactoryWithOptions(
    client,
    resyncPeriod,
    informers.WithTweakListOptions(func(opts *metav1.ListOptions) {
        opts.ShardSelector = shardSelector
    }),
)

For a 2-replica deployment, the selectors split the hash space in half:

  • Replica 0: shardRange(object.metadata.uid, '0x0000000000000000', '0x8000000000000000')
  • Replica 1: shardRange(object.metadata.uid, '0x8000000000000000', '0x10000000000000000')

A single replica can also cover non-contiguous ranges using ||:

"shardRange(object.metadata.uid, '0x0000000000000000', '0x4000000000000000') || " +
"shardRange(object.metadata.uid, '0x8000000000000000', '0xc0000000000000000')"

Verifying server support

When the API server honors a shard selector, the list response includes a shardInfo field in the response metadata that echoes back the applied selector:

{
  "kind": "PodList",
  "apiVersion": "v1",
  "metadata": {
    "resourceVersion": "10245",
    "shardInfo": {
      "selector": "shardRange(object.metadata.uid, '0x0000000000000000', '0x8000000000000000')"
    }
  },
  "items": [...]
}

If shardInfo is absent, the server did not honor the shard selector and the client received the complete, unfiltered collection. In this case, the client should be prepared to handle the full result set, for example by applying client-side filtering to discard objects outside its assigned shard range.

Getting started

This feature is in alpha and requires enabling the ShardedListAndWatch feature gate on the API server. The Kubernetes team is seeking feedback from controller authors and operators running large clusters.

Bottom line

Server-side sharded list and watch addresses a real scaling pain point for large Kubernetes deployments. By moving filtering into the API server, it reduces per-replica overhead and makes horizontal scaling of controllers more efficient. The feature is straightforward to adopt for controllers already using informers, and the shardInfo field provides a clear way to verify that the server is honoring the shard selector.

Similar Articles

More articles like this

Coding 1 min

How I made $350K from an open-source JavaScript library using dual licensing

A savvy developer's unorthodox business model, leveraging dual licensing of an open-source JavaScript library, has yielded a substantial $350,000 windfall, highlighting the untapped potential for profit in the open-source ecosystem. By offering a commercial license for the library's proprietary features, the developer has successfully monetized the project, illustrating the value of strategic licensing strategies in the open-source software market. This lucrative outcome underscores the complexities of open-source economics.

Coding 1 min

Apple is enforcing an old App Store rule against a new kind of software

Apple is cracking down on "containerized" apps, a type of software that bundles third-party code within a proprietary framework, forcing developers to rearchitect their products to comply with a 2014 App Store guideline that has only now become a point of contention. The move affects apps that use technologies like Docker and Kubernetes to package and deploy code. Developers are scrambling to adapt to the new enforcement.

Coding 2 min

AI Subagents 'Coming Soon' to Visual Studio Copilot

AI Subagents 'Coming Soon' to Visual Studio Copilot Visual Studio Magazine

Coding 1 min

Show HN: PHP-fts – Full-text search engine in pure PHP, no extensions

A lightweight, extension-free full-text search engine emerges in PHP, leveraging a novel combination of trie data structures and inverted indexing to deliver rapid query performance, with a claimed 10,000 documents searchable in under 1 second on a single core. This self-contained implementation sidesteps the need for external libraries, instead relying on PHP's built-in functionality to index and query text data. Its potential impact on resource-constrained web applications is significant.

Coding 1 min

BYD overtakes Tesla and Kia as the best-selling EV brand in key overseas markets

In a seismic shift in the global electric vehicle landscape, BYD's dominant market share in China and Southeast Asia has propelled it past Tesla and Kia to become the top-selling EV brand in key overseas markets, with the Chinese giant's e-platform 3.0 architecture and extensive dealership network driving its success. BYD's sales surge is particularly pronounced in countries like Indonesia and Malaysia, where its affordable models have captured a significant share of the growing EV market. The company's rapid expansion now poses a significant challenge to established EV leaders.

Coding 1 min

Going Full Time on Open Source

After a decade at Stripe, engineer Daniel X. Moore is betting his livelihood on a radical premise: that a single open-source tool—his TypeScript-native runtime **Effect TS**—can outmaneuver Node.js and Deno by baking algebraic effects, structured concurrency, and zero-cost dependency injection into the language itself. With $1.2M in pre-seed funding, Moore’s pivot tests whether the enterprise will pay for a runtime that treats side effects as first-class citizens, not afterthoughts.