Priority Rules
When a request comes in, NGINX may have multiple location blocks that could match.
To avoid ambiguity, NGINX follows a strict priority algorithm to select one—and only one—location.
The 4 Location Types (in Priority Context)
| Type | Syntax | Priority |
|---|---|---|
| Exact match | location = /path | Highest |
Prefix match (^~) | location ^~ /path/ | High |
| Regex match | location ~, ~* | Medium |
| Normal prefix match | location /path/ | Low (longest wins) |
The Actual Matching Algorithm (Step by Step)
NGINX processes locations in this exact order:
1. Exact Match (=)
location = /login {
return 403;
}
- If the request URI is exactly
/login - NGINX immediately stops searching
- No other locations are checked
Nothing can override an exact match
2. Prefix Match with ^~
location ^~ /static/ {
root /var/www/static;
}
- NGINX checks prefix locations marked with
^~ - If matched:
- Regex checks are skipped entirely
- This location is selected
Used to protect important prefixes from regex overrides
3. Regex Matches (~, ~*)
location ~ \.php$ {
fastcgi_pass php;
}
- Regex locations are tested in the order they appear
- First matching regex wins
- Order matters!
Regex can override normal prefix matches
4. Normal Prefix Matches
location /api/ {
proxy_pass http://api;
}
location / {
try_files $uri $uri/ =404;
}
- Among normal prefixes:
- Longest matching prefix wins
/api/beats/
Visual Priority Order (Memory Trick)
= (Exact)
^~ (Strong prefix)
~ (Regex – first match wins)
/ (Longest normal prefix)
Full Example with Multiple Matches
server {
location = /admin {
return 403;
}
location ^~ /static/ {
root /var/www/static;
}
location ~ \.php$ {
fastcgi_pass php;
}
location /static/images/ {
root /var/www/images;
}
location / {
try_files $uri $uri/ =404;
}
}
Request-by-Request Breakdown
-
Request 1:
/admin- Exact match exists
location = /adminis selected
-
Request 2:
/static/logo.png- Matches
^~ /static/ - Regex is skipped
/static/location used
- Matches
-
Request 3:
/static/images/a.php^~ /static/matches- Regex is skipped
/static/(not.php)
-
Request 4:
/index.php- No exact match
- No
^~prefix - Regex
\.php$matches - PHP location selected
-
Request 5:
/about/team- No exact
- No
^~ - No regex
- Prefix
/used - default handler
Why ^~ Exists (Very Important)
Without ^~:
location /images/ {
root /var/www/images;
}
location ~ \.jpg$ {
root /var/www/jpg;
}
- Request:
/images/photo.jpg - Regex wins → wrong directory
Fix
location ^~ /images/ {
root /var/www/images;
}