If you manage an Nginx-based infrastructure, you‘ve likely needed to implement conditional logic like:
- Blocking misbehaving IPs
- Showing custom error pages
- Doing A/B testing
- Blue/green deployments
This is where Nginx‘s if directive comes in handy – it allows you to make configuration decisions dynamically based on variables.
However, if can be tricky to use properly in Nginx. In this comprehensive guide, you‘ll learn common use cases for if, understand how it works under the hood, and master advanced if usage with best practices to avoid pitfalls.
How Nginx Configuration Works
Before jumping into if, let‘s do a quick recap of how Nginx configuration works:
- Configs are made up of directives – simple key-value pairs
- Directives are nested under contexts – main, events, http, server, location etc.
- The config is loaded on startup and parsed into a tree structure
When a request comes in, Nginx traverses this tree to find the best match based on IP, server name, URI etc. The directives in the matching context are then applied to handle that request.
When Does the if Directive Get Evaluated?
This brings us to a critical detail of if – it is evaluated only once at runtime during Nginx‘s startup.
The if condition is NOT re-evaluated on every request!
Knowing this is half the battle of using if properly. Many Nginx users assume if works like an "if statement" in a programming language. This assumption can lead to tricky bugs!
A Simple Example of if
Let‘s look at a basic example of using if to block visitors:
if ($remote_addr = "192.168.1.1") {
return 403;
}
This will return 403 forbidden if the client IP is 192.168.1.1.
But the if condition is only checked once at Nginx startup.
So if 192.168.1.1 visits later after restart, they won‘t be blocked!
Why if Behaves Differently Than You Might Expect
The reason if works this way is that Nginx configurations must be simple and fast.
Nginx serves over 35% of all websites, so it prioritizes high performance.
Evaluating complex if conditions on every request would be too slow. So Nginx compromises by only evaluating if once.
Common Uses Cases for if
Now that we understand when if gets evaluated, let‘s explore some common use cases.
1. Blocking Visitors by IP Address
A common example is blocking visitors by IP address, like our example above:
if ($remote_addr = "192.168.1.1") {
return 403;
}
However, there is a better way using Nginx map – we‘ll cover that soon.
2. Implementing Custom Error Pages
Another popular use of if is to show custom error pages:
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/errors;
}
location / {
if ($status = 500) {
return 500;
}
proxy_pass http://backend;
}
This custom error page approach works well since Nginx‘s $status variable is set properly on every request.
3. Feature Flags and A/B Testing
if can also be used for feature flagging and A/B testing:
if ($remote_addr ~ user-123){
set $show_new_checkout = 1;
}
...
if ($show_new_checkout = "1") {
proxy_pass http://new-checkout;
}
Here we enable the new checkout experience for specific users.
4. Blue-Green and Canary Deployments
Similar to the above, if helps with blue-green and canary deployments:
if ($remote_addr ~ office-ip) {
set $try_new_version = 1;
}
...
if ($try_new_version = "1") {
proxy_pass http://new-app-servers;
}
This sends office traffic to the new app servers as a canary test.
Alternatives to if for Conditional Logic
While if is very handy, you may want to reach for other tools too:
- Nginx
map– Excellent for large allow/deny lists and blocing IPs - Multiple
serverblocks – Allows conditions via server names - Lua/JavaScript scripting – For advanced conditional logic
- SSI
include– Similar toifbut more request-aware
Let‘s look at a couple of these in more detail…
Using map for Blocking Visitors
A better way to block visitors by IP is to use the Nginx map directive:
# Block IP map
map $remote_addr $block_ip {
default 0;
192.168.1.1 1;
192.168.1.2 1;
...
}
server {
if ($block_ip) {
return 403;
}
...
}
This keeps the block list separate from the if logic for easier maintenance.
The map block gets evaluated on every request, so it will block properly.
Using Multiple server Blocks
Multiple server blocks allow conditions based on server names or IPs:
server {
# Blocked ips
listen 192.168.1.1;
return 403;
}
server {
# Internal users
listen 192.168.50.0;
proxy_pass http://internal;
}
server {
# Everyone else
...
}
This is often clearer than a complex if statement.
Order of if Statements Matters!
Keep in mind the order of your if statements matters. Only the first match runs:
if ($remote_addr ~ office) {
set $mode "office";
}
if ($remote_addr ~ user123) {
set $mode "test";
}
# $mode will always be "office" for user123!
Be careful with if order and specificity. Use map instead when possible.
Common "Gotchas" Using if
While if is very useful, there are some common "gotchas" to be aware of:
- Variable scope limitations –
ifvariables aren‘t shared across contexts - Request timing issues –
ifruns at startup, not on each request! - Performance impacts – Regex checks in
ifhave a cost at runtime
Using if properly requires understanding how Nginx works under the hood.
Lua Conditionals Are More Flexible
For more complex conditions, Lua scripting can help:
location / {
content_by_lua_block {
if user_is_test(remote_addr) then
proxy_pass http://test_version;
else
proxy_pass http://main_version;
end
}
}
Lua conditionals are re-evaluated on every request. But Lua has a performance cost too.
Best Practices for Using if
Based on all we‘ve covered about if, here are some best practices:
- Start simple – Get basic
ifworking before extensive use - Validate often – Use
nginx -tto check for syntax issues - Monitor logs – Watch for weirdness after changes
- Limit regex – Avoid costly regex calls in
if - Consider alternatives –
mapandserverblocks may be better
And remember, if runs only once at Nginx startup!
Conclusion
The Nginx if directive lets you implement conditional logic based on variables like IP, headers, etc.
This unlocks very powerful use cases like access control, A/B testing, and canary deployments.
However, if behaves differently than you may expect – it does not re-evaluate on each request. Knowing this (and the alternatives) will help you become an Nginx expert!
We‘ve only scratched the surface of mastering Nginx here. For more tips and tutorials, check out our Nginx section. Let us know if you have any other topics you‘d like to see covered!


