Let me describe what I am trying to do first.

I have a bunch of pictures in a directory called /images/*.(jpg|gif|png|blah blah|)

Now say these images are embedded in an html page and I dont really care which image or where its embedded.

For every 10th request for the same picture file (if possible) or for any picture I want to display a fixed image (e.g. trollface.jpg). thats it!

I have searched around a bit but i am not even sure what I am looking for. Rewrite might help but then its a permanent thing. this has got to do something with requests. I have heard perl scripts can be used with nginx. I can't write an nginx module (though I did bravely lookup the docs and then gave up)

Before you ask "But why don't you do it in application, noob?". This is a static files only server. The point is to not execute any binary at all.


Another solution could be to have nginx proxy to itself. Set up two upstream vhosts, one which serves your normal images and one which serves trollface.jpg only.

Include the normal vhost as your upstream server with a weight of 9 and the trollface vhost as the other upstream server with a weight of 1.

This will serve the alternate image once in every 10 requests but not once in every 10 requests for each individual file.

Alternatively, the HttpEchoModule might be able to do the trick for you. A combination of echo_subrequest_async and echo_random could give you a 1 in 10 chance of delivering trollface.jpg instead of the file they requested.

There is also this post on the mailing list which suggests that someone is working on per-IP-address counters in the nginx config.

Note that I am not recommending any of these solutions, just noting that they're possible.

  • awesome! fantastic idea to use vhost upstream. thinking out of the box. :) In my own answer below I posted a link to HTTPEchoModule I did not see echo_Random and this definitely helps. per-IP would be a good to have. I am looking at per referrer, but this is a good place to start. Thanks – Abhishek Dujari Nov 20 '11 at 12:59

I can think of one solution to your question without the need to hack nginx.

Shortly, it can be handled on the file-system level.

In more details, you can configure an incron script to be executed on the IN_ACCESS event. This means that your script will be executed whenever a specific file is accessed (read). In this script, you can do whatever you want like counting the read accesses and them overwrite the file with another one (don't forget to keep a backup).

Please, note that the server caching may affect this method. The file/image might not be read when it is cached by the server or an intermediate proxy server.

I am assuming Linux platform. You may need to install the incron pacakge.

  • sounds like a plausible solution. Do you have any example of this IN_ACCESS event? I will lookup incron now. edit: ok i checked incron. although in_access will occur everytime , i am wondering how to do the nTH access for every file. – Abhishek Dujari Nov 19 '11 at 13:28
  • Look at the examples in this page: linux.die.net/man/5/incrontab – Khaled Nov 19 '11 at 13:32
  • Yes, but I don't see how we can store state information. For e.g. file xyz.txt was accessed 12 times - lets replace it. So end of it I need to maintain a running process or (FILE) to hold these values. I think I found an easier solution using nginx. posting answer. – Abhishek Dujari Nov 19 '11 at 13:43
  • You need to save this data yourself in a text file or database etc.. – Khaled Nov 19 '11 at 15:01
  • yes agreed. +1 for incron suggestion. might be useful. – Abhishek Dujari Nov 19 '11 at 15:16

Randomly.. I fall upon this.


THis seems much easier than writing an entire NGINX module. Basically we use the already made nginx modules except it seems I have to use memcache to save counters. But at least it looks possible.

There are updated examples for memcache and subrequests. It will still slow down nginx a bit due to "if" calls but not too much. I would prefer Khaled's method if I knew how to go about it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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