Short answer: nginx (pronounced “engine-x”) is free, open source software that serves websites and sits in front of applications. One program works as a web server, reverse proxy, load balancer and HTTP cache. Igor Sysoev released it publicly in 2004 to handle many thousands of simultaneous connections with little memory, which its event-driven design still does.
The project’s home page at nginx.org (read on 21 October 2026) calls it “an HTTP web server, reverse proxy, content cache, load balancer, TCP/UDP proxy server, and mail proxy server”. In practice that means it is the first program a request meets on a large share of the web’s servers: it answers static files itself and passes everything else on to the application behind it. This guide covers what nginx is used for, how its architecture differs from Apache, the open source and commercial editions, how its configuration is laid out on Debian and Ubuntu, and how to install it.
What does nginx mean, and how do you say it?
The name is a play on “engine x”, and that is how it is pronounced: “engine-ex”, not “n-jinx”. The open source project writes it in lower case, nginx; F5, the company that has owned the commercial side since 2019, writes NGINX in its product names. Both refer to the same core software.
What is nginx used for?
- Web server. Serving HTML, CSS, JavaScript, images and downloads straight from disk, fast and with little memory per connection.
- Reverse proxy. Accepting requests from the internet and passing them to an application server (Node.js, Python, PHP-FPM, Java) that listens only locally. What is a reverse proxy explains the pattern, and web server vs application server shows where each half of the work belongs.
- TLS termination. Holding the HTTPS certificate and decrypting traffic, so the application behind it speaks plain HTTP on localhost.
- Load balancer. Spreading requests over several backends with an
upstreamblock: round robin by default, orleast_conn,ip_hash,hashandrandom. - HTTP cache. Storing backend responses on disk with
proxy_cacheand answering repeat requests without asking the application. - Rate limiting and access control. Capping requests per client IP with
limit_req, or restricting paths by address or password. - TCP and UDP proxy. The
streammodule forwards non-HTTP traffic, such as a database port or a game server, with load balancing.
A reverse proxy with load balancing, for example, takes a dozen lines:
upstream app {
least_conn;
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://app;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}How does nginx work? The event-driven design
nginx runs as one master process and a few worker processes. The master reads the configuration, opens the listening ports and starts the workers; it handles no traffic itself. Each worker runs a single event loop: it asks the kernel (through epoll on Linux, kqueue on the BSDs) which of its thousands of open connections have data ready, does a little work on each, and moves on without ever waiting on one client. The usual setting, worker_processes auto, starts one worker per available CPU, which on a machine with SMT means one per logical CPU.
$ ps -o pid,user,cmd -C nginx
PID USER CMD
812 root nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
813 www-data nginx: worker process
814 www-data nginx: worker processThat design is why nginx keeps memory flat when many slow clients hold keep-alive connections open: an idle connection costs a small structure in a worker, not a whole process or thread. It also explains how a reload works without dropping traffic. The master starts new workers with the new configuration and tells the old ones to finish their current requests and exit; restarting or reloading nginx walks through that and when a full restart is needed instead.
The trade-off: a worker must never block. Slow disk reads can stall it, which nginx mitigates with thread pools for file I/O, and anything that runs application code (PHP, Python) has to live in a separate process that nginx talks to over FastCGI or HTTP.
nginx vs Apache
Apache httpd is the older web server (first released in 1995) and handles concurrency through interchangeable multi-processing modules (MPMs): prefork runs one process per connection, worker one thread per connection, and event hands idle keep-alive connections to a listener thread so workers stay free. Modern Apache with the event MPM narrows the gap, but the two still differ in ways that matter day to day:
| nginx | Apache httpd | |
|---|---|---|
| Concurrency model | A few event-driven workers, each holding thousands of connections | MPM of your choice: prefork (process per connection), worker (threads) or event |
| Per-directory config | None: no .htaccess, every change goes into the main config and needs a reload | .htaccess files, read on every request where AllowOverride permits |
| Running PHP | Through PHP-FPM over FastCGI only | mod_php inside Apache, or PHP-FPM |
| Static files under load | Very efficient, low memory per connection | Good with the event MPM; heavier with prefork |
| Modules | Compiled in or loaded as dynamic modules (since 1.9.11) | Large module ecosystem, loaded at runtime |
| Licence | 2-clause BSD | Apache License 2.0 |
| Typical role today | Front door: web server, reverse proxy, TLS, cache | Application-heavy shared hosting and setups that rely on .htaccess |
One Debian detail shows the difference in practice: installing libapache2-mod-php switches Apache from the event MPM to prefork, because mod_php is not thread-safe. Many hosts therefore run both servers together: nginx in front for TLS, static files and caching, Apache behind it for the PHP sites whose .htaccess rules nobody wants to translate.
Open source nginx vs NGINX Plus
The open source nginx from nginx.org is free under a 2-clause BSD licence and comes in two branches: mainline (odd minor version numbers, new features first) and stable (even minor numbers, bug fixes only). Distribution packages usually ship a stable release and backport security fixes, so Debian 12 still reports 1.22.1 years after release. Run nginx -v to see what you have, and check the nginx.org download page for the current branches rather than trusting a version number in any article.
NGINX Plus is F5’s paid subscription built on the same core. It adds features aimed at large deployments, such as active health checks, a live monitoring dashboard and API, extra session-persistence and load-balancing methods, JWT authentication and commercial support. For a website, an API or a handful of applications on one server, the open source edition is what nearly everyone runs.
How is nginx configured?
Everything lives in plain-text files made of directives (listen 80;) grouped into contexts (blocks in braces). The main file is /etc/nginx/nginx.conf; inside its http context, each server block is one site (what Apache calls a virtual host), and location blocks inside it decide how individual paths are handled.
| Path | What it holds |
|---|---|
/etc/nginx/nginx.conf | Global settings: user, worker processes, the events and http contexts, and the include lines for everything below |
/etc/nginx/sites-available/ | One file per site. The package ships a file named default |
/etc/nginx/sites-enabled/ | Symlinks to the sites that are switched on; only these are loaded |
/etc/nginx/conf.d/ | Extra *.conf files included into the http context |
/etc/nginx/snippets/ | Reusable fragments, such as fastcgi-php.conf for PHP-FPM |
/etc/nginx/modules-enabled/ | Dynamic modules loaded at start |
/var/log/nginx/ | access.log and error.log |
/var/www/html | The default site's document root |
The default site in Debian 12’s package (1.22.1, read from the packaged file with comments removed) is a complete minimal server block:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}How to install nginx on Ubuntu or Debian
- 1Install the package
Ubuntu · Debian sudo apt update sudo apt install -y nginxThe service starts and is enabled at boot straight away. Check it with
systemctl status nginx. - 2Open the firewall
Ubuntu · Debian with ufw sudo ufw allow 'Nginx Full' # ports 80 and 443 sudo ufw statusThe package ships ufw profiles named
Nginx HTTP,Nginx HTTPSandNginx Full. Make sure SSH is allowed before you enable ufw for the first time; setting up ufw has the order. - 3Check that it answers
any Linux curl -I http://localhostA
HTTP/1.1 200 OKwith aServerheader that starts withnginx(by default it carries the version, such asnginx/1.22.1on Debian 12, unlessserver_tokens off;is set) means the default site is up. Opening the server’s IP address in a browser shows the “Welcome to nginx” page. - 4Add your own site
Ubuntu · Debian sudo mkdir -p /var/www/example.com sudo nano /etc/nginx/sites-available/example.com # a server block like the one above sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginxSet
server_nameto your domain androotto the new directory, and point the domain’s DNS at the server. For HTTPS and proxying an app, nginx reverse proxy with SSL continues from here with certbot.
Basic nginx commands
| Task | Command |
|---|---|
| Test the configuration | sudo nginx -t |
| Test and print the full merged configuration | sudo nginx -T |
| Apply config changes without dropping connections | sudo systemctl reload nginx |
| Full restart | sudo systemctl restart nginx |
| Show the version | nginx -v |
| Version plus build options and modules | nginx -V |
| Service log | journalctl -u nginx |
| Watch the error log | sudo tail -f /var/log/nginx/error.log |
Make nginx -t a habit before every reload: it catches a missing semicolon before it can take a site down. The systemd unit on Debian and Ubuntu runs the same test before it starts nginx, so a broken file shows up as a failed start rather than a half-running server.
Errors you will meet first
- 502 Bad Gateway: nginx is fine, the application behind it is not answering. Fixing nginx 502 Bad Gateway goes through the causes in order.
- 504 Gateway Timeout: the backend answered too slowly; see nginx 504 Gateway Timeout.
- 403 Forbidden: usually file permissions or a missing index file; see nginx 403 Forbidden.
- 413 Request Entity Too Large: an upload above
client_max_body_size, which defaults to 1 MB; see 413 Request Entity Too Large. - bind() to 0.0.0.0:80 failed (98: Address already in use): another program, often Apache, already holds port 80; Address already in use shows how to find it.
Running nginx on your own server
Installing and configuring nginx yourself needs root access, both for the package and to bind ports 80 and 443, so it is a job for a VPS or dedicated server; on shared hosting the provider decides which web server runs. nginx is light enough for the smallest plan: a static site or a reverse proxy in front of one app uses a few megabytes of RAM. Any Linux VPS with Ubuntu or Debian takes the steps above as they are.
Frequently asked
What is nginx used for?
Serving websites and sitting in front of applications: as a web server for static files, a reverse proxy that passes requests to Node.js, Python or PHP-FPM, a load balancer across several backends, a TLS terminator and an HTTP cache. Its stream module also proxies plain TCP and UDP traffic.
How do you pronounce nginx?
Engine-ex. The name comes from 'engine x'. The open source project writes it in lower case as nginx, and F5 writes NGINX in its commercial product names.
Is nginx better than Apache?
For static files and as a reverse proxy in front of applications, nginx usually needs less memory when there are many connections, because of its event-driven workers. Apache is more convenient where sites rely on .htaccess files or mod_php. Many servers run both: nginx in front, Apache behind it.
Is nginx free?
Yes. The open source nginx from nginx.org is free under a 2-clause BSD licence, and it is the version Debian, Ubuntu and most other distributions package. NGINX Plus is F5's paid subscription on the same core, with extra features for large deployments and commercial support.