Kubernetes API Priority and Fairness (APF) Explained

Updated on
10 min read

Kubernetes API Priority and Fairness (APF) controls how the Kubernetes API server handles competing requests when demand approaches its capacity. Cluster operators and platform engineers can use it to keep important control-plane traffic moving without letting one noisy client monopolize the server. This explainer covers how APF classifies requests, separates traffic, queues bursts, and exposes overload behavior.

Why Kubernetes API Priority and Fairness Is Discussed

The Kubernetes API server is a shared control-plane service. Nodes, controllers, operators, CI systems, and people using kubectl all make requests to it. A sudden wave of list, watch, or update activity can consume request-handling capacity just as a controller needs to renew a lease or a node needs to report its health.

The older in-flight request limits can cap the total number of requests being served, but they do not decide which clients should receive that capacity first. API Priority and Fairness adds classification and isolation so that an overloaded cluster can preserve progress for higher-priority operations while managing less important traffic.

What Is Kubernetes API Priority and Fairness?

APF is a built-in kube-apiserver mechanism that classifies each eligible request and controls how much work can execute concurrently. It is stable and enabled by default in Kubernetes. The Kubernetes project provides the platform’s broader API and workload orchestration; APF is one control-plane feature that protects access to that API.

The official API Priority and Fairness documentation describes two main configuration resources: FlowSchemas select requests based on attributes such as user, group, verb, resource, and namespace; PriorityLevelConfigurations define how matching requests share concurrency and what happens when that capacity is occupied.

APF does not speed up the API server or create additional compute resources. It determines how available request-processing capacity is divided when demand competes for it.

The Problem APF Solves

Without request isolation, a burst from one client can occupy a large portion of the API server’s in-flight capacity. The result can be control-plane contention: a noisy controller may delay other controllers, and interactive requests can add further load. The server still needs a way to reject excess work, but a single global ceiling cannot distinguish routine background work from operations needed to keep the cluster functioning.

APF creates separate priority levels and a limited amount of queuing. This lets administrators reserve a stronger share of the concurrency budget for important request classes and distribute capacity among request sources within a class. A short burst can wait briefly in a queue instead of immediately failing; sustained demand beyond configured limits can still be rejected.

The HTTP standards-track RFC 6585 defines status code 429, “Too Many Requests,” for rate limiting and permits a response to include Retry-After. Kubernetes APF uses HTTP 429 when a request is rejected by its flow-control limits. Clients should use backoff and honor retry guidance when the server provides it rather than retrying continuously.

How APF Works

An eligible request passes through classification, priority assignment, and dispatch:

  1. The API server checks FlowSchemas in matching-precedence order. The first matching schema wins.
  2. The schema assigns the request to a priority level and may distinguish flows by user or namespace.
  3. If the level has concurrency available, the request executes. If it is full, the level either queues or rejects the request, depending on its configuration.
Overload control What it limits What happens when capacity is reached
In-flight limits without APF Overall requests being served Excess requests cannot be admitted; there is no APF classification or per-flow queueing
APF with Reject handling Concurrency for one priority level Excess requests are rejected, commonly with HTTP 429
APF with Queue handling Concurrency plus a bounded queue Excess requests wait briefly; requests can still be rejected if queues fill or a wait limit expires

With APF enabled, the API server’s configured mutating and non-mutating in-flight limits contribute to a shared concurrency budget. Priority levels divide that budget using nominal concurrency shares, rather than a fixed count of requests. The server can adjust how much unused capacity is lent or borrowed between levels within configured bounds. A request may occupy more than one concurrency “seat” when the API server estimates that it will consume more work, such as a large list response.

FlowSchemas and Priority Levels

A FlowSchema matches requests using rules over subjects and request attributes. Subjects can include a user, group, or service account. Resource rules can select API groups, resources, verbs, and namespaces; non-resource rules can match API paths such as health endpoints. matchingPrecedence determines evaluation order, with the numerically smaller value checked first.

A PriorityLevelConfiguration sets a level’s nominal concurrency shares and its overload behavior. With Queue, settings such as the number of queues, queue length limit, and hand size trade memory use and burst tolerance against latency and fairness. With Reject, the server turns away requests that cannot execute within the level’s limit. A FlowSchema only assigns requests; the priority level determines their concurrency and queue behavior.

Flows and Fair Queuing

Within one priority level, APF separates requests into flows. A flow is identified by its matching FlowSchema and an optional distinguisher, such as the requesting user or the target namespace. Requests from one flow therefore do not automatically share one queue with every other flow in the level.

When queuing is enabled, APF uses shuffle sharding to assign flows to a subset of queues, then fair queuing to make progress among competing flows. This reduces the chance that one busy client will crowd out all other clients in the same level. Fairness is scoped: a flow cannot gain capacity reserved for another priority level simply because it has many requests.

APF Components and Key Concepts

  • Priority level: A concurrency pool for a class of requests, with a policy for requests that cannot run immediately.
  • FlowSchema: A matching rule that assigns requests to one priority level. Only the first matching schema applies.
  • Flow distinguisher: An optional user- or namespace-based key that separates requests into flows.
  • Queue and shuffle sharding: A bounded waiting path that spreads flows across queues to improve isolation during short bursts.
  • Concurrency seat: A unit of capacity used to account for active request work; some requests can occupy multiple seats.
  • Exempt traffic: Requests assigned to the mandatory exempt level bypass APF limits. Built-in defaults also include a catch-all fallback and suggested levels for node, system, controller, and general workload traffic.

The suggested defaults are intended as a workable starting point, not a guarantee that every cluster’s traffic is classified ideally. The API server maintains certain mandatory and suggested objects. Before changing one, check whether it is server-managed; editing or deleting defaults can have effects that differ from ordinary Kubernetes resources.

APF also has a scope boundary. Some long-running requests, such as remote command execution and log tailing, are not subject to the APF filter. Watch requests are subject to APF. This distinction matters when diagnosing load: not every open API connection is necessarily consuming APF queue or concurrency capacity in the same way.

Real-World Uses

APF is useful when a cluster has different kinds of API traffic with different operational importance. For example, operators can keep node health updates and built-in controller work separate from less critical workload-controller traffic. A misbehaving service account that repeatedly lists resources can then be isolated within its classified level rather than freely consuming capacity intended for other flows.

Multi-tenant platforms can distinguish request classes by user, group, or namespace, provided authentication and FlowSchema rules reflect the actual workload identities. Teams can also use APF to manage bursty automation or interactive administration requests, but should avoid assuming that labels alone provide a security boundary: APF is traffic scheduling, not authorization. RBAC still controls which API operations a caller may perform.

APF is most useful when request patterns and failure priorities are understood. A small or lightly loaded cluster may need only Kubernetes’ suggested configuration. Custom rules add complexity and can starve traffic if they reserve too much concurrency, classify clients incorrectly, or select Reject without accounting for normal bursts.

Getting Started: Inspect and Monitor APF

Start by reading the active FlowSchemas and priority levels. These commands do not change cluster configuration:

kubectl get flowschemas
kubectl get prioritylevelconfigurations
kubectl describe flowschema <flow-schema-name>
kubectl describe prioritylevelconfiguration <priority-level-name>

Check which rules capture the clients you care about, the precedence of overlapping schemas, whether requests are distinguished by user or namespace, and whether a level queues or rejects overflow. A request can match only one FlowSchema, so a lower-priority-looking rule will not apply if an earlier rule already matches it.

The API server exports APF metrics that help distinguish queue pressure from active execution and rejection. If your account is authorized to read the API server’s metrics endpoint, inspect the flow-control series with:

kubectl get --raw /metrics | grep '^apiserver_flowcontrol_'

Useful metrics include apiserver_flowcontrol_rejected_requests_total, apiserver_flowcontrol_current_inqueue_requests, apiserver_flowcontrol_current_executing_requests, apiserver_flowcontrol_request_wait_duration_seconds, and apiserver_flowcontrol_nominal_limit_seats. Interpret rejection counters with their flow_schema, priority_level, and reason labels. A growing queue and rising wait duration suggest a different pressure pattern from immediate rejections.

If you see 429 responses, identify the matching FlowSchema and priority level before changing limits. Then check whether the client is retrying with backoff, whether an unexpectedly broad rule captures it, and whether the queue is full or the level is configured to reject. Make one scoped change at a time and observe its effect; avoid increasing every concurrency share as a first response, since APF distributes a finite API-server budget.

Common Misconceptions

“APF is just a global rate limit.” It is a request-classification and concurrency-management system. The same total demand can be handled differently depending on which FlowSchema and priority level match each request.

“A high priority guarantees that requests never fail.” Priority levels receive bounded shares of a finite budget. Queued work can wait too long, queues can fill, and configured rejection can return 429. Exempt traffic is a special case and should be used sparingly.

“Fair queuing means every request gets equal service.” Fairness is applied between flows within a priority level, not across the whole cluster and not as equal priority among every user. Classification, distinguishers, seat usage, and the level’s share all affect the result.

“APF replaces RBAC or fixes overloaded control planes.” APF does not grant permissions, add API-server capacity, or guarantee that a slow storage backend becomes healthy. It governs how API-server request capacity is shared; authentication, authorization, and control-plane sizing remain separate responsibilities.

Changelog

  • Initial publication.
  • Last updated: 2026-11-11.
TBO Editorial

About the Author

TBO Editorial writes about the latest updates about products and services related to Technology, Business, Finance & Lifestyle. Do get in touch if you want to share any useful article with our community.