Overview
Pick Postgres for new application databases; keep MySQL when the team already operates it well or needs Vitess-style sharding. As of 2026-10-01 PostgreSQL 18 (released 2025-09-25) is the current major, with 19 in beta, and MySQL 9.7 (released 2026-04-21) is the current Long-Term Support release alongside 8.4 LTS.
Comparison
| Dimension | Postgres 18 | MySQL 9.7 LTS |
|---|---|---|
| Types and JSON | jsonb with GIN indexes, arrays, ranges, rich types | JSON type with generated-column indexes |
| Indexes | B-tree (with skip scan in 18), GIN, GiST, BRIN, hash, partial, expression | B-tree, full-text, spatial, hash |
| DDL | Transactional; rolls back with the transaction | Atomic per statement; DDL implicitly commits |
| Extensions | pgvector, PostGIS, pg_partman, TimescaleDB, Citus | Plugins and storage engines; no comparable extension catalog |
| Scale-out | Read replicas; Citus or application sharding | Vitess is the established sharding layer |
| Notable recent | Asynchronous I/O, uuidv7(), virtual generated columns, OAuth auth | LTS releases: 8.4 and 9.7; 9.7 is the last line with sequential numbers; Innovation releases now use calendar versions (26.7 shipped 2026-07-28) |
| License | PostgreSQL License (permissive) | GPL with commercial option, owned by Oracle |
Pick Postgres when
Pick Postgres by default for SaaS, internal tools, and mixed relational and JSON data.
- One engine for relational data, JSONB documents, vectors (pgvector), and geospatial (PostGIS). See pinecone-vs-pgvector.
- Use
uuidv7()(new in 18) for time-ordered primary keys that keep indexes compact. - Transactional DDL makes migrations safer to retry.
- Managed hosts are plentiful: RDS, Aurora, Neon, Supabase, and others. See aurora-vs-rds-postgres.
Pick MySQL when
Pick MySQL when migration cost outweighs Postgres benefits.
- An existing Aurora MySQL deployment, or a MySQL fleet with tooling for replication, ProxySQL, and online schema change (
gh-ost,pt-online-schema-change). - Vitess-based horizontal sharding is the requirement.
- An application or framework tied to MySQL behavior (collations,
AUTO_INCREMENT, SQL modes). - Prefer the LTS releases for production; innovation releases are supported only until the next one.
Migrate
MySQL to Postgres is common; use pgloader for the load, then fix dialect differences.
AUTO_INCREMENTbecomesGENERATED ... AS IDENTITY;TINYINT(1)becomesboolean;ENUMbecomes a Postgres enum or check constraint.- Postgres is case-sensitive by default in comparisons; MySQL’s default collations are case-insensitive, so add
lower()indexes orcitext. - Stricter
GROUP BYand different string concatenation (||versusCONCAT) surface in application SQL. - ORMs (Prisma, Drizzle, SQLAlchemy) run on both; most work is in raw SQL and stored procedures.
See postgres for Postgres rules.
FAQ
Should I use Postgres or MySQL for a new app?
Use Postgres 18 by default for SaaS, internal tools, and mixed relational and JSON data. Pick MySQL 9.7 LTS only when you already run MySQL well, need Vitess sharding, or a framework is tied to MySQL behavior.
Is Postgres better than MySQL for JSON data?
Yes; Postgres jsonb supports GIN indexes, while MySQL’s JSON type relies on generated-column indexes. Postgres also adds arrays, ranges, and extensions such as pgvector and PostGIS in the same engine.
Which MySQL version should I run in production?
Prefer the LTS releases, 8.4 or 9.7, because innovation releases are supported only until the next one ships. MySQL 9.7 is the last line with sequential version numbers; innovation releases now use calendar versions.
How do I migrate from MySQL to Postgres?
Load the data with pgloader, then fix dialect differences such as AUTO_INCREMENT to GENERATED ... AS IDENTITY and TINYINT(1) to boolean. Watch case-sensitive comparisons, since MySQL’s default collations are case-insensitive; add lower() indexes or citext.