Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am trying to set up nginx and I don't get the point how to do the following setup:

I have an URL that needs to be passed to different backends depending on a range the '123' matches (e.g. 0-150 -> backend1, 151-400 -> backend2, ...).

Since I have almost no experience with regexp, I don't know how to do this (in location?).

Thanks in advance for your help, Sascha

share|improve this question

migrated from May 14 '11 at 17:02

This question came from our site for professional and enthusiast programmers.

I think you should ask this on instead. – Jonas May 12 '11 at 8:25
This would be too complicated, unobvious and possible buggy regex. What you're trying to achieve, load-balancing? – Timofey Stolbov May 12 '11 at 9:06
The number would be the resolution of an image. We have 4 different backends to deliver these images and we want load-balancing in the form, that all images with res <150 go to backend1, 151-400 to backend2... – vreen May 12 '11 at 10:35
up vote 1 down vote accepted

You can use:

location ~ ^/foo/bar/(\d|\d\d|1[0-4]\d|150)/ {
    proxy_pass backend1;

location ~ ^/foo/bar/(15[1-9]|1[6-9]\d|[23]\d\d|400)/ {
    proxy_pass backend2;

But why you do load balancing in such a heterogeneous way? Why not just shard by image id/hash of name? Your solution will result in different load and even load patterns on different servers. It would be tricky to administer them.

share|improve this answer
Thank you, your solutions seems to work great on my testing machine! The reason for this kind of load-balancing is, that some resolutions are requested more often than others and in this way we are able to share the load constantly. However the backends are nodes in a cluster that create the requested resolution on the fly (original image is in an oracle db) and keep them in a cache. In my opinion, this is not the right way, but this was not my decision ;-) However: Thank you very much!! – Sascha May 16 '11 at 6:24

If you have a static set of the picture sizes, you can make use of map. Declare backends and a map in http section of Nginx configuration file:

http {
  upstream backend1 {
    server backend1:80;

  upstream backend2 {
    server backend2:80;

  map $pic_size $backend {
    default backend_default;
    80 backend1;
    150 backend2;

Declare the location in server:

location ~ ^/foo/bar/(?<pic_size>\d+) {
  proxy_pass http://$backend;

If you'd like to support conditional logic, I would recommend using Perl handler. Again, in http:

http {
  perl_set $backend 'sub {
my $r = shift;
my $pic_size = $r->variable("pic_size");

$pic_size <= 150 and return "backend1";
$pic_size <= 400 and return "backend2";
return "backend_default";

In location:

location ~ ^/foo/bar/(?<pic_size>\d+) {
  proxy_pass http://$backend:80;
share|improve this answer
The $map was a huge help to me with a related problem I was trying to figure out (how to selectively forward a particular URL to a backend, though based on a text string rather than numeric) without resorting to use of the dreaded "if". Thanks! – jsh Jan 17 '13 at 16:29

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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