Nginx location priority

Solution 1:

From the HTTP core module docs:

  1. Directives with the "=" prefix that match the query exactly. If found, searching stops.
  2. All remaining directives with conventional strings. If this match used the "^~" prefix, searching stops.
  3. Regular expressions, in the order they are defined in the configuration file.
  4. If #3 yielded a match, that result is used. Otherwise, the match from #2 is used.

Example from the documentation:

location  = / {
  # matches the query / only.
  [ configuration A ] 
}
location  / {
  # matches any query, since all queries begin with /, but regular
  # expressions and any longer conventional blocks will be
  # matched first.
  [ configuration B ] 
}
location /documents/ {
  # matches any query beginning with /documents/ and continues searching,
  # so regular expressions will be checked. This will be matched only if
  # regular expressions don't find a match.
  [ configuration C ] 
}
location ^~ /images/ {
  # matches any query beginning with /images/ and halts searching,
  # so regular expressions will not be checked.
  [ configuration D ] 
}
location ~* \.(gif|jpg|jpeg)$ {
  # matches any request ending in gif, jpg, or jpeg. However, all
  # requests to the /images/ directory will be handled by
  # Configuration D.   
  [ configuration E ] 
}

If it's still confusing, here's a longer explanation.

Solution 2:

It fires in this order.

  1. = (exactly)

    location = /path

  2. ^~ (forward match)

    location ^~ /path

  3. ~ (regular expression case sensitive)

    location ~ /path/

  4. ~* (regular expression case insensitive)

    location ~* .(jpg|png|bmp)

  5. /

    location /path

Solution 3:

There is a handy online tool for testing location priority now:
location priority testing online

Solution 4:

Locations are evaluated in this order:

  1. location = /path/file.ext {} Exact match
  2. location ^~ /path/ {} Priority prefix match -> longest first
  3. location ~ /Paths?/ {} (case-sensitive regexp) and location ~* /paths?/ {} (case-insensitive regexp) -> first match
  4. location /path/ {} Prefix match -> longest first

The priority prefix match (number 2) is exactly as the common prefix match (number 4), but has priority over any regexp.

For both prefix matche types the longest match wins.

Case-sensitive and case-insensitive have the same priority. Evaluation stops at the first matching rule.

Documentation says that all prefix rules are evaluated before any regexp, but if one regexp matches then no standard prefix rule is used. That's a little bit confusing and does not change anything for the priority order reported above.