How do I set up Cloudflare rate limiting to protect my login and API endpoints?
Edge Security & CDN

How do I set up Cloudflare rate limiting to protect my login and API endpoints?

11 min read

Most teams don’t realize they need rate limiting until a credential stuffing or API abuse incident is already in progress. Cloudflare’s rate limiting lets you put the “bouncer” in front of your login and API endpoints so bursts of malicious traffic are blocked at the edge—before they ever hit your origin.

This guide walks through how to set up Cloudflare rate limiting to protect login pages and APIs, with practical examples and configuration patterns that work in real environments.


Why rate limiting matters for login and API endpoints

Login and API endpoints are high-value, high-risk targets:

  • Logins attract credential stuffing, brute force and scripted account takeover attempts.
  • APIs get scraped, abused with high-frequency calls, or hit with amplification attempts that exhaust backend resources.

Cloudflare sits in front of your sites, apps, and APIs as a connectivity cloud. Every request first hits Cloudflare’s global edge network, where you can:

  • Inspect the request (method, path, headers, IP, country, identity, bot score, etc.).
  • Count and limit requests over time windows.
  • Enforce actions (block, challenge, log only) without touching origin infrastructure.

Rate limiting turns those controls into concrete protections, especially when combined with:

  • Cloudflare WAF for known attack patterns.
  • Bot protection for non-human traffic.
  • Zero Trust / Access for sensitive internal endpoints.

Step 1: Decide what you’re protecting (and from whom)

Before you click anything, define your targets:

Typical login endpoints

  • /login, /signin, /account/login, /user/login
  • /oauth/token, /oauth2/token
  • /auth/* routes in single‑page apps or APIs that handle authentication

You’re primarily defending against:

  • Credential stuffing (many users, same password list)
  • Brute force on specific accounts
  • Automated password spraying from distributed IPs

Typical API endpoints

  • Public REST/GraphQL APIs: /api/*, /v1/*, /graphql
  • Mobile APIs: api.yourdomain.com/*
  • Partner or B2B APIs using tokens/keys

You’re primarily defending against:

  • Abuse of valid API keys
  • Overuse from a single client or tenant
  • Scraping or enumeration (e.g., scanning through IDs)
  • Low-and-slow attacks that run up origin load

Write down:

  • The paths you need to protect.
  • Any valid high‑volume traffic patterns (cron jobs, partner integrations, mobile bursts) you must not break.
  • How your clients identify themselves (IP, API key, auth header, cookie).

That will drive how you scope your rules.


Step 2: Understand Cloudflare rate limiting options

Cloudflare gives you a few ways to implement rate limiting, depending on plan and complexity.

1. HTTP rate limiting rules (per URL/path)

Best for: straightforward login / API protection on a per‑path basis.

  • Configure per‑path thresholds (e.g., “10 POST requests in 1 minute”).
  • Action options: block, challenge, log, or managed challenge.
  • Can match on method, path, and basic attributes.

2. Advanced rules with Rate Limiting (Request counts per expression)

Best for: API patterns that require more context.

  • Use rule expressions (similar to WAF) like:
    • http.request.uri.path contains "/api/"
    • http.request.headers["x-api-key"][0] ne ""
    • http.request.method in {"POST", "PUT"}
  • Group requests by IP, header, cookie, or combination.
  • Support sliding windows and more granular control.

3. Workers + Durable Objects / Queues (custom logic)

Best for: complex tenant‑aware or usage‑based throttling.

  • Implement custom counters per user, tenant, or key in Workers.
  • Offload heavy logic to Durable Objects.
  • Ideal when you need shared limits across multiple domains or custom billing logic.

Most teams protecting “a few login URLs and a couple of APIs” can start with HTTP or Advanced rate limiting rules and only move to Workers if their logic becomes very custom.


Step 3: Create a baseline rate limiting rule for your login endpoint

Let’s walk through a concrete example using the dashboard. You’ll mirror the same structure for all your login variants.

3.1 Navigate to rate limiting

  1. Log in to the Cloudflare dashboard.
  2. Select your zone (domain).
  3. Go to Security → WAF → Rate Limiting Rules (naming may vary slightly by plan).
  4. Click Create rule.

3.2 Define the login match condition

Use a narrow match to avoid over‑limiting legitimate traffic. Common patterns:

Example: simple login URL

(http.request.uri.path eq "/login" and http.request.method eq "POST")

If your login lives under /auth/:

(http.request.uri.path starts_with "/auth/" and http.request.method eq "POST")

If you also have an OAuth token endpoint:

(http.request.uri.path in {"/login" "/oauth/token"} and http.request.method eq "POST")

3.3 Choose the limit and period

Your choices here determine both protection and user experience. A good starting baseline:

  • Threshold: 5–10 requests
  • Period: 1 minute
  • Keyed by: IP address (or IP + header if many users share IPs)

For most consumer logins:

  • 10 requests per 1 minute per IP is lenient enough for real users who occasionally double‑click or refresh, but harsh on bots.

If you regularly see many legit users behind the same NAT (e.g., corporate campus), consider:

  • Slightly higher threshold (e.g., 20–30/min).
  • Or keying on a session cookie or CF‑Connecting‑IP if you have better client identifiers.

3.4 Select the action

Start conservative, then tighten once you’ve seen real traffic patterns:

  • Phase 1 – Monitor only:
    • Action: “Log” or “Simulate” if available.
    • Use this to confirm thresholds without impacting users.
  • Phase 2 – Soft block:
    • Action: “Managed Challenge” (turnstile‑style) or “JS Challenge.”
    • Good for login endpoints—human users get through, most bots do not.
  • Phase 3 – Hard block:
    • Action: “Block.”
    • Use for clear abuse (e.g., IPs with thousands of login attempts).

For login protection, I recommend:

  • Start with Challenge after X requests.
  • Consider moving to Block for obvious credential stuffing origins identified by WAF / bot scores.

3.5 Save and order your rule

  • Give it a descriptive name: LOGIN: POST /login – 10 req/min/IP.
  • Place it high enough in the rule order that it’s evaluated before generic rules but after any critical allow‑lists (e.g., your own monitoring tools).

Step 4: Build rate limiting rules for your APIs

APIs require a bit more nuance, because you often have:

  • Legitimate high‑frequency clients.
  • Different limits per endpoint or customer tier.
  • Long‑running connections (WebSockets, SSE) that behave differently.

4.1 Decide how to key your limits

For APIs, IP‑based limits are often too coarse. Prefer:

  • API key or token header
    • e.g., http.request.headers["x-api-key"][0]
  • Auth header with tokens:
    • e.g., http.request.headers["authorization"][0]
  • Tenant or client ID in a header or path:
    • e.g., /v1/tenant/{id}/…

Cloudflare’s advanced rate limiting lets you define “client identity” based on headers, not just IP.

Example: limit per x-api-key:

(http.request.uri.path starts_with "/api/" and http.request.method in {"GET" "POST"})

Then configure the rule to key by http.request.headers["x-api-key"][0] rather than IP, if your plan supports custom keying. If not, IP‑based is still better than nothing, but you’ll need to account for shared IP usage.

4.2 Set per‑endpoint and generic API rules

Start with two layers:

  1. Generic API protection

    • Covers the whole /api/ surface.
    • Example: 1000 requests per 5 minutes per key or IP.
    • Protects against sudden spikes and misuse.
  2. Strict rules for sensitive/expensive endpoints

    • Login‑like API routes (e.g., /api/auth/login, /oauth/token).
    • Heavy aggregation or report endpoints.
    • Example: 30 requests per 1 minute per key or even lower.

Example generic rule expression:

http.request.uri.path starts_with "/api/"

Example sensitive‑endpoint rule:

(http.request.uri.path eq "/api/auth/login" and http.request.method eq "POST")

4.3 Recommended starting thresholds

These are conservative, adjust based on your traffic:

  • Public API / shared secrets
    • 100–300 requests per minute per key for standard tier.
    • 1000+/min for premium tier clients (document and enforce via config).
  • Write-heavy or expensive operations
    • 20–60 requests per minute per key.
  • Authentication / token refresh endpoints
    • 10–20 requests per minute per key (most apps need far less).

Always run in log-only mode first if you’re not sure. Check Cloudflare analytics and logs to see who would be affected.


Step 5: Avoid breaking legitimate traffic

Rate limiting that silently breaks production is worse than no rate limiting. A few safeguards:

5.1 Use “log first, enforce later”

  • Many Cloudflare rate limiting features let you monitor or simulate rule actions.
  • Run rules without blocking for a few days.
  • Check:
    • Which clients exceed thresholds.
    • Whether those clients are legitimate (e.g., partner systems, internal jobs, search engine bots).

5.2 Allowlist known good sources (with care)

  • Add exceptions for:
    • Your own uptime monitors.
    • Trusted backend services.
    • Critical internal automation.

Example: Exclude your monitoring IP ranges:

not ip.src in {1.2.3.4 5.6.7.8}
and http.request.uri.path starts_with "/api/"

Don’t overuse allowlists. Each bypass is a potential path for abuse if those IPs or credentials are ever compromised.

5.3 Consider high‑volume legitimate patterns

  • Mobile apps may burst many small requests during app launch.
  • Batch jobs may hit specific endpoints heavily during narrow windows.

If you see consistent patterns:

  • Increase limits only for those specific routes or clients.
  • Or give premium clients separate API keys and attach higher limits to those keys.

Step 6: Combine rate limiting with WAF and bot protection

Rate limiting shouldn’t be your only line of defense. The strongest posture uses Cloudflare’s connectivity cloud capabilities together:

6.1 WAF rules for known attack patterns

  • Enable Cloudflare Managed WAF rulesets for:
    • Login protection heuristics.
    • OWASP top 10 (SQLi, XSS, etc.).
    • API-specific protection.

Many credential stuffing and injection attacks can be blocked before they hit your rate limits.

6.2 Bot protection and score‑based rate limiting

Cloudflare’s bot tools can:

  • Classify requests as automated vs. human.
  • Give you a bot score per request.

You can then:

  • Apply stricter rate limits to low bot scores.
  • Be more lenient for clear human or known good bots.

Example expression:

(http.request.uri.path eq "/login"
 and http.request.method eq "POST"
 and cf.bot_management.score lt 30)

Then set a very low threshold (e.g., 3 requests per minute) with hard blocking for those low‑score requests.

6.3 Zero Trust for internal or sensitive APIs

For internal admin or high‑risk APIs:

  • Use Cloudflare Access (Zero Trust) to require:
    • SSO via your IdP (Okta, Azure AD, etc.).
    • Device posture or user group checks.
  • Behind the scenes, Cloudflare connects these through an outbound‑only Argo Tunnel, so:
    • No inbound ports are opened.
    • Every request is identity‑checked at the edge.

Rate limiting on top of Access gives another safety net against misconfigured internal tools or compromised accounts.


Step 7: Operationalize and monitor your rate limits

Rate limiting is not “set and forget.” You need visibility and tuning.

7.1 Use analytics and logs

  • In the Cloudflare dashboard:
    • Check Security → Events and rate limiting analytics.
    • Look for:
      • Spike in blocked or challenged requests.
      • Concentrated abuse from specific ASN, countries, or paths.
  • Export logs (if available) to your SIEM:
    • Track alignment between rate limiting events and login failures, WAF hits, or API errors.
    • Build alerts on unusual patterns (e.g., sudden 10x increase in rate-limit blocks).

7.2 Feedback loop with app and SRE teams

  • Share metrics like:
    • Top limited IPs/keys.
    • Top limited endpoints.
  • Coordinate with application and SRE teams:
    • Adjust limits when new features launch.
    • Confirm planned batch jobs and expected request patterns.

7.3 Regular tuning cadence

  • Monthly review:
    • Tighten limits where abuse persists.
    • Relax limits where false positives appear.
  • After each major product change:
    • Validate that rate limiting still matches behavior.
    • Update rule expressions if paths or methods changed.

Example configurations you can adapt

Below are sample patterns you can tweak to match your environment.

Example 1: Basic login protection (IP‑based)

  • Expression

    (http.request.uri.path eq "/login" and http.request.method eq "POST")
    
  • Limit: 10 requests per 1 minute per IP

  • Action: Managed Challenge

  • Use case: Public web login for end users.

Example 2: API auth endpoint (per API key)

  • Expression

    (http.request.uri.path eq "/api/auth/login"
     and http.request.method eq "POST"
     and http.request.headers["x-api-key"][0] ne "")
    
  • Keyed by: x-api-key header

  • Limit: 20 requests per 1 minute per key

  • Action: Block

  • Use case: Programmatic login endpoint used by server‑to‑server clients.

Example 3: GraphQL API protection (score‑aware)

  • Expression

    (http.request.uri.path eq "/graphql"
     and http.request.method eq "POST"
     and cf.bot_management.score lt 40)
    
  • Limit: 100 requests per 5 minutes per IP

  • Action: Managed Challenge

  • Use case: Public GraphQL API with known bot pressure.


How this fits into a defensible architecture

When you put Cloudflare in front of your login and API endpoints:

  • Connect: All traffic is routed through Cloudflare’s global network, within milliseconds of your users.
  • Protect: Every request to /login, /api/*, and other sensitive endpoints is:
    • Evaluated at the edge against WAF, bot detection, and your rate limits.
    • Enforced before it reaches origin—no open inbound ports required for internal apps via Argo Tunnel.
  • Build: You can evolve from basic rules to full usage‑based controls with Cloudflare Workers and Durable Objects, without rebuilding core apps.

If you can point to where each request is evaluated (Cloudflare’s edge) and which rules apply, you’ve taken a major step toward a defensible, zero trust‑aligned architecture for both human logins and APIs.


To design the right rate limiting for complex environments, or to integrate with Zero Trust, SASE, and Workers‑based logic across multiple domains and APIs, it’s worth having a deeper conversation with Cloudflare.

Get Started