Login errors are rising, checkout retries are piling up, and the gateway already has a rate limit. The immediate question isn't just whether the threshold should be lower. It's whether the gateway is counting the right thing, across the right instances, before the application accepts an important action.
An API gateway rate limit controls request volume and timing. It can protect backend capacity and divide access fairly, but it can't establish that a browser request is legitimate, fresh, or safe to repeat. Sensitive website actions need deliberate limit keys, action-specific policies, and separate controls for replay and duplicate execution.
What an API Gateway Rate Limit Actually Controls
An API gateway rate limit caps how many requests a client can send to a route within a time period and rejects excess requests, usually with HTTP 429 Too Many Requests. A gateway receives API traffic before application code does. A route is a path and method combination, such as POST /login.
Think of the gateway as an office building's front desk counting visitors at the door. That counter can keep the lobby from overflowing, but counting alone doesn't check visitors' badges or their reasons for entering. Authentication and application rules still have work to do.
The same counter at different scopes
The scope determines which requests compete for capacity:
Whole API: A global cap protects shared infrastructure, but unrelated routes compete for the same allowance.
Client credential: A per-API-key cap separates issued machine clients, although every caller using that key shares its allowance.
Important action: A checkout-specific cap restricts order submissions without unnecessarily blocking product browsing.
Synthetic example: A client sends 120 requests in one minute against a fixed allowance of 100, with no reset during that sequence. The first requests consume the allowance, and the final 20 receive a rejection. The response includes Retry-After so a retryable client knows when to try again.
The MDN reference for HTTP 429 describes that status as a response to excessive requests and explains that the server may provide Retry-After. Clients should honor that delay rather than immediately resubmitting.
Operational boundary: Admission through a counter means capacity was available. It doesn't mean the application should accept the action.
A useful policy therefore needs more than a threshold. It needs an algorithm, a trusted counting key, an enforcement scope, and explicit rejection behavior.
Token Bucket, Fixed Window and Sliding Window Compared
A token bucket resembles a jar with a fixed capacity that refills steadily. Each request removes a token; a full jar accommodates a short burst. A fixed window resembles a shop counting sales from midnight to midnight, then starting over at the boundary.
A sliding window instead looks backward from the current moment. Its behavior depends on whether the implementation stores exact request timestamps or estimates recent traffic using counters.
Edit Alt Text
Rate limit policy types compared
| Policy | How it counts | Burst behavior | Main weakness |
|---|---|---|---|
| Token bucket | Each request removes one token; tokens refill at a set rate up to a capacity | Allows bursts up to bucket capacity, then the steady rate | Two values to tune: refill rate and capacity |
| Fixed window | Counts requests in clock-aligned windows such as 0–60 seconds | Count resets at each boundary, so a burst can pass on both sides of it | Simple to build, but allows boundary bursts |
| Sliding window log | Stores timestamps of recent requests and counts those inside the last N seconds | Smooth, with no boundary spike | Stores one timestamp per request, costly at high volume |
| Sliding window counter | Estimates the sliding window by weighting the previous and current fixed-window counts | Close to smooth, using only two counters | An approximation with a small estimation error |
Amazon API Gateway's throttling documentation describes a token-bucket implementation in which each request consumes a token, replenishment occurs at a configured requests-per-second rate, and bucket capacity accommodates bursts. That separates sustained throughput from temporary burst tolerance.
AWS account and regional quotas are service limits, not application design targets. A gateway's permitted aggregate throughput says nothing about the safe rate for password recovery or promotion redemption.
The boundary problem in practice
Synthetic example: A fixed-window policy permits 100 requests per minute. A client submits 100 at 12:00:59 and another 100 at 12:01:01. Both batches pass because they belong to different clock-aligned windows, admitting 200 requests within two seconds.
An exact sliding-window log with the same allowance rejects the second batch because the first batch remains inside the lookback period. The counter-based variant trades timestamp storage for estimation, so it shouldn't be treated as an exact substitute where strict accounting matters.
Choose token bucket when ordinary API clients need short bursts without unlimited sustained traffic. Fixed windows fit cheap, coarse protection where boundary spikes are acceptable. Sliding windows fit sensitive operations where those spikes undermine the policy.
For any implementation, record the applicable refill rate, capacity, window length, and rejection response. Also record the initial bucket state. A newly created full bucket and an empty bucket behave differently during deployment and restart.
Picking the Limit Key and the Enforcement Point
The limit key determines who shares an allowance. A carefully chosen threshold attached to the wrong key can punish a busy office while allowing a distributed attack to continue.
Identity selection also establishes a trust boundary. A caller-provided user header isn't an authenticated identity merely because the gateway can read it.
Choose the sharing boundary deliberately
Source IP: Available before login and inexpensive to use, but network address translation, mobile carriers, and office egress can put many legitimate users behind the same address. Trust forwarded client addresses only from known proxies.
API key or client ID: Suitable for machine clients with issued credentials. A leaked credential spends the same quota as its legitimate owner, so credential revocation remains necessary.
Authenticated user or tenant: Useful for customer fairness after authentication establishes a trusted identity. A tenant-wide allowance can still let a noisy integration crowd out colleagues.
Account identifier: Groups login or recovery attempts against the same target. Normalize identifiers consistently, and recognize that attackers can distribute attempts across targets.
Route plus identity: Separates expensive or sensitive actions from ordinary reads. Use normalized route names rather than arbitrary paths to avoid unnecessary counter growth.
For commerce systems separating storefronts from backend services, Grumspot's API-first ecommerce architecture explained provides useful architectural context. The practical rate-limiting decision is which trusted identity survives each service boundary, not where the storefront sends requests.
Local isn't deployment-wide
Envoy's local rate-limiting documentation states that a local bucket is shared across workers within a process, not across the entire gateway fleet.
Arithmetic illustration: A local policy of 100 requests per second per process, deployed across 10 replicas, can admit approximately 10 times the rate someone might mistakenly assume is fleet-wide. Distribution and available tokens affect the actual observed traffic, but adding replicas doesn't create a shared allowance.
Local enforcement suits immediate overload protection. Fleet-wide customer fairness requires coordinated decisions or shared state, with an explicit policy for what happens when that dependency becomes unavailable.
Scaling the gateway shouldn't silently multiply a tenant's contractual or operational allowance.
Before adopting a key, resolve these questions:
Trust: Has the gateway verified the identity?
Absence: What happens when the identity is missing?
Fallback: Which key applies instead, and can a caller deliberately select the weaker path?
Layering Gateway, Identity and Action Limits
A checkout workflow needs different controls for different resources. The gateway instance needs protection from incoming work, customers need fair access to shared capacity, and the application needs rules around placing an order or holding inventory.
The useful flow is local gateway admission → shared identity allowance → action-specific checks → application transaction. Browser verification belongs on the protected browser action, not indiscriminately on every endpoint involved in the workflow.
Edit Alt Text
Protect capacity before checking business allowances
Envoy's global rate-limiting documentation describes placing a local token bucket before a global rate-limit service. The local check absorbs large bursts before they generate fine-grained distributed checks.
Set the local refill rate near the instance's measured safe processing capacity. Set burst capacity from queueing tolerance and downstream behavior, not from the customer quota someone wants to advertise.
The shared layer should own allowances that must remain consistent across replicas, such as tenant, credential, or account consumption. That adds a dependency to request admission, so its latency and failure behavior need monitoring alongside gateway health.
A checkout policy with distinct jobs
Synthetic checkout example, not production recommendations:
| Layer | Illustrative rule | Purpose |
|---|---|---|
| Gateway instance | Local cap sized through load testing | Protect instance capacity |
| Session | 10 cart-submit attempts per 10 minutes | Restrict repeated submissions from the same session |
| Reservation action | One seat-hold request per seat every 2 minutes | Control repeated hold requests against the same resource |
| Order transaction | Idempotency key on order creation | Return the existing order for a repeated operation |
The reservation rule doesn't replace inventory locking or an atomic availability check. Otherwise, separate sessions can still race for the same seat after both pass admission.
Likewise, a session allowance isn't a reliable customer quota if callers can cheaply create new sessions. Pair it with an authenticated identity where available, and keep resource-specific transaction rules inside the application.
For safely retryable throttled requests, return 429 with Retry-After. Don't automatically retry a state-changing browser operation unless its application semantics make repetition safe. Keep browsing available when only submission capacity is exhausted.
MANDATE's guide to API abuse on protected website actions provides context for separating browser-action abuse from general infrastructure traffic.
Webhooks, callbacks, and machine APIs need their own policies. They don't participate in browser verification and should remain outside browser-only coverage. Validate their credentials and transaction semantics independently rather than forcing them through a browser flow.
Worked Example for a Login Endpoint
For a login endpoint, require capacity in both a source bucket and an account bucket. That prevents a source-only policy from overlooking repeated attempts against the same account from different addresses.
Credential stuffing means trying leaked username and password pairs against a login form to find accounts that still work. Attackers can distribute those attempts across sources and account identifiers, which makes a single IP threshold an incomplete control.
The OWASP Bot Management and Anti-Automation Cheat Sheet recommends multiple limit keys and token-bucket or sliding-window algorithms, and warns about fixed-window boundary bursts.
Two-bucket login limits
Synthetic example values for POST /api/login, not recommended production settings. This example uses sliding-window logic for both buckets.
| Bucket | Key | Window | Threshold | On exceed |
|---|---|---|---|---|
| Source bucket | Client IP address | 1 minute | 20 attempts, synthetic | 429 with Retry-After |
| Account bucket | Normalized username | 15 minutes | 5 failed attempts, synthetic | 429 with Retry-After and hand-off to the recovery flow |
| Combined rule | Both buckets | Each bucket's own window | Request passes only when both have capacity | Log which bucket made the decision |
The source counter records admission attempts. The account counter records failed authentication outcomes, so application feedback is required. A gateway that only sees incoming requests can't infer whether a password was correct.
Counter updates also need concurrency handling. Parallel attempts shouldn't all read the same remaining allowance and pass unchecked; reserve or update capacity atomically, and reconcile authentication outcomes deliberately.
Run the cases before deployment
Case A, ordinary typing mistakes: A legitimate user mistypes a password twice. Both buckets retain capacity, so subsequent requests proceed to authentication. Admission doesn't mean authentication succeeds.
Case B, concentrated guessing: A source repeatedly submits incorrect passwords for the same account. In this example, the account allowance is exhausted before the source allowance, and subsequent attempts receive the neutral throttling response.
The recovery hand-off must remain protected independently. Otherwise, an attacker can use account throttling to drive traffic into an unrestricted recovery endpoint or disrupt a victim's access.
Case C, distributed low-volume attempts: Requests rotate across addresses and account identifiers without exhausting either allowance. Neither bucket rejects them, even though the aggregate activity is abusive. New-device, unusual-location, and scripted-behavior signals can justify additional checks or step-up authentication, meaning an extra authentication requirement before access.
A passing pair of counters isn't evidence that a password submission came from the account owner.
Before enforcement, complete an operational checklist:
Decision logging: Record the deciding bucket, policy version, normalized route, and outcome without logging passwords.
False-positive review: Examine shared-network users, password-manager retries, and account recovery interactions.
Neutral responses: Keep throttling messages consistent so they don't disclose whether an account exists.
Outcome feedback: Distinguish attempts, failed authentication, successful authentication, and recovery completion.
This design deliberately leaves distributed attempts below both thresholds visible for risk analysis rather than pretending that a tighter counter solves every credential-stuffing pattern.
Where Rate Limits Stop and Replay Controls Start
A request can pass every threshold and still be wrong. A valid-looking message may have been captured earlier, or a legitimate customer may repeat an operation after losing the response.
Replay-resistant authentication uses protocol-specific freshness checks such as nonces or challenges to make captured messages unusable. Single-use requirements depend on the authenticator and protocol; they are not a rule that every session credential can be presented only once. Apply the relevant NIST authenticator guidance to authentication, and define business-action replay and retry rules separately.
Repetition has different meanings
Synthetic replay scenario: An attacker captures a valid checkout request and resends it once per minute, below the configured allowance. The counter admits the traffic unless another control rejects the reused proof or invalid transaction state.
Synthetic duplicate scenario: An order is created, but the response never reaches the customer. The customer retries with the same idempotency key, a unique operation key that makes a repeated request return the first result instead of creating another order.
Implement idempotency with durable storage and atomic coordination around the transaction. Bind the key to the caller and operation, reject incompatible payload reuse, and define retention and in-progress behavior explicitly.
Controls for sensitive browser actions and what each answers
| Control | Question it answers | Question it leaves open |
|---|---|---|
| Rate limit | How many requests arrived in this window? | Whether the request is fresh or legitimate |
| Replay-resistant credential | Has this proof already been used, or has it expired? | Whether the business action completed |
| Idempotency key | Is this a repeat of an operation already committed? | Whether the caller is a human |
| Browser verification | Does this browser action look scripted or tampered with? | Identity, payment validity, or uptime |
| Authentication and authorization | Who is calling, and may they perform this action? | How much volume or how fast they send it |
The practical application of authentication replay resistance to business actions is to verify short-lived proof against current server state and reject reuse. MANDATE's explanation of replay attacks gives additional context for that threat.
MANDATE provides browser verification for high-value actions such as sign-in, account creation, and checkout without CAPTCHAs. Its integration sends an opaque, short-lived credential, not a JWT, with the protected request; verification errors and retries must be handled explicitly, while the business outcome is reviewed separately.
Account takeover is an attacker gaining control of an existing account. Session theft is an attacker reusing a live session token taken from a user. Neither is interchangeable with credential stuffing, which describes an attack technique rather than every route to compromised access.
MANDATE isn't a general WAF, CDN, DDoS service, or payment-fraud scoring system. It can't guarantee that all abuse is detected or replace application transaction validation.
Signup Abuse and CAPTCHA Alternatives
A rate limit alone is a weak fit for signup abuse because automated accounts can be created slowly across many addresses. CAPTCHA alternatives work best as separate decisions with explicit triggers, not as a single replacement challenge placed everywhere.
The OWASP Credential Stuffing Prevention Cheat Sheet recommends combined defenses, identifies device, location, address reputation, and scripted behavior as useful risk signals, and describes MFA as the strongest defense against most password-related attacks. Its password-attack guidance supports layered authentication decisions, not a claim that MFA alone prevents signup farms.
Match the response to the signal
Repeated signup or recovery requests: Apply source and target-email-domain allowances. Domain-level limits need care because unrelated users can share a popular provider.
Unusual device or behavior: Evaluate new devices, unusual locations, denylisted or anonymized addresses, and attempts involving many accounts.
Risky authenticated sessions: Require multi-factor authentication where an existing authentication relationship makes that step meaningful.
High-value browser actions: Apply browser verification while retaining eligibility rules, authentication, and transaction checks.
Synthetic example: A new device creating five accounts in ten minutes triggers step-up verification under an illustrative application policy, while a returning user on a known device continues unchanged. That threshold isn't a production recommendation, and a known device shouldn't be exempt from other suspicious evidence.
Keep eligibility separate
Trial eligibility abuse means someone deliberately creating repeat accounts to claim a trial more than once. Handle it as an application eligibility rule; it isn't the same problem as misleading billing or cancellation practices.
No single control stops every signup farm. Measure each trigger for false positives in Observe mode, recording what would happen without rejecting the action, before enabling enforcement.
Confirm the Rollout Path Before You Enforce
A policy isn't ready merely because a counter increments correctly. Teams need evidence that it targets the intended requests, preserves legitimate workflows, and has an owner when verification or shared state becomes unavailable.
MANDATE's observe-before-enforce rollout guidance provides the relevant deployment approach. A new MANDATE app connection starts paused with an explicit Off release, so connection creation shouldn't be mistaken for active protection.
An operational release sequence
Inventory protected routes and completion events. Record each path and method alongside the application event that proves completion, such as an account being created or an order being committed, so admission isn't confused with success.
Assign keys at each layer. Document the coarse gateway policy, identity or session allowance, and action-specific rule, including trusted identity sources and missing-identity fallbacks.
Begin in Observe mode. Record would-reject events separately from enforced rejections so policy evaluation can be examined without interrupting customers.
Review grouped evidence across a full weekly traffic cycle. Compare decisions with legitimate-user impact, including abandoned signups and checkouts completed after retry, rather than approving a policy from a quiet traffic sample.
Confirm rollback and unavailability behavior. Decide whether each route fails open, allowing requests when verification is unavailable, or fails closed, rejecting them, and name the retry rules, escalation owner, and rollback procedure.
Enforce on a low-traffic sensitive route first. Return 429 with
Retry-Afterto safely retryable clients and confirm that interface behavior doesn't encourage repeated submissions.Review business outcomes before widening scope. Expand route by route only after examining completion, abandonment, recovery, and support evidence, because rejection counts alone don't establish value.
Define false positives carefully
A rejected request that the application would otherwise have legitimately completed is a false positive. Not every later retry proves one, but completed retries and support reports provide evidence worth investigating.
Teams should also distinguish a verification failure from a business rejection. An expired credential, unavailable verifier, exhausted allowance, invalid password, and unavailable inventory require different remediation even when the customer sees a failed action.
Keep deployment decisions and editorial claims reviewable. Technical accuracy, source links, internal references, and custom artwork should be approved before publishing guidance or treating it as an operational runbook.
The next concrete step is to select a high-value route, write down its key and policy, define its completion event, and enable observation before enforcement. That produces a testable admission policy instead of another unexplained gateway setting.
MANDATE protects important browser-originated website actions from automated abuse without CAPTCHAs, complementing gateway limits rather than replacing them. Visit MANDATE to evaluate browser verification for a selected signup, sign-in, or checkout action, with Observe mode and a confirmed rollback path before enforcement.
