Why AI Coding Assistant Quotas Are Misleading: Rate Caps vs. Total Limits

    A lawsuit over an AI coding assistant's subscription tiers exposed a common pricing problem: advertised usage multipliers that don't match what users actually receive. This article explains why the gap appears (a short 5-hour rate window versus weekly and monthly total caps), walks through a quantitative model showing how the binding constraint decides real deliverable usage, and proposes how to define unambiguous quotas with a token-bucket-plus-counter design, model-weighted units, and a single period multiplier. It closes with practical checklists for platform providers and enterprise buyers on making quotas readable, verifiable, and observable.

    1. Case Recap: A Dispute Over Multipliers

    An AI coding assistant vendor (referred to here as “the vendor”) launched two higher-tier subscription plans: a mid tier at $100/month and a high tier at $200/month. The vendor advertised their usage quotas as 5x and 20x the entry tier, respectively. In June 2025, two consumers filed a lawsuit with the following core claims:

    1. The actual multipliers fall far short of the advertisement. Using one model as an example, they calculated that on a weekly basis the high tier delivers only 6x the entry tier and the mid tier only 3.5x.
    2. The difference comes from the quota window. High-tier users do get 5x or 20x the entry-tier quota within each 5-hour window, but the weekly total was not scaled up by the same ratio.
    3. The vendor’s position is that the multiplier refers to a “single usage period.” The vendor argued that the advertised multipliers describe the quota within a single usage period (the 5-hour window), citing an explanation on the help page.
    4. The court’s ruling. In November of the same year, a U.S. federal magistrate judge ruled that the vendor must continue to defend the primary allegations that its advertising “potentially misleads consumers,” while dismissing several other claims.
      • The court found that the explanation about the single usage period required clicking through two links from the main sales page.
      • Users pay monthly and could reasonably expect the promised quota to be delivered monthly.
      • The plaintiffs may proceed on claims of negligent misrepresentation and breach of contract.

    This article does not judge the specific case. It focuses on the common problem it exposes: when two windows differ by two orders of magnitude, how can users see at a glance what they actually bought?

    2. Breaking Down the Problem: Three Layers, One Root Cause

    1. Surface layer: The denominator of the promised multiplier is the “single window,” while users understand the denominator as the “entire subscription period”

    These plans have at least three time scales:

    • Short window: 5 hours, controls burst rate;
    • Weekly cap: 7 days, constrains usage over a continuous week;
    • Subscription period: 1 month, the period users actually pay for.

    In plain terms: the short window decides “how fast you can run at once,” and the weekly cap decides “how far you can run in total over a week.” The advertising scaled up only one of these dimensions without disclosing the constraint on the other.

    2. Middle layer: The quota model is the combination of two mechanisms

    • The short window typically uses a “fixed quota + periodic reset” or token bucket model.
    • The long period is usually accumulated by a counter and reset to zero at expiry.

    Each mechanism is reasonable on its own, but combining them produces a key property: the deliverable amount depends on whichever of the two constraints—“rate” or “total”—is hit first. Looking at only one of them will inevitably distort the calculated multiplier.

    3. Deep layer: Inconsistent metering, so the advertising unit and the billing unit are disconnected

    • The subscription is billed monthly;
    • Usage is metered in hourly windows;
    • Model consumption is not equivalent because of different weights.

    The three units are inconsistent, so any conversion introduces ambiguity.

    The root cause: rate and total are designed as two independent parameters, yet no unified “deliverable usage” metric is disclosed to users.

    3. Quantitative Analysis: Do the Math First

    Let:

    • the entry tier’s quota for a single 5-hour window be Q, with W days per week and 24 hours per day, giving W × 24 ÷ 5 windows per week;
    • a given tier’s single-window quota be kQ (k is the window multiplier);
    • the tier’s weekly cap be m times the entry tier’s weekly cap (m is the weekly multiplier).

    If the tier runs at full window rate, the amount it can deliver in a week is min(k, m) × Q.

    This yields two conclusions:

    1. When m ≥ k, the weekly cap is not binding, and the actual weekly multiplier is k;
    2. When m < k, the weekly cap is exhausted first, the actual multiplier is m, and a (k − m) ÷ k portion of the window quota cannot be delivered.

    If the entry tier can run at full quota continuously for 168 hours a week—that is, m₀ × W × 24 ÷ 5 ≥ Q—then the higher tier’s continuous full-quota duration is roughly:

    1. 7 days × m ÷ k

    Plugging in the plaintiff’s calculation basis (m of 3.5 and 6, k of 5 and 20) gives the table below:

    Tier Relative Monthly Fee Window Multiplier (k) Weekly Cap Multiplier (m) Advertised Multiplier Actual Weekly Multiplier Weekly Full-Quota Duration
    Entry 1× 1 1 — — 7 days (baseline)
    Mid 2× 5 3.5 5× 3.5× ~4.9 days
    High 4× 20 6 20× 6× ~2.1 days

    Note: The k and m values are the plaintiff’s calculation basis. The “weekly cap multiplier” in the table is back-calculated from the “actual weekly multiplier”; it is not given directly in the source and is not official data. The “full-quota duration” is a theoretical upper bound derived under the assumption that the entry tier can run at full speed for the entire week, and is included only to convey the order of magnitude.

    Combined with the cost dimension, a clearer value curve emerges:

    • If you look only at the single-window rate, the burst quota per $1 is k ÷ monthly fee, which drops to 1/5 from the entry tier to the high tier (5÷100 versus 20÷200);
    • If you look at the weekly deliverable amount, the high tier’s weekly quota per $1 is actually about 1.2x the mid tier’s (6÷200 versus 3.5÷100).

    In other words, the high tier’s high multiplier is mainly reflected in “peak capability,” not “total cost-effectiveness.”

    This also explains the vendor’s motivation: raising the short-window quota satisfies the experience of users who interact frequently or code continuously, while tightening the weekly cap constrains long-term compute costs and prevents a few extreme heavy users from driving up the average cost. The strategy itself is defensible; the problem is that only half of it was disclosed.

    4. The Right Approach: How to Define an Unambiguous Quota

    1. A complete quota description includes at least five elements

    Element Question It Must Answer Bad Example
    Metering unit What is charged: request count, input/output tokens, or a model-weighted quota Only saying “5x quota” without saying what the quota is
    Time window How long is one window: 5 hours, 7 days, or 1 month Only saying “5-hour quota” without mentioning the weekly cap
    Reset method Fixed window, sliding window, token bucket, or reset at expiry A fixed window may allow a double burst at the boundary
    Model weight How different models and context lengths are converted Using “request count” to mask consumption differences between models
    Over-quota policy After the quota is used up: reject, queue, degrade, or route to manual approval Silent failure, leaving users unaware why they were blocked

    2. Reference implementation of a two-layer quota (illustrative)

    The pseudocode below expresses the short window with a token bucket and the long period with a counter. The core rule: a request is admitted only when both layers pass, and deductions are made in units of model-weighted cost.

    1. import time
    2. class TieredQuota:
    3. """
    4. Two-layer quota (illustrative implementation, not production-grade)
    5. burst : short-window token bucket, decides "how fast you can run"
    6. period : long-period counter, decides "how much you can run in total"
    7. """
    8. def __init__(self, burst_capacity: float, burst_window_s: float,
    9. period_capacity: float, period_window_s: float):
    10. self.burst_cap = burst_capacity
    11. self.burst_window_s = burst_window_s
    12. self.period_cap = period_capacity
    13. self.period_window_s = period_window_s
    14. self.burst_tokens = burst_capacity
    15. self.last_refill = time.monotonic()
    16. self.period_start = int(time.monotonic() // period_window_s)
    17. self.period_used = 0.0
    18. def _roll_period(self, now: float) -> None:
    19. """Reset the counter when entering a new long-period window; a fixed window may allow a double burst at the boundary"""
    20. idx = int(now // self.period_window_s)
    21. if idx != self.period_start:
    22. self.period_start = idx
    23. self.period_used = 0.0
    24. def try_acquire(self, cost: float) -> bool:
    25. now = time.monotonic()
    26. # 1) Short window: refill tokens at a steady rate over time
    27. elapsed = now - self.last_refill
    28. self.burst_tokens = min(
    29. self.burst_cap,
    30. self.burst_tokens + self.burst_cap * elapsed / self.burst_window_s,
    31. )
    32. self.last_refill = now
    33. # 2) Long period: roll to the new window
    34. self._roll_period(now)
    35. # 3) Admit only when both layers are satisfied
    36. if cost > self.burst_tokens or self.period_used + cost > self.period_cap:
    37. return False
    38. self.burst_tokens -= cost
    39. self.period_used += cost
    40. return True

    A quota policy can also be written as configuration, making it easier to review and publish:

    1. quota_policy:
    2. unit: weighted_token # Metering unit: model-weighted quota
    3. windows:
    4. - name: burst # Short window: controls burst rate
    5. length: 5h
    6. capacity: 20000
    7. - name: period # Long period: controls total volume
    8. length: 7d
    9. capacity: 60000
    10. weight_table: # Example weights; maintain per actual model capability
    11. standard: 1.0
    12. advanced: 4.0
    13. on_exceed:
    14. - action: degrade_model # First degrade to a lightweight model
    15. - action: queue # Then enter the queue

    This can be done in two conversion steps:

    1. First convert different models into the same unit by weight. Let model j’s per-request weight be w_j; then the weighted usage is U = Σ(n_j × w_j).
    2. Then use a single multiplier r to describe the relationship between tiers. A tier’s quota in each window is: entry-tier baseline × r.

    If designed well, r should be the same value for the “single window” and for the “whole week/month,” so users see the multiplier they expect. If cost considerations require the long-period multiplier to be smaller than the short-period one, at minimum:

    • display both multipliers side by side;
    • also provide an “estimated supportable duration per week/month.”

    5. Engineering Practice Checklist

    1. For platform providers: Make quotas a “readable contract”

    • Disclose the key metrics on the same screen. The metering unit, window length, per-window multipliers, and over-quota policy should be directly visible on the plan purchase page, not folded behind multiple links. This is the lesson of the case.
    • Provide a real-time usage dashboard. Show used/remaining quota and estimated reset time per window, plus an “estimated supportable duration” based on the current consumption rate. Such a capability can be built on general monitoring/alerting and logging services: write each call’s model, input/output length, and weighted usage to a log, then aggregate them into usage metrics.
    • Unify the billing and metering basis. Usage details should be traceable to a specific session, model, and time window, avoiding “accounts that don’t add up.”
    • Make over-quota behavior predictable. Take successive steps—degrade, queue, then clearly prompt the user to upgrade—rather than silently rejecting requests.
    • Announce changes in advance. When adjusting window lengths or multipliers, notify users ahead of time and set a transition period.
    • Be honest about capacity uncertainty. If the same plan’s available usage is affected by overall load at different times of day, disclose that too, so users don’t plan their work around a “theoretical upper limit.”

    2. For enterprise users: A procurement and selection checklist

    • Require the vendor to define each window and its multiplier, then convert this into a “supportable duration under worst-case (full-load) conditions”;
    • Require the ability to export usage data so it can be reconciled with your internal monitoring and alerting;
    • Pay attention to quota-sharing rules in multi-user collaboration scenarios, such as how a team pool is deducted and allocated;
    • Pay attention to whether quotas are re-converted after a model upgrade, and whether such adjustments are communicated in advance;
    • Validate the actual available amount through stress testing.

    The illustrative script below can be used to verify the actual available quota of two adjacent windows under a fixed-window quota:

    1. # Illustrative script: verify actual available quota for two adjacent windows under a fixed-window quota
    2. import time
    3. from quota import TieredQuota # Replace with the actual quota implementation
    4. quota = TieredQuota(
    5. burst_capacity=1000,
    6. burst_window_s=5 * 3600,
    7. period_capacity=6000,
    8. period_window_s=7 * 86400,
    9. )
    10. def burn_until_blocked() -> float:
    11. used, step = 0.0, 50
    12. while quota.try_acquire(step):
    13. used += step
    14. return used
    15. # 1st 5-hour window
    16. first = burn_until_blocked()
    17. # Wait until the next 5-hour window (compressed to 5 seconds in this example)
    18. time.sleep(5)
    19. second = burn_until_blocked()
    20. print(f"Window 1 available: {first:.0f}")
    21. print(f"Window 2 available: {second:.0f}")
    22. print(f"Two-window total: {first + second:.0f} (configured total {quota.burst_cap * 2:.0f})")

    A fixed-window quota can produce a “double burst” at the boundary. If two windows happen to straddle a reset moment, a user can consume close to 2x the single-window quota in a short time. For smoother rate control, use a sliding window instead, or add a constraint on the total across adjacent windows on top of the token bucket’s capacity.

    If an enterprise needs to build its own quota capability, it can be implemented on common cloud service primitives:

    • Use a container platform to host the quota service;
    • Use a message queue to smooth peaks and deliver requests in session order;
    • Write usage details to object storage for offline accounting;
    • Use logging and monitoring/alerting services to alert on over-quota events in real time.

    3. For platform providers: Help users “understand and calculate”

    • Display each window’s multiplier and the supportable weekly duration directly on the plan page;
    • Replace abstract “multipliers” with an “estimated supportable duration”;
    • Let users set usage budgets and reminder thresholds.

    6. Conclusion: A Quota Is a Contract

    The lessons of this dispute for the industry can be summarized in three points:

    • Rate and total must be disclosed together. Publishing only one layer, no matter how carefully worded, can still be misleading;
    • The metering unit must be unified. Replace “request counts” with a weighted quota so different models become comparable;
    • Usage must be observable. When users can see in real time “how much is left and how long it will last,” disputes drop sharply.

    For platforms, quota terms are a contract with users, just like billing rules. Only with transparent metrics, consistent metering, and verifiable data can the subscription model build lasting trust.