# Conditional cache

**URL:** <https://www.ruby-forum.com/t/conditional-cache/194268>\
**Category:** NGINX\
**Created:** [September 1, 2010, 9:01pm UTC](https://www.ruby-forum.com/t/conditional-cache/194268 "2010-09-01T21:01:45Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![paul2791](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/8797f3/32.png) [@paul2791](https://www.ruby-forum.com/u/paul2791)\
**Post date:** [September 1, 2010, 9:01pm UTC](https://www.ruby-forum.com/t/conditional-cache/194268/1 "2010-09-01T21:01:45Z")

</div>

I’ve been trying to set up two separate proxy caches, one for logged in  
users, one for guests. The one for guests had a very long expiry as  
guest pages don’t change much, User pages are very dynamic and expiry is  
very short.

Using cookies i can tell if a page request is by a user or guest, but I  
cannot see any easy way to alter the proxy as all the proxy\_cache  
commands can’t be put inside an if.

I’ve managed the following workaround, which works fine but it seems  
strange i have to use this method when there must be an easier and more  
straightforward way that i am just not seeing

set $memcached\_key “pages:$uri:$cache\_key”; ### dummy key, will never  
exist as i’m not using memcache for nginx  
if ($cache\_key = “guest”){error\_page 404 = @guests;} #set 404 for quest  
if ($cache\_key != “guest”){error\_page 404 = @users;} #set 404 for users  
memcached\_pass 127.0.01:11220; ## this server is empty, has no keys will  
ALWAYS return 404

location @users {  
proxy\_cache users;  
proxy\_cache\_key “$request\_uri$cache\_key”;  
proxy\_cache\_valid 502 504 1m;  
proxy\_cache\_valid any 5m;  
proxy\_pass [http://127.0.0.1:10098](http://127.0.0.1:10098);  
}

location @guests {  
proxy\_cache guests;  
proxy\_cache\_key “$request\_uri$cache\_key”;  
proxy\_cache\_valid 502 504 1m;  
proxy\_cache\_valid any 60m;  
proxy\_pass [http://127.0.0.1:10098](http://127.0.0.1:10098);  
}

Posted at Nginx Forum:

> **[conditional cache](https://forum.nginx.org/read.php?2,126105,126105#msg-126105)**
>
> I've been trying to set up two separate proxy caches, one for logged in users, one for guests. The one for guests had a very long expiry as guest pages don't change much, User pages are very dynamic and expiry is very short. Using cookies i can tell...

---

<div class="post-metadata">

**Author:** ![paul2791](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/8797f3/32.png) [@paul2791](https://www.ruby-forum.com/u/paul2791)\
**Post date:** [September 2, 2010, 1:21am UTC](https://www.ruby-forum.com/t/conditional-cache/194268/2 "2010-09-02T01:21:45Z")

</div>

Hello!

On Wed, Sep 01, 2010 at 03:00:30PM -0400, paul2791 wrote:

> strange i have to use this method when there must be an easier and more  
> straightforward way that i am just not seeing
> 
> set $memcached\_key “pages:$uri:$cache\_key”; ### dummy key, will never  
> exist as i’m not using memcache for nginx  
> if ($cache\_key = “guest”){error\_page 404 = @guests;} #set 404 for quest  
> if ($cache\_key != “guest”){error\_page 404 = @users;} #set 404 for users  
> memcached\_pass 127.0.01:11220; ## this server is empty, has no keys will  
> ALWAYS return 404

It’s good idea to avoid using anything in “if” except “return” and  
“rewrite … last”. See [GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com · GitHub](http://wiki.nginx.org/IfIsEvil).

Also it’s probably better use 418 status code here ;). I would  
recommend something like this:

location / {  
error\_page 418 = @guests;

```
   if (...detect guests...) {
       return 418;
   }

   proxy_cache users;
   ...

```

}

location @guests {  
proxy\_cache guests;  
…  
}

> proxy\_cache\_key “$request\_uri$cache\_key”;  
> proxy\_cache\_valid 502 504 1m;  
> proxy\_cache\_valid any 60m;  
> proxy\_pass [http://127.0.0.1:10098](http://127.0.0.1:10098);  
> }

Alternatively you may want to just set correct Cache-Control /  
Expires / X-Accel-Expires headers in backend’s response and avoid  
explicitly setting validity via proxy\_cache\_valid.

Maxim D.

---

<div class="post-metadata">

**Author:** ![paul2791](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/8797f3/32.png) [@paul2791](https://www.ruby-forum.com/u/paul2791)\
**Post date:** [September 2, 2010, 5:03pm UTC](https://www.ruby-forum.com/t/conditional-cache/194268/3 "2010-09-02T17:03:41Z")

</div>

Maxim,  
Thats brilliant, thanks  
Would proxy\_pass be considered as a rewrite and safe within an IF as i  
use it a lot to bypass cache?

Also, 418 is great code, had never seen that before. I do have some  
logic elsewhere in my conf where i have more than two ifs. Does Nginx  
allow the use of nondefined codes? 419 for instance? so i could have

location / {  
error\_page 418 = @cache1;  
error\_page 419 = @cache2;

if (…needtoshowcache1…) {  
return 418;  
}  
if (…needtoshowcache2…) {  
return 419;  
}

proxy\_cache cache3;  
…  
}

location @cache1 {  
proxy\_cache cache1;  
…  
}  
location @cache2 {  
proxy\_cache cache2;  
…  
}

Ive got as far as testing the error\_page 419 =@cache2 ; line and nginx  
didn’t choke on that, but haven’t tested the actual return yet

And yes, all of this would be easier of the developers set expires in  
backend, but until they do, im using nginx to make sure our site flies  
as fast as it can no matter how slow their code is

Posted at Nginx Forum:

> **[Re: conditional cache](https://forum.nginx.org/read.php?2,126105,126361#msg-126361)**
>
> I've been trying to set up two separate proxy caches, one for logged in users, one for guests. The one for guests had a very long expiry as guest pages don't change much, User pages are very dynamic and expiry is very short. Using cookies i can tell...

---

<div class="post-metadata">

**Author:** ![paul2791](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/8797f3/32.png) [@paul2791](https://www.ruby-forum.com/u/paul2791)\
**Post date:** [September 2, 2010, 5:53pm UTC](https://www.ruby-forum.com/t/conditional-cache/194268/4 "2010-09-02T17:53:29Z")

</div>

Hello!

On Thu, Sep 02, 2010 at 11:15:14AM -0400, paul2791 wrote:

> I just tried a quick test, using your first method for users/guests ,  
> with 419 instead of 418. Seems to work fine. Any reason I couldn’t or  
> shouldn’t use these codes to redirect to different interal @locations???

418 is one from RFC 2324, “Hyper Text Coffee Pot Control  
Protocol”. It means “I’m a teapot”. Good code to say request  
should be processed elsewhere. 😉

You are free to use any 4xx/5xx code otherwise unused in a  
particular location (and it’s good idea to avoid overloading codes  
which may happen to be returned due to other reasons).

Maxim D.

---

<div class="post-metadata">

**Author:** ![paul2791](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/8797f3/32.png) [@paul2791](https://www.ruby-forum.com/u/paul2791)\
**Post date:** [September 2, 2010, 5:16pm UTC](https://www.ruby-forum.com/t/conditional-cache/194268/5 "2010-09-02T17:16:00Z")

</div>

I just tried a quick test, using your first method for users/guests ,  
with 419 instead of 418. Seems to work fine. Any reason I couldn’t or  
shouldn’t use these codes to redirect to different interal @locations???

Posted at Nginx Forum:

> **[Re: conditional cache](https://forum.nginx.org/read.php?2,126105,126372#msg-126372)**
>
> I've been trying to set up two separate proxy caches, one for logged in users, one for guests. The one for guests had a very long expiry as guest pages don't change much, User pages are very dynamic and expiry is very short. Using cookies i can tell...

---

<div class="post-metadata">

**Author:** ![paul2791](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/8797f3/32.png) [@paul2791](https://www.ruby-forum.com/u/paul2791)\
**Post date:** [September 3, 2010, 12:31pm UTC](https://www.ruby-forum.com/t/conditional-cache/194268/6 "2010-09-03T12:31:35Z")

</div>

On Thu, Sep 2, 2010 at 5:52 PM, Maxim D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 418 is one from RFC 2324, “Hyper Text Coffee Pot Control  
> Protocol”. Â It means “I’m a teapot”. Â Good code to say request  
> should be processed elsewhere. 😉

Isn’t that non-canonical? it’s for coffee machines, not for normal  
servers or proxies.  
(Only joking, I guess the Internet won’t stop working because of this  
non standard usage)  
😉
