Most startups think about rate limiting only after something goes wrong. A scraper hammers the product search endpoint, a bot tries ten thousand passwords against the login form, or a customer's integration script enters an infinite loop and takes the whole database down for everyone. By then the fix is urgent, and urgent fixes tend to be blunt.
Rate limiting is the practice of capping how many requests a client can make within a time window. It is one of the cheapest forms of protection you can add to a web app or mobile backend, and it quietly improves reliability, cost control, and security at the same time. This guide explains how to design limits that stop abuse without annoying real customers, and how to roll them out safely.
If you are still choosing your backend foundations, our overview of monolith versus microservices for startups is a useful companion, because where you enforce limits depends on how your system is shaped.
It helps to be specific about the threats, because each one needs a slightly different limit.
Notice that only some of these are malicious. Plenty of the traffic you will limit comes from well meaning customers and your own code, which is why the response to a limit should always be clear and recoverable.
Consider a typical scenario. A startup ships a mobile app where users sign in with a one time password sent by SMS. The endpoint that requests the OTP has no limit. A script, or even a bug in a retry loop, could call it thousands of times, and every call might trigger a paid text message. For example, if each message costs a few rupees, a single afternoon of abuse could turn into a surprisingly large bill, while real users wait for slow responses.
The fix is not complicated. Limit OTP requests per phone number and per IP address, add a short cooldown between sends, and cap the daily total per number. We cover the sign-in side of this in detail in our guide to OTP login for Indian apps with SMS and WhatsApp fallbacks. The principle applies everywhere: any endpoint that costs you money or exposes sensitive actions deserves its own, stricter limit.
You do not need to invent anything. Four patterns cover almost every case.
Count requests in a block of time, such as 100 per minute, and reset when the minute ends. It is simple, but a client can send a burst at the end of one window and another at the start of the next, briefly doubling the intended rate.
Count requests over the last 60 seconds, measured continuously. This removes the boundary problem and feels fair. A sliding window counter approximates it cheaply and works well for most APIs.
Each client has a bucket that refills at a steady rate. Every request spends a token. If the bucket is full, the client can burst briefly, then settles to the refill rate. This matches how real people use apps, with short flurries of activity followed by quiet.
Instead of counting requests over time, cap how many can run at once. This is ideal for expensive operations such as report generation or AI inference, where the danger is many slow jobs piling up rather than raw request count.
Rule of thumb: use a token bucket for general API traffic, strict fixed or sliding windows for login and OTP endpoints, and concurrency limits for heavy jobs.
A limit is only as good as the identifier it counts against. Choosing the wrong key is the most common reason rate limiting either fails to stop abuse or blocks innocent people.
In multi-customer products, separate limits per tenant also protect you from one account dominating shared resources. That idea connects closely to the data isolation choices described in our guide to multi-tenant SaaS architecture.
Adding limits to a live product is risky if you flip a switch and hope. A staged approach keeps customers safe.
If you run more than one server, in-memory counters will not work, because each instance sees only part of the traffic. Redis is the usual choice, with atomic increments and expiry built in. Managed API gateways and CDNs can also enforce limits at the edge, which keeps abusive traffic away from your application entirely.
Use coarse limits at the CDN or gateway to absorb floods, and finer application level limits for business rules, such as five failed logins per account per hour. Edge limits are cheap but blunt. Application limits understand users and plans.
Return 429 Too Many Requests, a Retry-After value, and consistent headers that show the limit and remaining budget. Mobile apps should read these and back off with a gentle delay rather than retrying instantly. Predictable responses make partner integrations dramatically easier to support.
When clients are told to wait, the worst outcome is that they all come back at the same instant. Encourage exponential backoff with random jitter in your SDKs and documentation. Good API documentation that spells out limits and retry behaviour prevents many support tickets before they begin.
Decide in advance what happens if your limiter, such as Redis, goes down. For most endpoints, failing open (letting requests through) keeps the product usable. For high risk endpoints like OTP or password reset, failing closed may be safer. Write this decision down so it is deliberate, not accidental.
Rate limits are also a product feature. Free users might receive a modest allowance, paying customers a larger one, and enterprise accounts a negotiated ceiling. Publishing these numbers makes your platform feel professional and trustworthy. If usage drives revenue in your product, pair limits with metering. Our guide to usage-based billing and metering for SaaS shows how the same counters can feed invoices.
It also pays to remember that rate limiting is one layer, not the whole wall. Combine it with strong authentication, input validation, and good security headers. Our practical guide to HTTP security headers for web apps covers another inexpensive layer worth adding.
A small team can implement basic limits in a day or two. The harder work is deciding thresholds, handling multi-tenant fairness, and testing under realistic load. If your product handles payments, personal data, or high traffic, an experienced partner can design this with you before launch. Our web development team builds secure, scalable backends for startups and SMEs, with protection like this planned from the first sprint.
Rate limiting is not about distrusting your users. It is about making sure a small number of bad requests, whether malicious or accidental, never ruin the experience for everyone else. Start by listing your sensitive and expensive endpoints, measure real traffic, set generous limits in log-only mode, and enforce them in stages with clear 429 responses. Then revisit the numbers as your product grows.
Do this early and it costs a few days of work. Do it after an incident and it costs customer trust, cloud spend, and a stressful weekend. The smartest time to add rate limiting is before you need it.