Yashveer Singh
Connect
<- All posts
SaaS Architecture and Scaling7 min read

Soft Limits, Hard Limits, and Rate Limiting: A SaaS Survival Guide

Limits protect your product from abuse, misuse, and accidental destruction. Here is how to implement them properly.

Written by Yashveer Singh, founder of Yashveer Labs.

# Soft Limits, Hard Limits, and Rate Limiting: A SaaS Survival Guide

Limits in SaaS fall into three categories: soft limits that warn users before they are blocked, hard limits that enforce a ceiling absolutely, and rate limits that restrict request frequency to protect system stability. Getting the distinction right matters more than most teams realize. A soft limit on a feature a user depends on degrades into a hard limit without warning. A missing rate limit on a public API endpoint is an invitation to an outage.

What you need to know

  • Soft limits enforce behavior by nudging users toward upgrades; hard limits enforce behavior by blocking it; neither should be applied where the other belongs
  • Rate limiting protects your infrastructure from abuse and runaway clients; it is a separate concern from plan limits
  • The most damaging SaaS failure mode is a limit that is not communicated clearly until the user hits it mid-workflow
  • Rate limits should use a sliding window or token bucket algorithm, not fixed windows, to prevent traffic spikes at window boundaries
  • Every limit should have a monitoring path: alert when users are consistently hitting limits because that is either a pricing signal or an abuse signal

The core argument

The difference between a soft limit and a hard limit is a matter of trust and conversion, not just engineering. A soft limit says: you are approaching the boundary of your plan, here is what happens next, and here is how to avoid the disruption. A hard limit says: you cannot proceed. Both have their place, but using a hard limit where a soft limit belongs creates the specific user experience that generates the most support tickets and the most negative reviews: a user mid-workflow, blocked, confused, and unable to complete something they were already doing.

I designed the limit structure for Nexli's free plan specifically to prevent this. The free tier has a soft limit on the number of active students: when a school approaches 80% of their limit, the admin dashboard shows a persistent banner. At 90%, we show a modal during login. At 100%, we still let them view existing data but block creation of new records. A hard block at 100% with no warning at 80% and 90% would have produced the wrong experience for schools who discovered the limit on the first day of term. Soft limits give users agency; hard limits enforce the non-negotiable.

Rate limiting is a different problem entirely. It is not about pricing; it is about protecting the system. Without rate limits on the API, a single misconfigured client can generate enough load to affect other tenants. The pattern I use: a conservative per-IP limit for unauthenticated endpoints (a few hundred requests per minute), a higher per-user limit for authenticated endpoints (a few thousand requests per minute), and a per-tenant limit for operations that touch expensive resources. Rate limit headers (X-RateLimit-Remaining, X-RateLimit-Reset) should be included in every API response so clients can self-manage.

Common mistakes

  1. Hard-limiting the API at plan tier without communicating the limit in the API response. If a user's plan allows 10,000 API calls per month and they hit 10,000 on the 15th, the 10,001st call should return a 429 with a message that includes the plan limit and the reset date, not a generic error.
  1. Using a fixed-window rate limiter that resets at clean intervals. A fixed window that resets every minute creates a burst double-tap: a client can make the full quota at the end of one window and the full quota at the start of the next, effectively getting double the throughput at window boundaries. Use a sliding window or token bucket instead.
  1. Not distinguishing between limit types in your admin tooling. Customer support should be able to see in one view whether a user is hitting a plan limit or a rate limit. These require different responses: a plan limit is an upgrade conversation; a rate limit is a debugging conversation.
  1. Setting limits too low during beta and not adjusting them. Beta limits are often conservative. Real usage data from beta users is the input that should calibrate the limits for GA. Teams that launch to GA with beta-era limits get complaints from day one.
  1. Not alerting on limit hits. A user who hits a plan limit without upgrading is either unhappy or unaware. Either signal deserves a response. Set up tracking for limit hit events and build a lightweight follow-up flow.

Where to start

  1. Inventory every limit in your product. List every place where a user can be blocked (plan limit, rate limit, hard technical limit). For each one, answer: does the user have warning before the block? Is the message helpful? Does it tell them what to do next?
  1. Implement rate limiting at the API gateway or middleware layer. Use Redis as the counter store (it handles atomic increments correctly). The algorithm should be a sliding window or token bucket. Start with conservative limits and loosen them based on real traffic data.
  1. Add limit headers to every API response. X-RateLimit-Limit (the ceiling), X-RateLimit-Remaining (what is left), and X-RateLimit-Reset (when it refills) give clients the information they need to self-manage without hitting the limit constantly.

Related reading

FAQ

Frequently asked

Author

Why I am the right person for this kind of build

I do not have a degree yet. I do not need one. I have shipped Dwarka Bricks, Expert Tutorials, Prominence Football Academy, Velmora, and Nexli. The work is on real URLs, used by real people. Yashveer Singh, founder of Yashveer Labs. If the topic on this page is the one you are facing right now, I have done it for someone else and I can do it for you.

Related reading