Overview
PostgreSQL and MySQL are both free, open-source, relational databases, and both give you real ACID transactions with MVCC (multi-version concurrency control) under the hood, so for a huge range of applications, either one will work correctly. The differences that matter show up once you look at what each database was built to optimize for: PostgreSQL was built as a standards-compliant, extensible object-relational system; MySQL was built for straightforward, fast relational storage with a strong focus on ease of replication and operation at web scale.
Feature comparison
| PostgreSQL | MySQL (InnoDB) | |
|---|---|---|
| Concurrency model | MVCC, native | MVCC via InnoDB, the default storage engine since 5.5 |
| JSON support | jsonb, binary, indexable with GIN | JSON, validated on write, not natively GIN-indexed |
| Arrays / composite types | Native array and custom composite types | No native array type |
| Full-text search | Built in (tsvector/tsquery) | Built in, less flexible ranking |
| Materialized views | Yes | No native equivalent |
| Recursive CTEs | Yes | Yes, since MySQL 8.0 |
| Window functions | Yes | Yes, since MySQL 8.0 |
| Table partitioning | Declarative partitioning built in | Native partitioning, fewer partition types |
| Extensions | Rich ecosystem (PostGIS, pg_trgm, pg_stat_statements, …) | Pluggable storage engines, fewer extension points |
| Replication | Streaming (physical) and logical replication | Binlog-based replication, mature and widely deployed |
| Row-level security | Built in | Not built in, enforced in application logic |
Where PostgreSQL tends to win
Anything that benefits from rich data types or extensibility. Storing semi-structured data next to
relational data (jsonb with a GIN index queries almost as fast as a dedicated column), geospatial
data (PostGIS is the de facto standard for this), or workloads that want materialized views,
recursive queries, or custom aggregate functions all lean toward PostgreSQL.
Where MySQL tends to win
Simplicity and familiarity at scale. A huge share of the web's CMS/e-commerce/SaaS stack (and the tooling, hosting, and operational knowledge that comes with it) was built around MySQL, and its replication model is a well-understood, battle-tested path to read scaling. If your workload is straightforward relational CRUD and your team already knows MySQL operations, there's rarely a strong reason to switch.
Note
Both databases have closed most of the historical feature gaps (window functions, CTEs, and JSON support all landed in MySQL 8.0), pick based on your actual data model and team's operational experience, not outdated "MySQL is faster, Postgres has more features" folklore from a decade ago.
Verdict
Neither database is categorically better; they're both mature, both handle real transactional workloads correctly, and the gap in raw feature support has narrowed a lot. Reach for PostgreSQL when your data model wants richer types or extensibility; reach for MySQL when you want the most common, most widely supported relational default and don't need those extras.