An example. Assuming you have the domain “example.com” then you might have an app that handles user login and you spin that up on, say, port 30000 and you map it to port 80 such that is appears as:
You might also have an app that handles user signups which you spin up on port 30001 and you map to port 80 such that it appears as:
You might also have an admin app that you spin up on port 30002 and you map to
You might also have an app that allows users to update their profile information and you spin that up on port 30003 and map that to
http://www.example.com/profile
And you might have an app that publishes much of your content as static HTML files, which you spin up on no port, as it does not accept TCP/IP requests — instead it queries the database and then creates static html files, which you save to some directory such as /var/www/example.com/public_html/ and you map that to
You can see how this gives the sysadmins a lot of freedom to spread load across servers in creative ways — if 1 app becomes especially popular, or resource hungry, the sysadmins can rather easily move it to its own server (or set of servers). This is one of the main reasons most big sites move to an architecture like this — it facilitates fine grained control of what sort of requests go to a particular server.
This is a flexible style and it allows small, maintainable apps. By contrast, consider web development circa 2001, when many people felt it was enough to put a big blob of PHP in a directory and let Apache serve it as one big app.
Nginx's fast reverse proxy allows developers to focus on building their apps, without having to worry too much the server details. It also offers a cleaner separation between concerns that should worry programmers and concerns that should worry the sysadmins.
(A final point: in my own apps, for information that needs to be shared quickly across apps, like which users are logged in, I use ZeroMQ to knit the apps together.)