NGINX Words Explained: Worker, Server Block, Location, Upstream, proxy_pass, 502 vs 504

October 1, 2026 · How It Actually Works: Real Systems as State Machines (part 6)

▶ Watch on YouTube & subscribe to The Stack Underflow

Words like worker, location, upstream and proxy_pass label almost every box in the NGINX state-machine video. This primer explains each one first, with one running example: a browser asks for /books/42 on shop.example over HTTPS, and NGINX passes the request to one of two Java application servers.

The one-line version: the master manages, workers do the work; a server block is picked by address and port then Host, a location by path; proxy_pass sends the request to an upstream, and when that fails a timeout is 504 and almost everything else is 502.

Last verified against the nginx.org documentation: 1 October 2026. Scope: open-source nginx, stable branch 1.30 (1.30.5 at the time of checking). Every claim links to its source at the bottom of the page.

One picture: NGINX is an airport

Each request is a passenger. The pegs below are an analogy, memory aids, not technical claims; the table says where one breaks. The chain: the airport manager (master) hires the air-traffic controllers (workers); they guide each passenger to a terminal (server block), then a gate (location); there the transfer desk (proxy_pass) puts them on the connecting fleet (upstream).

What NGINX is and how it runs

WordMemory pegWhat it actually is
Web server vs reverse proxyThe shop vs the check-in deskA web server answers from its own files. A reverse proxy receives a request, passes it to another server, gets the response and sends it back. A load balancer is a reverse proxy spreading requests across several servers. (Unlike a real check-in desk, a proxy does carry the answer back.)
Master processThe airport managerReads and checks the configuration, opens the listening sockets, starts the workers, then waits for signals. It never handles a client connection.
Worker processesThe air-traffic controllersDo the actual processing of requests. worker_processes defaults to 1; auto tries to detect the number of CPU cores, which the docs call “a good start” when in doubt. Each worker is a whole process, not a thread per request.
Event loopAnswering radio callsEach worker asks the OS which connections are ready (epoll on Linux), runs their handlers, expires timers, and waits again. One worker serves up to worker_connections (default 512), a number that “includes all connections (e.g. connections with proxied servers, among others), not only connections with clients”. A blocking call stalls the whole worker.

The configuration file

WordMemory pegWhat it actually is
Directive, block, contextThe rulebookA simple directive is a name and parameters ending in ;. A block directive ends in braces. A block that can hold other directives is a context. Outside every block is the main context.
events, http, server, locationSections inside sections”The events and http directives reside in the main context, server in http, and location in server.”
includeSee appendixPulls another file, or every file matching a mask, into the configuration at that spot. Allowed in any context; the included text must be valid directives and blocks.

The running example as configuration:

upstream bookstore {
    server app1:8080;
    server app2:8080;
}

server {
    listen      443 ssl;
    server_name shop.example;
    # ssl_certificate / ssl_certificate_key ...

    location /books/ {
        proxy_pass http://bookstore;
    }
}

Which server block, which location

WordMemory pegWhat it actually is
server, listen, server_nameThe terminal and its signA server block is a virtual server. NGINX first tests the connection’s address and port against listen, then the Host header against server_name of the blocks that matched.
TLS termination and SNISecurity unseals the envelope; SNI is the name on the outsideNGINX does the TLS handshake with the certificate named in the server block. The handshake happens before any HTTP request, so the Host header isn’t known yet; SNI lets the browser send shop.example during the handshake so NGINX can pick the right certificate.
Default serverThe fallback terminalNo matching server_name, or no Host header: the request goes to the default server for that port, the first server block listening there unless default_server is set. “The default server is a property of the listen port and not of the server name.”
locationThe gateMatches the URI path without the query string (see the order below).
Phases and modulesStations and their staffEvery request passes eleven phases in a fixed order, from POST_READ to LOG. Modules register handlers in them: rewrite rules in the rewrite phases, allow/deny in ACCESS. FIND_CONFIG picks the location.

How a location is chosen (nginx 1.30)

  1. An = exact match ends the search.
  2. Otherwise the longest matching prefix is selected and remembered. If it has ^~, regexes are not checked.
  3. Otherwise regex locations (~, or ~* for case-insensitive) are tried in file order; the first match wins.
  4. If none matches, the remembered prefix is used.

So /books/42 lands in location /books/. (Current docs also describe “predicate locations”, added in mainline 1.31.5; they are not in stable 1.30, so the video leaves them out.)

Passing the request to your app

upstream and proxy_pass. Peg: the connecting fleet and the transfer desk. upstream defines a named group of servers; proxy_pass http://bookstore in the location sends requests there. Because it says http, the hop to Java is plain HTTP; TLS ended at NGINX.

Load balancing (peg: picking the next aircraft). Default: weighted round robin, weight 1. Alternatives: least_conn (fewest active connections), hash (a key you build), ip_hash (client address, so a client keeps reaching the same server), random (and random two).

Proxy timeouts (peg: how long the desk waits; the clock restarts with every reply):

DirectiveDefaultWhat it actually limits
proxy_connect_timeout60sEstablishing the connection to the upstream
proxy_send_timeout60sThe gap between two successive writes, “not for the transmission of the whole request”
proxy_read_timeout60sThe gap between two successive reads, “not for the transmission of the whole response”

So a slow response that keeps sending data doesn’t hit proxy_read_timeout.

proxy_next_upstream (peg: rebooking on the next aircraft). Default error timeout: a connection error or timeout while connecting, sending, or reading the response header moves the attempt to the next server, but only “if nothing has been sent to a client yet.” A POST, LOCK or PATCH that already reached a server isn’t retried unless you add non_idempotent.

max_fails and fail_timeout (peg: out of rotation for a while). Open-source NGINX learns about failing servers only from real requests (a passive check). By default one failed attempt within 10 seconds marks a server unavailable for 10 seconds. Active, scheduled health checks are a commercial feature.

502 vs 504 (peg: 504 is no answer in time; 502 is refused or garbled, or no aircraft left). When no server gives a usable response, the error is made by NGINX, not your app. In the nginx 1.30 source, a timeout becomes 504 Gateway Timeout; a refused connection, an invalid response header, or no live servers left becomes 502 Bad Gateway.

Changing the configuration safely

  • nginx -t (peg: checking the new rulebook): checks syntax, then tries to open the files the configuration refers to. Edits do nothing until a reload or restart.
  • Reload, HUP (peg: the controllers hand over): nginx -s reload sends HUP to the master. It checks the new configuration and tries to apply it (open log files and listen sockets). On failure it rolls back and keeps the old one. On success it starts new workers and asks the old ones to shut down gracefully: they stop accepting, finish current requests, then exit. A reload is not a restart.
  • QUIT vs TERM (peg: finish and leave vs close at once): nginx -s quit (QUIT) is graceful; nginx -s stop (TERM) and INT are fast.

Pause & Prove

1. A request arrives on port 443 with a Host header that matches no server_name. Which server block handles it?

  • None: NGINX rejects it. No: an unmatched Host still gets a server block.
  • The server block whose name is closest. There is no fuzzy matching on names.
  • The default server for that address and port. ✓ The first server block listening there, unless one has default_server on its listen. It’s a property of the listening port, not of a name.
  • The last server block in the file. Order matters, but it’s the first one, by default.

2. NGINX can’t connect to your app: the connection is refused. Which status does the browser get? (Community poll)

  • 500. That’s an internal error; a refused upstream connection isn’t one.
  • 502. ✓ A refused connection, an invalid response header, or no live servers left becomes 502 Bad Gateway.
  • 503. Not from a refused connection in this mapping.
  • 504. Only a timeout becomes 504.

3. Peg drill

Say the peg for each: master, location, 502. Answers: the airport manager; the gate; refused or garbled (or no aircraft left). Bonus: 504 is no answer in time.

Before / after this video

Sources

Checked on 1 October 2026, plus the video’s own verified sources:

Change notes

  • 1 Oct 2026: first published.

Not affiliated with or endorsed by F5 or the nginx project. NGINX is a trademark of F5, Inc. Found a mistake? Tell us in the video’s comments and we’ll correct this page.

Found this useful? The deep version lives on YouTube — new breakdowns of how AI dev tools actually work, weekly.

Subscribe on YouTube →

Prefer email? Get the free newsletter: one failure, traced step by step, about once a week.