If a URL is public, someone will script it.
Login, search, lead forms, password reset, and JSON endpoints attract credential stuffing, spam, and cost amplification. Rate limiting is not hostility to users — it is fair allocation under abuse.

Throttle the flood. Keep the path open for people.
Design the limit with product
| Question | Example |
|---|---|
| Unit | IP, user, API key, session |
| Window | 10/min, 100/hour |
| Scope | route class (login vs search vs lead form) |
| Response | 429 + Retry-After |
| Bypass | allowlists for known partners |
Return honest status codes. Document limits for partners. Log and alert on sustained 429 spikes.
Layered defense
- Edge rate limits (CDN/WAF)
- Application limits with clearer product rules
- Challenges (CAPTCHA-class) only when risk is high
- Bot management for extreme cases
Do not punish entire mobile carrier NATs without additional signals. Combine IP with session, device, and behavior where you can.
Forms specifically
Lead forms need spam controls that do not destroy conversion: honeypots, time-to-complete, rate limits, and server-side heuristics. Pair with the lead-form reliability practices in this journal.
Closing
Ship budgets on public write paths and expensive reads before launch marketing multiplies traffic — including hostile traffic.
Need rate limits on forms or APIs? Start a project inquiry.
Communicating limits
Partner APIs should publish limits in developer docs. Browser forms should show friendly messages on 429, not a blank fail. Support needs a way to distinguish abuse from a viral launch.
Cost control
Serverless and third-party OCR/AI endpoints need especially tight budgets — abuse becomes a finance incident, not only an availability one.
IPv6 and shared NAT
Pure IP limits fail for some mobile networks. Combine signals; escalate challenges rather than hard-blocking entire ranges when possible.
Product copy for 429
Users should see: “Too many attempts. Try again in a few minutes.” not a generic 500. For APIs, include a machine-readable error code and Retry-After.
Coordinating with CDN
If both CDN and origin rate limit, align thresholds so the edge absorbs abuse without origin thrash. Document which layer is source of truth for partner integrations.
Worked example: contact form
- 5 submits / IP / 10 minutes
- 20 submits / IP / day
- Honeypot + minimum fill time 3s
- Server-side validation always
- 429 returns JSON/HTML with retry guidance
- Alert if 429 ratio exceeds baseline after a campaign launch
Worked example: public search API
- 60 requests / key / minute
- Burst capacity documented
- Heavier endpoints (export) separate, lower ceiling
- Partner keys isolated from browser tokens
Discovery questions we ask
- What breaks if this is wrong in production next week?
- Who is paged, and is that written down?
- What does “done” mean in a checklist a stranger can run?
- Which metric proves the practice is working a month later?
If those answers are vague, the write-up is not finished — and neither is the system.
How this fits the rest of the journal
Pair this note with post-launch ownership, performance budgets, and technical SEO where relevant. Most failures are cross-cutting: a migration without redirects, a flag without expiry, a form without rate limits.
Closing reminder
Write the operating rules while the team that built the feature still remembers why. That is cheaper than reverse-engineering six months later during an outage.