QoS IOPS Limiting - Pure IOPS

AI Tools

Lightbits Quality of Service (QoS) rate-limit policies allow you to cap a volume's read and write throughput. Limits can be expressed as bandwidth, IOPS, or IOPS-per-GB of volume capacity.

This article describes how IOPS and IOPS-per-GB limits are enforced, through a policy option called Pure IOPS.

Pure IOPS Overview

Previously, a Lightbits IOPS limit was a bandwidth budget derived from a 4 KiB block size. So the IOPS that a volume actually achieved fell as the application's I/O size grew. Pure IOPS removes this mismatch between configured and delivered IOPS.

CSPs package and sell storage in tiers, and those tiers are almost always expressed in IOPS. A tenant subscribes to "10,000 IOPS," not "X MB/s at a 4 KiB block size." When a budget-conscious or subscription-capped tenant runs a workload with larger I/Os, the prior behavior silently delivers far fewer IOPS than the tenant contracted for.

That drives the following:

  • SLA and billing disputes - paying for an IOPS tier that cannot actually be reached.

  • Support load - paying for 10K IOPS but only getting 2.5K issues that are actually a unit-of-measure mismatch.

  • Imprecise monetization and capacity planning - when the real cap floats with block size, it is difficult to map a price tier to a guaranteed entitlement or to oversubscribe predictably.

With Pure IOPS, a CSP can enforce exactly the IOPS tier a tenant subscribed to, independent of how the tenant drives I/O. The cap matches the contract, tiers become clean and defensible, multi-tenant fairness improves, and IOPS-based pricing offerings become straightforward to operate.

For enterprises and other non-CSP users, the same predictability is valuable anywhere you want fine-grained QoS control over volumes and tenants - noisy-neighbor isolation, dependable per-volume performance ceilings, and IOPS numbers that hold steady across mixed and large-block workloads. That makes benchmarking, capacity planning, and chargeback far more reliable, because the configured limit behaves consistently regardless of application I/O size.

Enabling Pure IOPS

When Pure IOPS is enabled on the policy, each I/O operation counts as exactly one unit (1 IOP) toward the configured limit, independent of its size. so a configured "5,000 IOPS" limit delivers 5,000 IOPS no matter what block size the application uses. The internal bandwidth translation (the × 4096 step) is no longer applied.

each I/O = 1 unit, regardless of size

Example: IOPS Limit Configured to 5,000 with Pure IOPS

Application I/O Size

Actual IOPS Achieved

4KiB

~5,000 IOPS

8 KiB

~5,000 IOPS

128 KiB

~5,000 IOPS


The configured limit now means exactly what it says - 5,000 IOPS - for every I/O size. This makes the limit predictable and size-independent, which matches the common expectation of an "IOPS limit".

This applies to both limit types:

  • IOPS — the configured value is the absolute IOPS cap for the volume.

  • IOPS-per-GB — the effective cap is per-GB limit × volume capacity in GB, and each I/O still counts as one unit toward that effective cap.

Pure IOPS is opt-in and defaults to disabled, so existing policies and behavior are unchanged unless you explicitly turn it on.

Using lbcli

Add the --pure-iops flag when creating or updating an IOPS/IOPS-per-GB policy:

# Create a policy lbcli create qos-policy --name=my-policy --type iops \ --write-limit 5000 --read-limit 5000 --pure-iops # Update an existing policy lbcli update qos-policy --name=my-policy --type iops \ --write-limit 5000 --read-limit 5000 --pure-iops

Using the REST API

Set the pureIops field to true on the QoS policy when creating or updating it:

{ "name": "my-policy", "limitIops": { "readIops": 5000, "writeIops": 5000 }, "pureIops": true }

Verify the Setting

The current value is shown in the policy listing:

lbcli list qos-policies -o json

The output includes a pureIops field (true or false) for each policy.

Validation and Compatibility

  • Default is disabled. When pureIops is false (the default), the behavior is identical to before this change. Existing policies are unaffected.

  • Only valid with IOPS-based limits. Pure IOPS can be combined only with the iops or iops-per-gb limit types. Combining it with a bandwidth limit is rejected with an InvalidArgument error, since bandwidth limiting is inherently byte-based.

  • Applies on create and update. This option can be set when creating a new policy, or applied to an existing policy via an update.