Skip to content

How to use NGINX Variables + Reference List

Config variables are a powerful tool to control how NGINX routes requests. HTTP request, header and env variables give us precise control on how requests are routed. Let’s dig in!


Using NGINX Config Variables

Configuration variables are typically used in the server block of the NGINX config file. We can use if statements and variables to control how a request is routed within NGINX. Here’s a simple example of what we’re talking about:

					server {
    listen 80;
    # check host
    if ($host = {
        # remove www by redirecting
        return 301$request_uri;
    # send request to backend
    location / {
        proxy_pass http://backend;

In the example above, we check the host variable (a built-in NGINX variable) and route the request either to a redirect or to our backend. This is just a simple example. We can build incredibly complex algorithms with these simple building blocks.

Let’s walk through the variables available to us.

Request Variables

NGINX provides access to almost every aspect of the HTTP request as variables that we can use in our routing logic.
Variable Description Example
$remote_addr The http client’s public ip
$request_length Tells us how long the the request is. This includes the headers and request body. 2930 (bytes)
$content_length Similar to $request_length, but only has the length of the request body 2000 (bytes)
$request_method The type of HTTP request received (GET/POST/PUT/DELETE) GET

Here’s an example of request-based request routing:

					server {
    location / {
        proxy_pass http://backend/$request_method$request_uri
        proxy_set_header X-RemoteIP $request_addr;

In this example we’re re-writing the request path and setting a header before sending the request to our backend.

The proxy_pass line is pre-appending the request method to the request. This could be useful if your backend didn’t have access to the HTTP method, or wanted to use path-only based routing. (e.g. /post/companies, /get/companies)

The proxy_set_header line is adding an HTTP header with the client’s IP address. This way the backend can still access the client’s IP address even though it’s behind a load balancer. (You could also use the X-ForwardedFor header here, there’s a great write up on the NGINX blog about that)

Ready to get the whole story on your uptime?
Status List delivers uptime checks with technical diagnostics in a one dashboard. A pass/fail isn’t the whole story.
Join over 2,000 companies and try it for free today.

HTTP Header Variables

Predefined NGINX variables allow us to access the HTTP header values as well. 

Variable Description Example
$content_type The Content-Type http header application/json
$http_user_agent The http client’s user agent (User-Agent Header) Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ Safari/537.36
$cookie_{name} The value of the HTTP cookie with the given name (e.g. $cookie_auth) cookie-value
$http_{name} The HTTP header at {name} (e.g. Authorization) Bearer 31d728c8-7141-42d1-a07d-77e26fac400b

Here’s an example of header-based routing:

					server {
    if ($http_user_agent ~ Bot) {
        return 403 "Bots are forbidden";
    if ($http_authorization = "") {
        return 403 "Missing bearer token";
    location / {
        proxy_pass http://backend$uri?$query_string&auth=$http_authorization

In this example, we’re blocking out bad requests and moving the Authorization header into the query string. The Bot check and missing Authorization HTTP header will simply block the request with a 403 response. Requests that meet our requirements will be forward on. In the requests that we forward, we extract the Authorization header and append it to the query string. This can be useful if your backend doesn’t want to touch HTTP Headers, but is able to access the query string.

Location Variables

Location variables allow us to access URI properties. This is really useful for path and query-based routing and redirecting. Here are a few commonly used built-in variables.

Variable Name Description Example
$request_uri The full requested path with query string //contact?ref=gas
$uri A normalized version of $request_uri. (e.g. double slashes converted to single slash) This value will change during redirects or rewriting. /contact
$scheme The request scheme (http/https) https
$query_string (aka $args) The query portion of the URL (without the leading ?) search=hello&user=3920
$arg_{name} The value of a specific query field (e.g. $arg_search) hello
$host The value of the Host header
$hostname Similar to $host, but doesn’t include the port number

Here’s an example of location based routing:

					server {
    if ($arg_search != "") {
        rewrite ^(.*)$ /search/$arg_search break;
    if ($uri = /contact) {
        return 301 /new-contact-page;

In this example we’re re-routing searches and the contact page. If any query contains the search field, we rewrite the URI to use the /search endpoint. In the second part, we’re creating a static redirect for the /contact page. 

Upstream Variables

We can also access variables based on the upstream response. Here is a table of commonly used upstream variables:
$upstream_response_time Measures how long the backend took to process the request 3.293 (seconds)
$upstream_queue_time Measures how long this request waited in the queue before being processed by the backend 1.203 (seconds)
$upstream_status The HTTP status code returned by the backend 200
$upstream_addr The backend address used for this request

Here’s an example of how we might use upstream variables:

					server {
    location / {
        proxy_pass http://backend;
        add_header X-BackendTime $upstream_response_time;
        add_header X-BackendUsed $upstream_addr;

In this example, we’re adding some diagnostic metrics to our HTTP response header. We add the backend used and how long it took for that backend to process the request. This type of information can be really helpful in tracking down production issues.

Map Variables

Maps are a great way to deal with lookup tables. For example, if we have a set of redirects we’d like to make, we can use a map. NGINX will evaluate the lookup in the background and we can access it as a single variable. Here’s an example

					# redirection table
map $uri $redirected_uri {
    / /index.html
    /cntact /contact
    /pricing /contact-sales
server {
    if ($redirected_uri) {
        rewrite ^ $redirected_uri;

Environment Variables

Environment variables are really helpful when we need to spin up multiple NGINX instances. We can use variables to inject host names, domain names and backend information into our configuration. Unfortunately NGINX doesn’t support environment variables on it’s own. But, we can get around that problem with templating.

Templating is where we create an NGINX configuration file, but use bash variables to inject our environment variables. Here’s an example:

					cat /etc/nginx/nginx.template.conf
http {
    server {
        server_name ${DOMAIN}
        listen ${PORT};
        location / {
            proxy_pass http://${BACKEND};

We can take that template and run it through something like envsubstr to generate our actual configuration. 

					envsubstr < /etc/nginx/nginx.template.conf > /etc/nginx/nginx.conf

Our nginx.conf will now contain our “rendered” configuration.

Set Variables

We can also create user-defined variables using the set directive. This can be useful for extracting request details and reconstructing the request. You can use the set directive similar to how we use the rewrite/return directives. Here’s an example:

					server {
    set $uid 0;
    if ($uri ~ "^/([0-9]+)/") {
        set $uid $1;
    location / {
        proxy_pass http://backend;
        proxy_set_header X-UserId $uid;

In this example, we extract the user’s id for the backend. First we check if the URI has the format that contains a UID. Then we extract that UID and add it to the X-UserId header. That X-UserId header is then passed to the backend.

Full Variable Reference

You can find the full NGINX variable reference here.

More Reading