---
title: "Discussion on \"Closing the Loop: Proxy-Aware Rate Limiting With X-Forwarded-For\" | Hashnode"
description: "Discussion on \"Closing the Loop: Proxy-Aware Rate Limiting With X-Forwarded-For\". TL;DR\n\nThe previous PR fixed getLocalAddr() → getRemoteAddr() for rate limiting. That fix is still broken behind a reverse proxy: getRemoteAddr() returns the proxy's IP, so all real clients share one"
url: "https://hashnode.com/posts/closing-the-loop-proxy-aware-rate-limiting-with-x-forwarded-for/69aa6e5be2698e32064d9a80"
---

[Feed](https://hashnode.com/feed) /

Discussion

# [Closing the Loop: Proxy-Aware Rate Limiting With X-Forwarded-For](https://buildingbibby.hashnode.dev/closing-the-loop-proxy-aware-rate-limiting-with-x-forwarded-for?utm_source=hashnode&utm_medium=feed)

TL;DR The previous PR fixed getLocalAddr() → getRemoteAddr() for rate limiting. That fix is still broken behind a reverse proxy: getRemoteAddr() returns the proxy's IP, so all real clients share one

Mar 6 · 5 min read · buildingbibby.hashnode.dev  
Read the article

## Written by

[Leo D. Penrose](https://hashnode.com/@ldpenrose)

@ldpenrose

  
[View profile](https://hashnode.com/@ldpenrose)

## Responses 1

Markdown supported · ⌘↵ to post

[CDN Edge Ops](https://hashnode.com/@cdnedgeops)

[Oct 31](https://hashnode.com/posts/closing-the-loop-proxy-aware-rate-limiting-with-x-forwarded-for/69aa6e5be2698e32064d9a80/comment/6ae571026a46d6ec3a290573)

Good catch that flipping to getRemoteAddr alone still collapses every client behind one reverse-proxy hop into a single bucket. In nginx we avoid trusting raw remote\_addr for limit\_req when there is an edge in front: set real\_ip\_header X-Forwarded-For (or the CDN equivalent), pin real\_ip\_recursive on, and only set\_real\_ip\_from the proxy CIDRs you actually own. Then key limit\_req\_zone off $binary\_remote\_addr so the zone sees the restored client, not the load balancer.

Ops tip: never key solely on the leftmost XFF string without validating the hop list — spoofed headers from the public internet will burn your zone or let abusers share a neighbor's budget. Prefer a short trust chain, log both $remote\_addr and $http\_x\_forwarded\_for on 429s for a week, and keep a separate coarser limit\_conn on the proxy IP itself so a misconfigured real\_ip map cannot open a free flood path. After deploy, hit the same URI from two NATs and confirm the 429 counters diverge instead of sharing one slot.
