advanced27 min studyLesson 444 in Engineering

Storage fairness: count operations and bytes separately

Calculate request-size-dependent ceilings and trace buffered I/O attribution before interpreting a device limit as a tenant service guarantee.

On this page

What you’ll understand

  • Convert fixed-size I/O rates between operations and bytes.
  • Explain why application requests and device operations need not match.
  • Separate storage authorization from performance isolation.

A checkpoint writer issuing large sequential writes and a retrieval worker issuing small random reads can collide on the same storage path while reporting similar application request counts. Their byte volumes, queue occupancy, and durability costs differ. Linux 6.12 cgroup v2 provides per-device I/O controls, but those controls operate within a block-I/O accounting and enforcement path. They do not automatically create a reservation in a remote object store or prove that tenants cannot read each other’s files.

Operation rate and byte rate impose different ceilings

An IOPS limit counts operations in the relevant accounting domain; a bytes-per-second limit counts data volume. For fixed-size operations, multiplying operation rate by size relates the two. Small requests often reach an operation ceiling before a byte ceiling, while large requests can reach the byte ceiling first. This is an accounting model, not a performance prediction: device latency, read/write asymmetry, queue depth, random versus sequential access, and competing work can keep achieved throughput below either configured ceiling.

Distinguish an application-level lookup or checkpoint call from block requests. A lookup can be satisfied by a page cache without device I/O, or trigger several metadata and data reads. Filesystem merging, splitting, compression, copy-up, and writeback can change counts and timing. A “thousand requests” application metric therefore cannot be compared directly to a thousand block operations without tracing the path. For AI workloads, report request-size distributions and durability requirements alongside totals; a buffered write accepted into memory has not necessarily reached the persistence boundary the application needs.

B=λs,λ≤min⁡ ⁣(Imax⁡,Bmax⁡s)B=\lambda s,\qquad\lambda\le\min\!\left(I_{\max},\frac{B_{\max}}{s}\right)
For positive fixed operation size s in bytes, λ is operations per second, B is bytes per second, Imax is an operation-rate ceiling, and Bmax a byte-rate ceiling. The minimum is a necessary configured-rate bound in a matching accounting domain, not guaranteed device throughput.↔ Scroll wide equations horizontally.

Trace the device and the charge owner

Linux io.max identifies limits for a particular block device and resource direction. Inspect the effective hierarchy and underlying storage layout: a filesystem can sit above multiple layers, and the bottleneck may be elsewhere. Buffered writeback attribution depends on filesystem and kernel support and on which cgroup owns the writeback work. Shared inode patterns can complicate that ownership. A leaf’s application byte counter alone does not establish that the intended cgroup receives every relevant device charge. Compare application, filesystem, and device evidence before drawing a tenant-level conclusion.

A ceiling is also different from a minimum service entitlement. Throttling one writer can reduce interference without ensuring that a reader meets a tail-latency objective under every queue state. Remote storage adds server-side quotas, authentication, replication, and network bottlenecks beyond the local block controller. Define whether the claim covers local block traffic, a storage service account, a volume, or an object namespace. Enforce object and file permissions separately; traffic shaping cannot prevent an authorized path with an incorrect tenant check from exposing another customer’s checkpoint.

Ruseful=Ncompleted within deadlineTR_{\rm useful}=\frac{N_{\rm completed\ within\ deadline}}{T}
Useful storage goodput is completed application operations within the specified deadline divided by a positive observation duration T in seconds. Its unit is useful operations per second; it is not the same counter as device IOPS.↔ Scroll wide equations horizontally.

Construct an aggressor that tests the promised boundary

Keep the victim’s query distribution and cache state controlled, then vary aggressor request size, read/write mix, queue depth, and persistence behavior. A large buffered write test can expose writeback bursts that a direct-read test misses. Include a quiet baseline, a saturated aggressor, and a recovery phase while recording errors and unfinished work. If the victim appears faster when requests time out, completed-request latency alone is a misleading oracle. Match the measurement to the promised useful service and identify which device or remote dependency actually saturated.

Use the queue lab only for average normalized pressure. Reset, explicitly set arrival four and service three, predict growth from four pending items, then Play or Step. For an independent comparison Reset and explicitly set arrival two and service three before predicting drainage. Both rate values must be restored after Reset; an edit at nonzero time recomputes from the initial backlog. There are no blocks, page cache, request sizes, durability barriers, or I/O schedulers here. The real storage experiment supplies those missing mechanisms.

One pair of limits produces two different request ceilings

A hypothetical device-accounting domain has ceilings of 1,000 operations per second and eight mebibytes per second. Compare fixed four-kibibyte operations with fixed 64-kibibyte operations, ignoring all other bottlenecks.

  1. Eight mebibytes equals 8,388,608 bytes. Dividing by 4,096 bytes yields a byte-derived ceiling of 2,048 operations per second. The smaller configured ceiling is therefore 1,000 operations per second for four-kibibyte operations.

  2. At that operation ceiling, four-kibibyte requests move 4,096,000 bytes per second, or 3.90625 mebibytes per second. Unused byte allowance cannot bypass the independent operation ceiling.

  3. For 65,536-byte operations, the byte-derived ceiling is 128 operations per second. That is below 1,000, so the byte ceiling binds. The modeled traffic is then eight mebibytes per second, although achieved throughput may still be lower.

The result

Equal IOPS settings do not imply equal achievable request rates across sizes, and neither ceiling promises latency or minimum service.

Explore the model

Interactive lab

Interactive lab · queue

Normalized queue pressure is not a block-I/O trace

Use independent Reset → set BOTH rates → predict → Play/Step experiments for (λ,μ)=(4,3) and (2,3). Each recomputes q=max(0,4+(λ−μ)t). Rates are abstract items per model second, not measured storage IOPS.

Normalized queue pressure is not a block-I/O traceFluid 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 forBacklog arithmetic motivates an admission margin, while real attribution and request sizes determine storage isolation.

Check your understanding

A tenant performs 500 application reads per second while its block counter records 100 operations per second. What is the sound next interpretation?

Try it yourself

A hypothetical fixed-size path has ceilings of 500 operations per second and four mebibytes per second. For 16-kibibyte operations, calculate the configured rate bound. Does achieving it prove fsync latency isolation?

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

Give me a hint

Convert both byte prefixes consistently and keep rate ceilings separate from persistence and latency.

Compare with the solution

Four mebibytes divided by 16 kibibytes is 256 operations per second. The minimum of 500 and 256 is 256, so the byte ceiling binds in this simplified matching domain. This is an upper bound, not promised achieved service. Reaching that average does not establish an fsync deadline: writeback, device queues, barriers, other tenants, and the actual durability path still matter. Test the required persistence operation and count deadline failures and unfinished requests instead of replacing that evidence with an average bandwidth observation.

Take it with you

  • IOPS and byte ceilings bind differently as request size changes.
  • Trace application work through cache, filesystem, writeback, and device accounting.
  • Validate useful durable service and storage authorization 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.