Nginx Location Block Matching Rules
Understand Nginx location block matching priority including exact match, preferential prefix, regex, and generic prefix with practical routing examples.
Detailed Explanation
The location directive is one of the most important and frequently misunderstood concepts in Nginx configuration. It determines how Nginx processes requests based on the URI path, and understanding the matching priority is essential for correct routing behavior.
Location Types and Priority
Nginx evaluates location blocks in a specific order of priority, regardless of the order they appear in the configuration file:
- Exact match (
=): Highest priority. Matches the URI exactly and stops searching immediately. - Preferential prefix (
^~): If this prefix matches, Nginx skips all regex evaluation. - Regex (
~case-sensitive,~*case-insensitive): Evaluated in the order they appear in the file. - Prefix match (no modifier): The longest matching prefix wins, but a regex match can override it.
location = /exact { } # Only matches /exact
location ^~ /images/ { } # Prefix match, skips regex
location ~ \.php$ { } # Case-sensitive regex
location ~* \.(jpg|png)$ { } # Case-insensitive regex
location /documents/ { } # Standard prefix
location / { } # Catch-all fallback
How Matching Works Step by Step
When a request arrives, Nginx first checks all prefix locations (both regular and preferential) and remembers the longest match found. If the longest match uses the ^~ modifier, regex evaluation is skipped entirely. Otherwise, Nginx proceeds to check regex locations in their configuration file order. If any regex matches, it takes precedence over the remembered prefix match. If no regex matches, the longest prefix match is used.
Common Configuration Patterns
Serve static files directly while proxying everything else:
location ~* \.(css|js|jpg|png|gif|ico|svg|woff2)$ {
root /var/www/static;
expires 30d;
}
location / {
proxy_pass http://backend;
}
API versioning with separate backends:
location /api/v1/ {
proxy_pass http://api_v1_backend;
}
location /api/v2/ {
proxy_pass http://api_v2_backend;
}
Nested Locations
Locations can be nested within each other. Inner locations inherit directives from outer locations unless they are explicitly overridden:
location /app/ {
proxy_pass http://backend;
location /app/static/ {
alias /var/www/static/;
}
}
Debugging Location Matching
To debug which location block is handling a specific request, add a custom response header in each location block:
location / {
add_header X-Debug-Location "root-catchall" always;
}
Then inspect the response headers with curl -I to confirm the correct block is being matched for each request path.
Use Case
You are configuring complex Nginx routing rules and need to understand which location block handles each request to avoid unexpected behavior with overlapping patterns.