What is Nginx?
Nginx (pronounced “engine-x”) is one of the most popular web servers in the world. A web server is a program that listens for requests from browsers and sends back web pages, images, and data. Nginx is famous for being fast, lightweight, and able to handle a huge number of users at the same time without slowing down. In this page you’ll learn what Nginx actually does, the three jobs it’s best at, and why its design lets it scale so well — so the install and config pages later make sense.
What is Nginx, in plain English?
Nginx is a piece of software you install on a Linux server. Once it’s running, it sits and waits for incoming connections on a network port (a numbered “door” on your server — port 80 for plain HTTP, port 443 for secure HTTPS). When a request arrives, Nginx decides what to do with it: send back a file, hand it off to your application, or pass it along to another server.
It was created in 2004 by Igor Sysoev to solve the “C10k problem” — the challenge of handling 10,000 connections on one machine at the same time. Old web servers struggled with that. Nginx was built from day one to handle it gracefully, and that design choice is still why people pick it today.
Nginx is free and open source. There’s also a paid version called Nginx Plus with extra features, but for almost everything you’ll do as a beginner or intermediate engineer, the free open-source build (the one you get from Ubuntu’s
apt) is all you need.
The three main roles of Nginx
Most people use Nginx for one or more of these three jobs. Understanding them is the key to everything else.
1. Static web server
A static file is a file that never changes per request — an HTML page, a CSS stylesheet, a JavaScript file, an image, or a PDF. Serving static files is the simplest job: a browser asks for /index.html, and Nginx reads that file from disk and sends it back.
When to use this: hosting a plain HTML site, a single-page app build (React, Angular, Vue), documentation, or downloads. Nginx is extremely good at this — it can serve thousands of static files per second.
2. Reverse proxy
A reverse proxy is a server that sits in front of your application and forwards requests to it, then sends the application’s reply back to the browser. Your app (a Node.js, Python, or Java program) runs quietly on an internal port like 3000, and Nginx on port 80/443 is the public face that talks to the outside world.
When to use this: running any dynamic application. You almost never expose a Node.js or Django app directly to the internet — you put Nginx in front for HTTPS, security, and stability. When NOT to: if you’re only serving static files, you don’t need the proxy part at all.
3. Load balancer
A load balancer spreads incoming requests across several copies (instances) of your application so no single one gets overwhelmed. If one instance crashes, Nginx routes traffic to the healthy ones.
When to use this: when one server can’t handle your traffic, or when you want zero-downtime deploys and redundancy. When NOT to: a small site with one app instance doesn’t need it yet — add it when you actually scale out.
| Role | What it does | Typical use case |
|---|---|---|
| Static server | Sends files straight from disk | Marketing site, SPA build, docs |
| Reverse proxy | Forwards requests to your app | Node/Django/Java backend behind HTTPS |
| Load balancer | Splits traffic across many app instances | High-traffic apps, redundancy |
Why Nginx scales so well: the event-driven architecture
This is the part most tutorials skip, and it’s the reason Nginx is so fast.
Older servers (like classic Apache with its default setup) used a process-per-connection or thread-per-connection model: every visitor got their own process or thread. A thread is a unit of work the operating system schedules; each one uses memory and CPU. With 10,000 visitors, you’d need 10,000 threads, and the server would run out of memory just managing them.
Nginx uses an event-driven, asynchronous model instead. It runs a small fixed number of worker processes — usually one per CPU core. Each worker can juggle thousands of connections at once using a non-blocking event loop. “Non-blocking” means a worker never sits idle waiting for one slow client; while it waits for data from one connection, it handles others. This is why a tiny server can serve enormous traffic with very little memory.
Think of it like a waiter. The old model hires one waiter per table (expensive, and most stand around waiting). Nginx is one skilled waiter who takes an order, moves to the next table while the kitchen cooks, and comes back exactly when each dish is ready — serving far more tables with far fewer staff.
A first look at where Nginx lives on Ubuntu
When you install Nginx on Ubuntu (covered fully on the install page), it lands in predictable places. Knowing these now will help everything click later:
| Path | What it holds |
|---|---|
/etc/nginx/nginx.conf | The main configuration file |
/etc/nginx/sites-available/ | Your site config files (one per site) |
/etc/nginx/sites-enabled/ | Symlinks to the sites that are actually active |
/var/www/html/ | The default folder for static files |
/var/log/nginx/ | Access and error log files |
You manage the running service with systemctl, the standard Ubuntu tool for controlling background services:
sudo systemctl status nginx
Output:
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running) since Mon 2026-06-15 09:12:04 UTC; 3min ago
Docs: man:nginx(8)
Main PID: 1432 (nginx)
Tasks: 5 (limit: 4915)
Memory: 6.1M
CPU: 41ms
Notice the tiny memory footprint — about 6 MB to serve a website. That’s the event-driven design paying off.
Security gotcha: A fresh Ubuntu server usually has the
ufwfirewall. After installing Nginx you must open the web ports or no one can reach it:sudo ufw allow 'Nginx Full'(which opens both port 80 and 443). Forgetting this is the number-one “why can’t I see my site?” mistake.
Nginx vs Apache, at a glance
Apache is the other giant in this space. You’ll compare them in detail on a dedicated page, but here’s the quick mental model:
| Nginx | Apache | |
|---|---|---|
| Architecture | Event-driven (async) | Process/thread per connection |
| Static files | Extremely fast | Fast, slightly heavier |
| Per-directory config | No .htaccess | Supports .htaccess |
| Best at | Reverse proxy, high concurrency | Flexible module ecosystem, shared hosting |
A common real-world setup even uses both — Apache running the app and Nginx in front as a fast proxy.
Best Practices
- Run Nginx as a reverse proxy in front of any dynamic app — never expose Node, Python, or Java apps to the internet directly.
- Keep each site in its own file under
/etc/nginx/sites-available/and enable it with a symlink intosites-enabled/— it keeps configs clean and easy to disable. - Always run
sudo nginx -tto test your config before reloading, so a typo never takes your site down. - Reload (don’t restart) after config changes with
sudo systemctl reload nginx— it applies changes with zero dropped connections. - Open only the ports you need in
ufw(80 and 443) and keep everything else closed. - Watch
/var/log/nginx/error.logfirst whenever something breaks — it almost always tells you exactly what’s wrong.