# Nginx $upstream\_cache\_status not available when used in rate limiting

**URL:** <https://www.ruby-forum.com/t/nginx-upstream-cache-status-not-available-when-used-in-rate-limiting/244959>\
**Category:** NGINX\
**Created:** [July 18, 2016, 9:27pm UTC](https://www.ruby-forum.com/t/nginx-upstream-cache-status-not-available-when-used-in-rate-limiting/244959 "2016-07-18T21:27:45Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rafa\_F](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/958977/32.png) [@Rafa\_F](https://www.ruby-forum.com/u/Rafa_F)\
**Post date:** [July 18, 2016, 9:27pm UTC](https://www.ruby-forum.com/t/nginx-upstream-cache-status-not-available-when-used-in-rate-limiting/244959/1 "2016-07-18T21:27:45Z")

</div>

Hi,

I use Nginx as reverse proxy, and I would like to rate limit the  
requests  
to origin server, but only limit the requests with cache status EXPIRED.  
I  
just tested with a map “cache\_key”, and the rate limiting doesn’t work,  
the  
$cache\_key was logged as empty string. But changing  
$upstream\_cache\_status  
to non-upstream variables like $remote\_addr and adding an IP match value  
will make the rate limiting work. The zone I defined like so:  
limit\_req\_zone $cache\_key zone=cache\_host:1m rate=1r/m;  
map $upstream\_cache\_status $cache\_key {  
EXPIRED $host;  
default “”;  
}  
I enabled cache setting in nginx.conf, and one of my server chunk uses  
the  
rate limit zone like below:  
limit\_req zone=cache\_host busrt=1;

Is this because $upstream\_cache\_status value is set after the request is  
sent to origin server and got the response, while $cache\_key is used in  
rate limit zone which checked before the request was sent to origin  
server? If  
so, is there a recommended way to implement rate limiting only for  
requests  
with specific cache status?

Thanks!  
Linna

---

<div class="post-metadata">

**Author:** ![Linna.Ding](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/46a35a/32.png) [@Linna.Ding](https://www.ruby-forum.com/u/Linna.Ding)\
**Post date:** [July 20, 2016, 8:04pm UTC](https://www.ruby-forum.com/t/nginx-upstream-cache-status-not-available-when-used-in-rate-limiting/244959/2 "2016-07-20T20:04:17Z")

</div>

I assume $upstream\_cache\_status variable is set after requests are sent  
and  
responses are got. But is there a way to do do rate limiting ignoring  
cache?  
Really appreciate any help on this.

Thanks.

Posted at Nginx Forum:

> **[Re: Nginx $upstream\_cache\_status not available when used in rate limiting](https://forum.nginx.org/read.php?2,268345,268383#msg-268383)**
>
> Hi, I use Nginx as reverse proxy, and I would like to rate limit the requests to origin server, but only limit the requests with cache status EXPIRED. I just tested with a map "cache\_key", and the rate limiting doesn't work, the $cache\_key...

---

<div class="post-metadata">

**Author:** ![Linna.Ding](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/46a35a/32.png) [@Linna.Ding](https://www.ruby-forum.com/u/Linna.Ding)\
**Post date:** [July 20, 2016, 8:17pm UTC](https://www.ruby-forum.com/t/nginx-upstream-cache-status-not-available-when-used-in-rate-limiting/244959/3 "2016-07-20T20:17:09Z")

</div>

On Wed, Jul 20, 2016 at 02:03:44PM -0400, linnading wrote:

Hi there,

> I assume $upstream\_cache\_status variable is set after requests are sent and  
> responses are got. But is there a way to do do rate limiting ignoring cache?  
> Really appreciate any help on this.

I’m afraid that, having read the mails, I’m not at all sure what kind  
of limiting you want to do.

If 10 requests come in at the same time to-or-from the same something,  
you want the last few requests to be delayed or rejected.

What is the “something” that you care about?

## f

Francis D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Linna.Ding](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/46a35a/32.png) [@Linna.Ding](https://www.ruby-forum.com/u/Linna.Ding)\
**Post date:** [July 20, 2016, 8:52pm UTC](https://www.ruby-forum.com/t/nginx-upstream-cache-status-not-available-when-used-in-rate-limiting/244959/4 "2016-07-20T20:52:47Z")

</div>

Hi Francis,

It is “to the same upstream server” that I care about. I would like to  
limit the request rate to the same upstream server.

The Scenarios is like:  
10 requests at the same time to the same upstream server, the upstream  
server should only receive requests at rate 1r/m. Last few requests will  
be  
delayed or rejected. But for these last few requests, some of them can  
be  
served by cache, they should not be delayed/rejected.

Thanks,  
Linna

Posted at Nginx Forum:

> **[Re: Nginx $upstream\_cache\_status not available when used in rate limiting](https://forum.nginx.org/read.php?2,268345,268386#msg-268386)**
>
> Hi, I use Nginx as reverse proxy, and I would like to rate limit the requests to origin server, but only limit the requests with cache status EXPIRED. I just tested with a map "cache\_key", and the rate limiting doesn't work, the $cache\_key...

---

<div class="post-metadata">

**Author:** ![Linna.Ding](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/46a35a/32.png) [@Linna.Ding](https://www.ruby-forum.com/u/Linna.Ding)\
**Post date:** [July 20, 2016, 11:29pm UTC](https://www.ruby-forum.com/t/nginx-upstream-cache-status-not-available-when-used-in-rate-limiting/244959/5 "2016-07-20T23:29:20Z")

</div>

On Wed, Jul 20, 2016 at 02:52:10PM -0400, linnading wrote:

Hi there,

> It is “to the same upstream server” that I care about. I would like to  
> limit the request rate to the same upstream server.

That makes sense, thanks.

I am not aware of a way to achieve this directly in stock nginx.

I see that there is a third-party module at  
[GitHub - cfsego/nginx-limit-upstream: limit the number of connections to upstream for NGINX · GitHub](https://github.com/cfsego/nginx-limit-upstream) which looks like  
it aims to do what you want; and I see that nginx-plus has a  
“max\_conns” value per server in an upstream block, documented at  
[Module ngx\_http\_upstream\_module](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server)

If non-stock is ok for you, possibly one of those can work?

> The Scenarios is like:  
> 10 requests at the same time to the same upstream server, the upstream  
> server should only receive requests at rate 1r/m. Last few requests will be  
> delayed or rejected. But for these last few requests, some of them can be  
> served by cache, they should not be delayed/rejected.

I think that the limit\_\* directives implementation is such that the  
choice is made before the upstream is chosen; and there are no explicit  
limits on the connections to upstream. That is likely why the  
third-party  
module was created.

Cheers,

## f

Francis D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Linna.Ding](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/46a35a/32.png) [@Linna.Ding](https://www.ruby-forum.com/u/Linna.Ding)\
**Post date:** [July 21, 2016, 4:52pm UTC](https://www.ruby-forum.com/t/nginx-upstream-cache-status-not-available-when-used-in-rate-limiting/244959/6 "2016-07-21T16:52:03Z")

</div>

Thanks Francis and Valentin!  
These options can help a lot to limit requests to upstream server,  
thought  
not related to rate limiting.

Thanks!  
~L

Posted at Nginx Forum:

> **[Re: Nginx $upstream\_cache\_status not available when used in rate limiting](https://forum.nginx.org/read.php?2,268345,268404#msg-268404)**
>
> Hi, I use Nginx as reverse proxy, and I would like to rate limit the requests to origin server, but only limit the requests with cache status EXPIRED. I just tested with a map "cache\_key", and the rate limiting doesn't work, the $cache\_key...

---

<div class="post-metadata">

**Author:** ![Linna.Ding](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/46a35a/32.png) [@Linna.Ding](https://www.ruby-forum.com/u/Linna.Ding)\
**Post date:** [July 20, 2016, 11:55pm UTC](https://www.ruby-forum.com/t/nginx-upstream-cache-status-not-available-when-used-in-rate-limiting/244959/7 "2016-07-20T23:55:37Z")

</div>

On Wednesday 20 July 2016 14:52:10 linnading wrote:

> 

[..]

While “proxy\_cache\_lock” isn’t what you’re asking about, it can  
significantly  
reduce number of requests that reaches your upstream server.

> **[Module ngx\_http\_proxy\_module](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_lock)**
>
> The ngx\_http\_proxy\_module module allows passing requests to another server.

wbr, Valentin V. Bartenev
