SaaS Usage Limits and Fair Use: Capping Cost Without Churn

How to set SaaS usage limits and a fair use policy that protects your margin without punishing your best customers. Soft caps, hard caps, and the overage conversation.

· Justin Boggs

A round black analog water meter mounted against a wall

Photo by Hansong Huang on Unsplash

The right way to cap usage in a small SaaS is two limits, not one. A soft limit sits where you expect normal customers to top out — crossing it triggers a notification and, eventually, a conversation about a bigger plan. A hard limit sits well above it and exists only to stop a single account from running your infrastructure bill into the ground. Most founders build only the hard limit, set it low, and then spend the next year explaining to their best customers why the product stopped working. A fair use policy is the written version of the soft limit: what you consider normal, and what happens when someone isn't.

TL;DR

  • Two thresholds, not one: a soft limit that notifies, and a hard limit far above it that protects the platform.
  • Never let a customer hit a wall silently. Notify at multiple points before the cap — Vercel's Spend Management fires at 50%, 75%, and 100% of your amount, which is a good default to copy.
  • Degrade before you deny. Slower, cheaper model, queued instead of realtime — all better than a 403.
  • AI features break the old math because marginal cost is real and variable. Meter the token, not the request.
  • Enforcement lags. Vercel's spend checks run "every few minutes," so set your cap below the number you can actually tolerate.

Why usage limits matter more now than they did in 2020

For most of SaaS history, the marginal cost of one more customer action was close to zero. A user who ran 400 reports instead of 40 cost you some database CPU and nothing else. Unlimited plans worked because "unlimited" was mostly true.

AI features ended that. Every generation has a real, variable, per-call cost that shows up on someone's invoice at the end of the month. If you've wired an LLM into your product — a summarizer, a chat assistant, a document parser — you now have a cost structure that looks more like a telco than a software company. Your gross margin is a function of how heavily individual accounts use one specific feature.

That changes the shape of the problem. It's no longer "how do we push people to a higher tier." It's "how do we make sure one account can't quietly cost us $4,000 this month."

And usage in almost every SaaS is wildly unequal. A small number of accounts do most of the volume. That's the shape you're designing around:

Line chart showing a steep power-law curve of usage per account, with the top few accounts far above the rest and a dashed line marking the 95th percentile

Illustrative shape only — the curve represents a typical long-tail distribution, not measured data from any specific company.

The practical consequence of that curve: a cap placed near the top of the distribution barely affects anyone. A cap placed at the average affects a lot of people, badly. Most founders set the cap by dividing their cost budget by their customer count, which lands them squarely in the second category.

Instead, look at where your actual accounts sit and put the soft limit near the top of the range you're happy to serve. If you can say "95% of customers will never notice this policy," you have a fair use policy. If you can't, you have a pricing change wearing a policy costume — and your customers will read it that way.

Soft limits, hard limits, and the tranche between them

Three enforcement shapes, and they solve different problems:

| | Soft limit | Hard limit | Tranched (both) | | --- | --- | --- | --- | | What happens at the line | Notify user and you; keep serving | Deny the request | Notify at the soft line, deny at the hard line far above | | Protects margin? | Only if you follow up | Yes, immediately | Yes | | Protects the platform? | No | Yes | Yes | | Customer experience | Good — no surprise breakage | Bad — silent wall | Good, with a real backstop | | Best for | Usage you want customers to have | Abuse, runaway loops, security | Almost every real product | | Failure mode | You never have the upgrade conversation | Churn from your highest-value accounts | More engineering work up front |

The tranched version is the one to build. A soft limit at the fair-usage line that triggers notifications and a monetization conversation, and a genuine hard limit far beyond it — 5x, 10x, whatever your infrastructure can absorb — that exists purely as a backstop against a runaway loop or a compromised key.

The distinction matters because the two limits answer different questions. The soft limit asks "is this customer on the wrong plan?" The hard limit asks "is something broken or malicious?" Those need different responses, and collapsing them into one number gives you the wrong response to both.

Here's the flow I'd wire into a new product:

flowchart TD
  A[Usage event] --> B{Under soft limit?}
  B -->|Yes| C[Serve normally]
  B -->|No| D{Under hard limit?}
  D -->|Yes| E[Serve, but notify user<br/>+ flag for upgrade conversation]
  D -->|No| F{Degraded mode available?}
  F -->|Yes| G[Serve with cheaper model<br/>or queue for off-peak]
  F -->|No| H[Deny with a clear error<br/>+ an upgrade path in the message]

The F branch is the one most implementations skip, and it's the highest-leverage box on the diagram. Denying a request is the most expensive possible outcome for the customer relationship and often not necessary. Falling back to a smaller model, dropping realtime to a queue, or reducing output length all cost you far less than a support ticket that starts with "your product stopped working."

Stripe's own docs frame the useful actions around a usage alert this way: email the user, deprovision access, or notify your sales team of an upsell. Notice that "deprovision" is one option out of three, not the default.

How to actually instrument this

You need three things: a meter, alerts, and a spend backstop. All three exist off the shelf.

Meter the unit that costs you money. If your AI feature's cost scales with tokens, meter tokens — not requests. A request that summarizes a 200-page PDF and a request that answers "what's my account balance" are not the same unit, and metering requests means the heavy user subsidizes nobody and you eat the difference. This is the single most common instrumentation mistake, and it's very hard to fix after customers have anchored on a number.

Set alerts before the wall. Stripe's usage alerts let you fire when a customer exceeds a meter threshold, either for one customer or all of them. There's a ceiling worth knowing: you can create a maximum of 25 alerts per combination of a specific meter and customer. That's plenty for tiered warnings but not enough for a per-percent alerting scheme, so plan your thresholds rather than generating them.

A few Stripe constraints that bite in production, straight from the docs: billing thresholds don't apply to trial subscriptions, they aren't evaluated in the 24 hours before a subscription ends, and a subscription is only allowed a single monetary threshold. Stripe is also explicit that invoiced amounts "might be slightly higher than the specified thresholds because invoices aren't issued at the exact moment a specified threshold is reached." Your caps are approximate. Design for that.

Cap your own spend, separately. Customer-facing limits don't protect you from your own infrastructure. Vercel's Spend Management is the model here: you set a dollar amount per billing cycle, and it can notify, hit a webhook, or pause production deployments. Notifications fire at 50%, 75%, and 100% of the amount — three warnings before anything breaks, which is the pattern to copy in your own product.

Two details from that documentation are worth internalizing because they generalize to every system like this. First, enforcement lags: Vercel checks metered usage "every few minutes," and the docs say plainly that "projects can keep serving traffic and accruing usage for several minutes after you cross the spend amount," recommending you set the amount below your true ceiling. Second, recovery is manual — paused projects "won't automatically unpause if you increase the spend amount." Both are the correct design. Both will surprise you at 2am if you didn't read them first.

Your upstream AI provider has the same structure. Anthropic's API separates spend limits from rate limits: a monthly spend cap by tier, plus per-minute request and token limits. Hit a rate limit and you get a 429 with a retry-after header telling you how long to wait. Hit the spend cap and you also get a 429 — but with no retry-after, because retrying won't help; the docs note that automatic SDK retries will simply fail until access resumes. If you're proxying an AI provider, your app needs to distinguish those two cases and say different things to the customer. "Try again in a moment" and "your organization's monthly budget is exhausted" are very different messages.

Worth stealing: Anthropic uses a token bucket algorithm, so capacity replenishes continuously rather than resetting at fixed intervals. That's a much better customer experience than a monthly cliff, because a user who briefly spikes recovers in minutes instead of waiting for the first of the month. If you're building your own limiter, do the same. There's more on the mechanics in our guide to rate limiting architecture for indie SaaS, and the metering side is covered in adding usage-based billing with Stripe.

Writing the fair use policy (and having the overage conversation)

The policy document is short. Four things:

  1. What you meter. Name the unit in plain language. "AI generations," "documents processed," "seats." Not "compute units."
  2. What normal looks like. A number, or a range. Vagueness here is what makes fair use policies feel like a trap.
  3. What happens when someone exceeds it. Notification first, then a conversation, then — only in extreme cases — throttling. Say the order explicitly.
  4. What counts as abuse. Automated scraping, resale, sharing credentials across organizations. This is the clause that lets you act fast when you need to.

What kills trust is a policy that reserves an unlimited right to do anything, at any time, at your discretion. Founders write that clause because a lawyer told them to, and customers read it as "we will move the goalposts when it suits us." Commit to a number and a notice period instead. If you need to change the number later, that's a price increase for existing customers and should be handled like one.

Then there's the conversation itself, which is the part nobody prepares for. Someone crosses the soft limit and you have to email them.

The framing that works: their usage is evidence the product is working, and you want to keep serving it. Not "you have exceeded your allowance." Something closer to: "You're running about 4x the volume of a typical account on this plan, which is great — it also means the plan isn't priced for what you're doing. Here's what a plan that fits looks like."

Three tactical things that make it go better. Send it early, when they're at 70-80% of the soft limit, not at 110% — nobody likes being told about a problem after it's already a problem. Lead with what they get on the higher tier rather than what you'll take away. And offer a grandfathered path for the accounts that were with you before the limit existed, because those customers took a risk on you and the policy is a change in terms they didn't agree to.

The customers who churn over a usage conversation are almost never churning over the number. They're churning because the first they heard of it was an error message.

Frequently asked questions

What's the difference between a fair use policy and a hard usage cap?

A hard cap is a technical limit enforced by your code — past the number, the request fails. A fair use policy is a written statement about what you consider reasonable, enforced socially and commercially first. Most products need both, with the policy line set well below the technical one.

Where should I set the soft limit if I don't have usage data yet?

Pick a number you'd be comfortable serving to every customer at your current price, then double it for the launch cohort. You'll have real distribution data within a few months, and lowering an unused limit is much easier than raising one people have already anchored on. Be explicit that early limits are provisional.

Should I ever hard-block a paying customer?

Rarely, and never as the first action. Reserve hard blocks for behavior that endangers the platform for everyone else — a runaway loop, a leaked key, obvious abuse. For a customer who is simply using the product a lot, degrade the service or invoice the overage instead.

How do I handle usage limits for AI features specifically?

Meter tokens rather than requests, since a single request can vary in cost by orders of magnitude. Build a fallback to a cheaper model rather than a hard denial. And distinguish upstream rate limits from upstream spend caps in your error handling, because one is temporary and one isn't.

Do usage limits hurt conversion?

Clear ones don't. What hurts conversion is ambiguity — a prospect who can't tell whether their use case fits will assume it doesn't. Publishing a concrete number, even a modest one, converts better than "fair use applies." This is the same principle behind pricing pages that convert.

Can Stripe enforce the limit for me?

Stripe can meter usage, fire alerts, and invoice overage, but the enforcement decision stays in your application. Stripe tells you a customer crossed a threshold; your code decides whether to notify, degrade, or block. Treat Stripe as the meter, not the valve.

Set the limit before you need it

The reason to build usage limits and a fair use policy now, before any account is anywhere near them, is that every version you build under pressure is worse. Limits designed during a surprise $3,000 invoice are always too tight, always announced badly, and always land on the customers you most wanted to keep.

Build the tranche: a soft limit near the top of normal, notifications well before it, a degraded mode instead of an outright denial, and a hard limit far above that exists only to stop genuine runaway. Write down what normal means, in a number. Then have the overage conversation early and frame it around what the customer gets.

Capping cost and keeping customers aren't in tension. They're in tension only when the customer finds out about the cap from an error message.

If you're wiring metered usage into a Next.js SaaS, the Coding Capybaras marketplace has copy-paste AI prompts for the Stripe billing and rate-limiting pieces described above.