advanced26 min studyLesson 347 in Engineering

CPU quota: a shared time budget rather than dedicated cores

Relate cgroup v2 quota and period to aggregate CPU time, bursty parallel consumption, hierarchical throttling, and measured scheduling behavior.

On this page

What you’ll understand

  • Convert a cpu.max quota/period pair into a CPU-time bandwidth ratio.
  • Explain why multiple runnable threads can exhaust a shared budget early.
  • Distinguish quotas, weights, CPU placement, and ancestor constraints.

A service with a quota equivalent to one CPU can still run several threads simultaneously on several CPUs and then be throttled. Its budget limits aggregate CPU time over the configured accounting period; it does not reserve a physical core or guarantee smooth execution. This lesson concerns Linux 6.12 cgroup v2 cpu.max for fair-class workloads, with burst accumulation disabled in the simplified examples. Real-time scheduling, newer scheduler integrations, per-CPU accounting slices, and ancestor policies require their own documented treatment.

Quota and period define a bandwidth budget

cpu.max supplies a maximum CPU-time budget and a period, conventionally expressed in microseconds by the interface. A quota of 150000 over period 100000 corresponds to 1.5 CPU-seconds per wall-clock second in the ideal average interpretation. It does not identify which CPUs will provide that time. The value max means no local quota restriction, but does not override an ancestor's finite budget, affinity restrictions, or competition. Read the effective hierarchy before concluding that an apparently unlimited child has unlimited execution capacity.

Threads in the same cgroup share the aggregate budget. If enough CPUs are available, parallel threads can consume several units of CPU time during one unit of elapsed time. Once the applicable budget is exhausted, runnable work can be throttled until replenishment. Actual accounting uses implementation mechanisms such as per-CPU runtime slices, so a simple rectangular budget picture is a teaching approximation. Short bursts, alignment, and configured burst behavior can differ from a naive exact cap on every arbitrary measurement window.

U=QPU=\frac QP
Q and P use the same CPU-time and wall-time units, such as microseconds. U is a dimensionless CPU-equivalent bandwidth ratio for the stated fair-class quota model, not a count of reserved cores or a guaranteed throughput. Q is finite and nonnegative here; max is handled separately.↔ Scroll wide equations horizontally.

Parallelism and hierarchy change the latency pattern

For an idealized fresh period with p continuously running threads on p available CPUs, a shared quota Q can be consumed in Q/p elapsed time. This estimate ignores slices, preemption, system overhead, and other constraints. If the interval is shorter than the period, later arrivals can wait behind throttling even when a whole-second utilization graph looks modest. A burst of request workers can therefore worsen tail latency without increasing the configured average budget. Measure the scheduling pattern before blaming the application's lock implementation.

CPU weight distributes contested fair-class capacity relative to siblings; it is not a hard ceiling or an idle-machine reservation. CPU placement and cpuset rules constrain where execution can occur, but selecting CPUs alone does not necessarily make them exclusive or eliminate shared-cache interference. Ancestor quota exhaustion can throttle a child that has local runtime remaining. With different periods, transient details require the real hierarchy, while steady aggregate budget reasoning still rules out interpreting a generous child limit as a promise of independent capacity.

tideal exhaust=Qp,Uchild,avg≤min⁡kQkPkt_{\rm ideal\ exhaust}=\frac Qp,\qquad U_{\rm child,avg}\le\min_k\frac{Q_k}{P_k}
The first estimate assumes a fresh finite budget and p positive parallel workers, ignoring accounting granularity. The second is a steady budget upper bound over the constrained child-to-ancestor path under the simplified model; siblings can consume part of ancestor budgets, so it is not a guaranteed allocation.↔ Scroll wide equations horizontally.

Use counters with a workload-specific experiment

Read cpu.stat counters and their units, including usage and throttling information, across a defined interval. A high ratio of throttled periods is not automatically the same percentage of wall time lost, and summing per-thread waiting can exaggerate a single request's delay. Correlate request arrival, runnable threads, CPU pressure, ancestor usage, and runtime versions. Compare a lower worker count, a different period, or an adjusted budget one at a time with the same workload. A quota change cannot promise a proportional application speedup if memory or I/O dominates.

The queue lab illustrates only offered work versus average service. Reset, explicitly set arrival four and service three, predict growth, then Play or Step. For a separate stable run Reset and explicitly set arrival two and service three before predicting and playing. The rates are normalized work items per second, not cpu.max fields. Edits preserve elapsed time and recompute from four initial jobs. This fluid curve cannot show quota-period bursts, throttled intervals, CPU weights, placement, or scheduler accounting.

Spend one budget with three parallel workers

In an idealized fresh accounting period, quota Q is 150 ms of aggregate CPU time and period P is 100 ms. Three workers can each run continuously on separate available CPUs. Assume zero configured burst, no ancestor restriction, no contention, and ignore slice/granularity effects.

  1. The quota ratio is 150/100=1.5 CPU-equivalents on average. This is not a reservation of one and a half particular physical cores.

  2. Three simultaneous workers consume three milliseconds of aggregate CPU time per elapsed millisecond. They spend 150 ms of budget in 150/3=50 ms of wall time in this simplified model.

  3. If they remain runnable, the ideal picture then has 50 ms until the next 100 ms period boundary without new budget. Actual timing can differ under the omitted scheduler accounting and workload behavior, so use counters and traces to test the real latency pattern.

The result

The same average quota can produce a burst followed by throttling. Parallel execution and a CPU-time budget are compatible, and neither implies dedicated cores.

Explore the model

Interactive lab

Interactive lab · queue

Average capacity cannot show quota-period jitter

Compare separate normalized fixed-rate runs using Reset → explicitly set both λ and μ → predict → Play or Step. Use (4,3), then Reset and (2,3). Edits retain elapsed t and recompute from four initial jobs. The fluid model has no cpu.max period, runtime slices, throttling, CPU affinity, or weights.

Average capacity cannot show quota-period jitterFluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Current readings: Fluid backlog: 4; Net rate · λ − μ: −1 /s; M/M/1 mean residence: 1 s. All parameters are adjustable with the labeled controls below.02.557.51001.534.56Elapsed time · sFluid backlogλ < μ
Fluid backlogCurrent time
Fluid backlog
4
Net rate · λ − μ
−1 /s
M/M/1 mean residence
1 s
t = 0 s

Fluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.

Look forAverage offered load matters, but a smooth backlog model cannot explain the period-level latency caused by a shared CPU quota.

Check your understanding

A fair-class cgroup has cpu.max equivalent to two CPU-seconds per second. What does that configure by itself?

Try it yourself

A child has finite quota/period ratio 2.0 while its ancestor's ratio is 1.0, shared with other work. What steady upper bound follows from these ratios? In a separate ideal period, 25 ms quota over 100 ms period is consumed by four fully parallel workers; when is it exhausted?

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

A child's budget cannot remove an ancestor constraint. Divide aggregate quota by parallel workers only under the stated ideal assumptions.

Compare with the solution

The child's steady quota upper bound is at most min(2.0,1.0)=1.0 CPU-equivalent, and competition for the ancestor budget can reduce its actual share. This is not a guaranteed allocation. In the separate fresh-period example, four workers consume 25/4=6.25 ms of wall time to spend 25 ms of aggregate CPU budget. Real accounting slices, preemption, and available CPU placement can change observed timing; the arithmetic is not an exact scheduler simulation.

Take it with you

  • Quota divided by period is an aggregate bandwidth ratio, not dedicated cores.
  • Parallel workers can exhaust a shared budget early and create throttling latency.
  • Weights, CPU placement, ancestors, and actual counters must be interpreted separately.

Read further

Original sources and deeper explanations to follow at your own pace.

Optional progress, saved in this browser when available. Revisit any lesson at any time.

Lesson not marked complete.