Small startup
Nginx in front of two app servers and one PostgreSQL. The app tier scales; the database becomes the bottleneck.
What this architecture teaches
Two app servers behind Nginx can handle far more traffic than one, so the obvious bottleneck moves — straight to the database, which everything still shares.
PostgreSQL runs only a handful of queries at once and accepts 100 connections by default. When queries arrive faster than it completes them, waiting queries hold connections until the limit is reached and new clients are refused with “sorry, too many clients already”.
Ways out: cache reads, add read replicas, put a connection pooler such as PgBouncer in front, or use a bigger instance.
What to look for
- Both servers stay healthy
- PostgreSQL’s queue grows past its 250 queries/s capacity
- “too many clients already” once 100 connections are used
Components
- Web users — Web browser (Traffic source)
Nginx — Nginx (Load balancer)
app-1 — Node.js (Server)
app-2 — Node.js (Server)
PostgreSQL — PostgreSQL (Relational DB)