The PostgreSQL database: a complete overview, pros, cons and limits
What PostgreSQL is used for, where it is the best choice and where another database wins: pros and cons, a comparison with MySQL, SQLite, MongoDB and ClickHouse, extensions, SQL examples, limits and tips.
In short
PostgreSQL is a free open-source relational database with a strict approach to data: transactions, constraints and one of the most complete SQL implementations. On top of classic tables it stores JSON with indexes, geodata (PostGIS), vectors for AI search (pgvector) and time series (TimescaleDB), so one database often covers what used to take three. It is the default choice for web service and SaaS backends, online shops and finance. Its weak spots: every connection is a separate process (you need a connection pooler), updates leave old row versions that VACUUM has to clean up, and analytics over billions of rows and horizontal write scaling are better served by other systems.
PostgreSQL at a glance
The main facts in one table — where the database came from, how it keeps data consistent and how it evolves.
- Type
- Object-relational database with open source code
- History
- The POSTGRES project at UC Berkeley under Michael Stonebraker from 1986; SQL from 1995; the name PostgreSQL since 1996
- Developed by
- PostgreSQL Global Development Group — a community; no company owns the project
- License
- PostgreSQL License — free, including commercial use
- Transactions
- ACID and MVCC: reads do not block writes
- SQL
- One of the most complete implementations: CTEs, window functions,
MERGE, SQL/JSON - JSON
jsonbsince 2014: binary JSON with indexes- Indexes
- B-tree, Hash, GIN, GiST, SP-GiST, BRIN; partial and expression indexes
- Extensions
- PostGIS, pgvector, TimescaleDB, Citus and hundreds more
- Replication
- Streaming since 2010, logical since 2017
- Releases
- A major version once a year, supported for five years; fixes at least quarterly
- Popularity
- The most used database among developers in the Stack Overflow survey since 2023
What PostgreSQL is used for: 8 areas
The core is classic transactional data, but extensions have turned PostgreSQL into a platform. Under each area — the tools and extensions it runs on.
-
01
Web service and SaaS backends
Users, subscriptions, orders and permissions: data with strict links between tables. Every popular framework supports it.
-
02
Online shops and payments
Transactions guarantee that money and stock never go out of sync — either the whole operation is saved, or none of it.
-
03
Geodata and maps
“Nearest shops”, delivery zones, routes: PostGIS is the standard for spatial data.
-
04
Site search
Full-text search with word forms and ranking, plus typo-tolerant matching — without a separate search engine.
-
05
Vector search and AI
Embeddings next to the data they describe: semantic search and RAG in the same database as the products and users.
-
06
Time series and metrics
Sensor readings, events, prices: partitioning by time and compression for years of history.
-
07
Documents and JSON
Flexible attributes, settings and third-party responses in
jsonb— with indexes, right next to strict columns. -
08
Job queues
Background jobs, emails and webhooks without a separate broker: workers pick up tasks without getting in each other’s way.
Pros and cons of PostgreSQL
PostgreSQL puts data correctness first. Most of its strengths come from that — and most of the tuning it needs, too.
Pros · 8
-
Reliable transactions
ACID, a write-ahead log and point-in-time recovery: after a crash the database comes back consistent.
-
Rich SQL
CTEs, window functions,
LATERAL, upsert andMERGE: reports and complex logic are written in the database instead of loops in code. -
JSON with indexes
jsonbgives document flexibility without giving up transactions, joins and constraints. -
Extensions
PostGIS, pgvector, TimescaleDB, pg_cron: new capabilities plug into the same database and the same SQL.
-
An index for every case
Partial and expression indexes, GIN for JSON and text, BRIN for huge time-ordered tables.
-
Strict data
Types, foreign keys,
CHECKandUNIQUEconstraints stop bad data at the door — not in a report a month later. -
No vendor lock-in
A free license and a community instead of an owner company: no licence fees and no risk that the product is closed.
-
Managed everywhere
AWS, Google Cloud, Azure, Supabase, Neon and many local providers offer it as a service with backups and replicas out of the box.
Cons · 8
-
A process per connection
Each connection costs memory, and the default limit is 100. Hundreds of web processes need a pooler such as PgBouncer.
-
VACUUM and bloat
An update writes a new version of the row; the old one is cleaned up by autovacuum. If it falls behind, tables and indexes swell.
-
Write scaling
Reads scale with replicas, but all writes go to one primary server. Sharding means Citus or your own logic.
-
Modest defaults
Out of the box it is tuned for a small machine:
shared_buffers,work_memand autovacuum must be set for real load. -
Major upgrades take planning
Minor updates are simple, but a major version needs
pg_upgradeor logical replication, and every extension must support it. -
Row storage for analytics
Scanning billions of rows for a few columns is slow — columnar databases like ClickHouse are built for that.
-
Expensive frequent updates
Because of row versions, a table where the same rows change thousands of times a second creates a lot of writes and cleanup work.
-
Needs an administrator’s eye
Backups, monitoring, slow queries and disk growth need regular attention — or a managed service that does it for you.
PostgreSQL compared with MySQL, SQLite, MongoDB and ClickHouse
A qualitative comparison with the databases PostgreSQL is most often weighed against. Exact figures depend on the data and the queries, so the table shows relative positions rather than benchmarks.
| Criterion | PostgreSQL | MySQL | SQLite | MongoDB | ClickHouse |
|---|---|---|---|---|---|
| Data model | tables plus JSON, geodata, vectors | tables | tables in one file | documents | columnar tables |
| Transactions | full ACID | ACID with InnoDB | ACID, one writer at a time | multi-document since 4.0 | limited |
| Query language | the richest SQL | SQL, fewer features | SQL | its own query language | SQL dialect for analytics |
| JSON | jsonb with GIN indexes | JSON type, indexes on expressions | JSON functions | native | JSON type |
| Scaling | read replicas; sharding via Citus | replicas, mature tooling | one machine | built-in sharding | clusters with shards |
| Analytics on billions of rows | slow without extensions | slow | not for this | medium | best |
| Operations | server, needs tuning and a pooler | server, easy to start | no server at all | server or cluster | server or cluster |
| License | PostgreSQL License, free | GPL, owned by Oracle | public domain | SSPL, not open source | Apache 2.0 |
| Best at | web services, SaaS, money, mixed data | classic websites and CMS | apps, prototypes, small sites | documents with a changing shape | events, logs, analytics |
When to choose PostgreSQL — and when not to
Thirteen typical tasks with a verdict. Where PostgreSQL is not the best choice, the alternative is named.
-
Web service or SaaS backend
Best fitThe default choice: strict data, transactions and every framework supports it.
-
Online shop, payments, accounting
Best fitTransactions and constraints keep money and stock consistent.
-
Geodata and maps
Best fitPostGIS is the industry standard for spatial queries.
-
Tables plus flexible JSON
Best fitjsonb with indexes removes the need for a separate document database.
-
Vector search for RAG
Best fitpgvector handles millions of vectors next to the data they describe.
-
Site search
WorksBuilt-in full-text search is enough for most sites; for complex relevance use Elasticsearch or Meilisearch.
-
Job queue
WorksSKIP LOCKED is fine up to thousands of jobs per second; beyond that — RabbitMQ, NATS or Kafka.
-
Time series
WorksWith TimescaleDB — yes; at huge ingest rates look at ClickHouse.
-
A simple content site
WorksWorks, but a CMS on MySQL or SQLite is simpler to run.
-
Analytics on billions of events
Pick anotherClickHouse: columnar storage is many times faster here.
-
Cache and sessions
Pick anotherRedis or Valkey: data in memory, microsecond access.
-
A database inside an app or device
Pick anotherSQLite: one file, no server.
-
Storing files and images
Pick anotherObject storage like S3; keep only the link and metadata in the database.
The PostgreSQL ecosystem: tools for common tasks
Much is built in, the rest comes as extensions and separate tools. The middle column is what ships with PostgreSQL itself.
| Task | Built in | Extensions and tools |
|---|---|---|
| Connection pooling | — | PgBouncer, PgCat |
| Backups | pg_dump, pg_basebackup | pgBackRest, Barman, WAL-G |
| High availability | streaming replication | Patroni, CloudNativePG |
| Query statistics | pg_stat_statements | pgBadger, postgres_exporter |
| Query plans | EXPLAIN ANALYZE, auto_explain | explain.dalibo.com |
| Geodata | — | PostGIS |
| Vectors | — | pgvector |
| Time series | partitioning | TimescaleDB |
| Sharding | partitioning, postgres_fdw | Citus |
| Full-text search | tsvector, pg_trgm | ParadeDB |
| Scheduled jobs | — | pg_cron |
| Queues | SKIP LOCKED, LISTEN/NOTIFY | pgmq, River, Graphile Worker |
| Schema migrations | — | Flyway, Liquibase, Atlas, goose |
| Administration | psql | pgAdmin, DBeaver, DataGrip |
The limits of PostgreSQL: where it hits the ceiling
-
Thousands of direct connections
If the web server can open more processes than the database accepts connections, a traffic peak takes down every site on it at once. A pooler in front of the database solves this.
-
Hot rows updated constantly
Counters, balances and statuses changed thousands of times a second generate dead row versions faster than autovacuum clears them. Batch the updates or move counters to Redis.
-
Analytics over billions of rows
Row storage reads whole rows for every scan. For event and log analytics a columnar database is an order of magnitude faster.
-
One server for all writes
When one primary can no longer absorb the writes, the next step is sharding with Citus or splitting data by service — a serious project.
-
Files inside the database
A field holds up to 1 GB, but images and documents in tables bloat backups and replicas. Keep files in object storage.
-
Schema changes on large tables
Some
ALTER TABLEoperations lock the table or rewrite it completely. On tables with hundreds of millions of rows migrations need a plan and a lock timeout.
8 tips for working with PostgreSQL without the bruises
-
01
A pooler from day one
PgBouncer in transaction mode lets hundreds of web processes share a few dozen real connections.
-
02
Turn on pg_stat_statements
It shows which queries eat the most time in total — that is where to start optimising, not with guesses.
-
03
EXPLAIN before an index
EXPLAIN (ANALYZE, BUFFERS)shows the real plan and where the time goes. An index added blindly may never be used. -
04
Indexes for queries, not just in case
Every index slows down writes and takes disk. Remove unused ones — the statistics show them.
-
05
Tune autovacuum, never turn it off
For large, busy tables lower the thresholds so cleanup runs more often and in smaller steps.
-
06
Test backups by restoring
pgBackRest with WAL archiving gives point-in-time recovery. A backup nobody has restored is only a hope.
-
07
Migrations without long locks
CREATE INDEX CONCURRENTLY, a shortlock_timeoutand big changes split into steps keep the site online. -
08
The right types
timestamptzfor time,numericfor money,textwith aCHECKinstead ofvarchar(n), identity columns instead of serial.
What PostgreSQL looks like: 3 SQL examples
Three examples behind PostgreSQL’s main strengths: strict tables with JSON, reports right in the database and a job queue without a separate broker. Checked on PostgreSQL 16.
Strict columns and JSON in one table
Constraints guard the fields whose rules are known, jsonb keeps the rest, and a GIN index finds orders by any key inside the JSON.
-- an order: strict columns where the rules are known, JSON for the rest
CREATE TABLE orders (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
customer_id bigint NOT NULL REFERENCES customers (id),
total numeric(12, 2) NOT NULL CHECK (total >= 0),
status text NOT NULL DEFAULT 'new',
details jsonb NOT NULL DEFAULT '{}',
created_at timestamptz NOT NULL DEFAULT now()
);
-- an index over any field inside the JSON
CREATE INDEX orders_details_idx ON orders USING gin (details);
-- orders delivered by courier
SELECT id, total
FROM orders
WHERE details @> '{"delivery": "courier"}';
Reports and upsert in the database
A window function ranks customers within each month in one query, and ON CONFLICT inserts a row or updates the existing one atomically.
-- revenue by month and each customer's place within the month
SELECT date_trunc('month', created_at) AS month,
customer_id,
sum(total) AS revenue,
rank() OVER (PARTITION BY date_trunc('month', created_at)
ORDER BY sum(total) DESC) AS place
FROM orders
GROUP BY 1, 2
ORDER BY month, place;
-- stock: insert a new row or add to the existing one in a single command
INSERT INTO stock (sku, qty) VALUES ('A-100', 5)
ON CONFLICT (sku) DO UPDATE SET qty = stock.qty + EXCLUDED.qty;
A job queue without a broker
Each worker takes one queued job; SKIP LOCKED makes the others skip it instead of waiting, so workers never grab the same job twice.
-- a worker takes the next job; other workers skip it instead of waiting
WITH next AS (
SELECT id
FROM jobs
WHERE status = 'queued'
ORDER BY created_at
FOR UPDATE SKIP LOCKED
LIMIT 1
)
UPDATE jobs
SET status = 'running', started_at = now()
FROM next
WHERE jobs.id = next.id
RETURNING jobs.id, jobs.payload;
Questions about PostgreSQL
What is PostgreSQL in simple terms?
A free database that stores an application’s data in tables and guarantees it is not lost or corrupted. It is used by websites, online services, shops and banks — from small projects to very large ones.
How do you pronounce PostgreSQL?
“Post-gres-Q-L”. The short name Postgres is officially accepted too.
PostgreSQL or MySQL?
For a new web service or SaaS PostgreSQL is usually the better choice: richer SQL, JSON with indexes, extensions and stricter data. MySQL is simpler to start with and fits classic sites and CMS where it is already the standard.
Can PostgreSQL replace MongoDB?
In most projects — yes: jsonb with GIN indexes stores documents and searches inside them, while keeping transactions and joins. MongoDB remains stronger where built-in sharding of huge document collections is needed.
Is PostgreSQL free?
Yes, completely, including for commercial use. It is distributed under the PostgreSQL License, similar to MIT and BSD; you pay only for servers or a managed service.
How much data can PostgreSQL handle?
Terabytes on one server are normal. With the default block size a table can grow to 32 TB and a single field to 1 GB; beyond one machine, sharding with Citus is used.
Do I need Redis if I have PostgreSQL?
Often not at the start: PostgreSQL can handle queues, simple caching and sessions. Redis or Valkey become worthwhile for hot counters, rate limiting and caches with microsecond access.
Is PostgreSQL good for analytics?
For reports on millions and tens of millions of rows — yes, thanks to window functions and parallel queries. For billions of events a columnar database like ClickHouse is much faster.
Online form
PostgreSQL
databases
I work with PostgreSQL in my projects: I design the schema for the task, speed up slow queries and set up indexes, backups and connections. Tell me about the task — I answer within one working day.