Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

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 use Nginx to served cached files produced by a web application, and have spotted a potential problem; that the url-space is wide, and will exceed the Ext3 limit of 32000 subdirectories.

I would like to break up the subdirectories, making, say, a two-level filesystem cache. So, where I am currently caching a file at


I would store that instead at something like


My trouble is that I can't get try_files, or even rewrite to make that mapping. My searching on the subject leads me to believe that I need to do something like this (heavily abbreviated):

http {
    map $request_uri $prefix {
        /aa*   a/a;
        /ab*   a/b;
        /ac*   a/c;
        /zz*   z/z;

    location / {
        try_files /var/cache/www/$prefix/$request_uri/index.html @fallback;

        # or
        # if (-f /var/cache/www/$prefix/$request_uri/index.html) {
        #     rewrite ^(.*)$ /var/cache/www/$prefix/$1/index.html;
        # }

But I can't get the /aa* pattern to match the incoming uri. Without the *, it will match an exact uri, but I can't get it to match just the first two characters.

The Nginx documentation suggests that wildcards should be allowed, but I can't see a way to get them to work. Is there a way to do this? Am I missing something simple? Or am I going about this the wrong way?

share|improve this question

I suspect that globs are only supported with the special hostname mode. You need to use regular expressions to achieve this, so your map should look like this:

map $request_uri $prefix {
    ~^/aa(?<suffix>.*)$ /a/a/$suffix;
share|improve this answer

A more careful reading of the Nginx documentation reveals that the functionality that I want is part of the Rewrite module. What I thought needed to be:

map $request_uri $prefix {
    /aa* a/a;
    /ab* a/b;
    /ac* a/c;
    /zz* z/z;

is easily implemented with this:

if ($request_uri ~= "/(\w)(\w)(.*)") {
    set $prefix $1/$2;

And then the try_files directive works like this:

location / {
    root /var/www/cache;
    try_files /$prefix$request_uri @fallback;
share|improve this answer

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.