We are using apache2.2 as a front-end server with application servers as reverse proxies behind apache.

We are using mod_cache for some images and enabled it like this:

<IfModule mod_disk_cache.c>
    CacheEnable disk /
    CacheRoot /var/cache/apache2/mod_disk_cache
    CacheIgnoreCacheControl On
    CacheMaxFileSize 2500000
    CacheIgnoreURLSessionIdentifiers jsessionid
    CacheIgnoreHeaders Set-Cookie

The image urls vary completely and have no common start pattern, but they all end in ".png". Thats why we used the root in CacheEnable /

If not served from the cache, the request is forwarded to an application server via reverse proxy. So far so good, cache is working fine.

But I really only need to cache all image request ending in ".png". My above configuration still works as my application server send an appropriate Cache-Control: no-cache header on the way back to apache. So most pages send a no-cache header back and they get not cached at all. My ".png" responses doesn't send a Cache-Control header so apache is only going to cache all urls with ".png". Fine.

But when a new request enters apache, apache does not know that only .png requests should be considered, so every request is checking a file on disk (recorded with strace -e trace=file -p pid):

[pid 19063] open("/var/cache/apache2/mod_disk_cache/zK/q8/Kd/g6OIv@woJRC_ba_A.header", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)

I don't want to have apache going to disk every request, as the majority of requests are not cached at all. And we have up to 10.000 request/s at peak time. Sometimes our read IO wait spikes. It is not getting really slow, but we try to tweak it for better performance.

In apache 2.4 you can say:

<LocationMatch .png$>
    CacheEnable disk

This is not possible in 2.2 and as I see no backports for debian I am not going to upgrade.

So I tried to tweak apache2.2 to follow my rules:

<IfModule mod_disk_cache.c>
  SetEnvIf Request_URI "\.png$" image
  RequestHeader unset Cache-Control
  RequestHeader append Cache-Control no-cache env=!image
  CacheEnable disk /
  CacheRoot /var/cache/apache2/mod_disk_cache
  #CacheIgnoreCacheControl on 
  CacheMaxFileSize 2500000
  CacheIgnoreURLSessionIdentifiers jsessionid
  CacheIgnoreHeaders Set-Cookie

The idea is to let apache decide to serve request from cache based on Cache-control header (CacheIgnoreCacheControl default to off). And before simply set a RequestHeader based on the request. If it is not an image request, set a Cache-control header, so it should bypass the cache at all.

This does not work, I guess because of late processing of RequestHeader directive, see https://httpd.apache.org/docs/2.2/mod/mod_headers.html#early

I can't add early processing as "early" keyword can't be used together with a conditional "env=!image"

I can't change the url requesting the images and I know there are of course other solutions. But I am only interested in configuring apache2.2 to reach my goal.

Does anybody has an idea how to achieve my goal?

1 Answer 1



The no-cache environment variable can be set to disable caching on a finer grained set of resources in versions 2.2.12 and later.

So you should be able to disable caching on everything other than requests ending in .png with

SetEnvIf Request_URI !\.png$ no-cache

  • this doen't help, see here httpd.apache.org/docs/2.2/env.html : "When set, mod_cache will not save an otherwise cacheable response. This environment variable does not influence whether a response already in the cache will be served for the current request." so it does not cache a response, but it will still check if there is something in the cache.
    – Janning
    Jul 3, 2012 at 18:52
  • hmmm... the only other way around I can think of then is using a second local copy of Apache configured to cache and then proxy the image requests to that? (ala stackoverflow.com/questions/10674743/…). Your main traffic would incur a tiny hit on the regex. Your image traffic will incur a bit of latency and fd's for the tcp connection.
    – Matt
    Jul 12, 2012 at 7:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.