Quick verdict
Choose MySQL if your stack, hosting or team is already built around it, or if you want a built-in, vendor-documented route to automatic failover through Group Replication and InnoDB Cluster. Choose PostgreSQL if you want a permissive licence with no single owning company, the indexable jsonb type, or extensions such as PostGIS and pgvector. Both run demanding production workloads and are offered as managed services by AWS, Azure and Google Cloud, so for a typical web application either is a sound choice.
MySQL is developed by Oracle. The MySQL Community Server is free under the GPL v2, and Oracle also sells commercial editions (Enterprise, Standard and NDB Cluster CGE among them) and runs the MySQL HeatWave cloud service. MySQL has two release tracks: LTS releases (8.4 and 9.7 are the current LTS lines) and Innovation releases. In July 2026 MySQL moved to calendar versioning, and MySQL 26.7.0 is the first such release; it is an Innovation release.
PostgreSQL is developed by the PostgreSQL Global Development Group and released under the PostgreSQL Licence, a permissive licence similar to BSD and MIT. A new major version ships roughly once a year and each is supported for five years. PostgreSQL 18 is the current major version (18.6 at the time of writing), and versions 14 to 18 are supported, with 14 reaching end of life in November 2026.
Side by side
| Aspect | MySQL | PostgreSQL |
|---|---|---|
| Licence | GPL v2 (Community Server and client libraries), plus Oracle commercial licences and editions | PostgreSQL Licence (permissive, BSD/MIT-like) |
| Release model | LTS lines (8.4, 9.7) with 5 years premier plus 3 years extended support; Innovation releases, now calendar versioned (26.7) | One major version a year, each supported for 5 years; current major 18 |
| JSON | JSON type stored in a binary format and validated; indexed through generated columns, functional indexes or multi-valued indexes |
json (text) and jsonb (binary); jsonb supports GIN indexes directly |
| Default isolation level | REPEATABLE READ (InnoDB) | READ COMMITTED |
| MVCC housekeeping | Old row versions rebuilt from undo logs; removed by the purge process | Old row versions stay in the table until VACUUM; autovacuum is on by default |
| Replication | Asynchronous by default, semisynchronous, delayed, GTID-based; Group Replication | Streaming (physical) replication, synchronous option, logical replication, hot standby |
| Automatic failover | Group Replication elects a new primary; InnoDB Cluster with MySQL Router handles client failover | Not in core; the docs say failover detection needs external tools |
| Extensions and special types | Built-in spatial types; VECTOR data type; pluggable storage engines |
Extension system: PostGIS for geospatial, pgvector for vector search, and many more |
| Managed cloud | Amazon RDS and Aurora, Azure Database for MySQL, Google Cloud SQL, Oracle MySQL HeatWave | Amazon RDS and Aurora, Azure Database for PostgreSQL, Google Cloud SQL |
| Official GUI tool | MySQL Workbench (rebuilt as version 26.7 in 2026) | None from the core project; pgAdmin is the widely used community tool |
| Main trade-off | One company controls development and the commercial editions | HA and failover need extra tooling you must choose and run |
Key differences
Licensing and who controls the project
Oracle makes the MySQL server and client libraries available under the GPL v2 (with an additional permission for included software under other licences) and sells commercial licences for software that embeds or bundles MySQL without GPL obligations. Oracle also offers commercial editions such as MySQL Enterprise Edition. PostgreSQL uses the PostgreSQL Licence, which permits use, copying, modification and distribution without fees or written agreements, and the project states it has no plans to change it.
For most teams running a database behind their own application, both licences are free to use. The difference matters mainly if you distribute software that includes the database. This page describes licence terms; it is not legal advice.
JSON vs JSONB
MySQL's JSON type validates documents on insert and stores them in an internal binary format for quick access to elements. JSON columns are not indexed directly: you index a generated column or use a functional index, and InnoDB supports multi-valued indexes on JSON arrays. MySQL can also apply partial in-place updates through JSON_SET(), JSON_REPLACE() and JSON_REMOVE() under documented conditions.
PostgreSQL has two types. json stores an exact copy of the input text; jsonb stores a decomposed binary form that drops whitespace and key order, keeps only the last of duplicate keys, and supports GIN indexes. The PostgreSQL documentation recommends jsonb for most applications.
MVCC and locking
Both engines use multi-version concurrency control so that readers see a consistent snapshot. InnoDB keeps hidden transaction and roll-pointer fields on each row and rebuilds older versions from undo logs; deleted rows are physically removed later by the purge process. Its default isolation level is REPEATABLE READ, where range searches take gap or next-key locks to block inserts into the scanned range.
In PostgreSQL an UPDATE or DELETE leaves the old row version in the table until VACUUM reclaims it, and the documentation states that reading never blocks writing and writing never blocks reading. The default isolation level is READ COMMITTED, and SERIALIZABLE is implemented with Serializable Snapshot Isolation. Autovacuum is enabled by default; the docs advise against disabling it.
Replication and high availability
MySQL replication is asynchronous by default, with semisynchronous and delayed replication, and GTID-based replication that avoids tracking log file positions. Group Replication adds single-primary mode with automatic primary election, or multi-primary mode. The manual notes that Group Replication has no built-in client failover and recommends InnoDB Cluster, which combines it with MySQL Router and MySQL Shell.
PostgreSQL provides WAL-based streaming replication (optionally synchronous), hot standby for read-only queries on replicas, and per-table logical replication. Its documentation is explicit that PostgreSQL does not provide the software to detect a primary failure and promote a standby automatically; you trigger promotion with pg_ctl promote or pg_promote(), or use a third-party HA tool. Managed cloud services handle this for you on both engines.
Extensions: PostGIS, pgvector and MySQL's built-in types
PostgreSQL's extension system is one of its main draws. PostGIS adds storage, indexing and querying of geospatial data. pgvector adds vector similarity search with HNSW and IVFFlat indexes and supports PostgreSQL 13 and later. Managed services such as Azure Database for PostgreSQL document pgvector support.
MySQL builds spatial types into the server (InnoDB and MyISAM support SPATIAL indexes) and has a VECTOR data type holding up to 16,383 single-precision values. A VECTOR column cannot be used as a key. Check the MySQL documentation for which vector search functions are available in your edition before planning on them.
SQL dialect: side by side
Auto-increment vs identity. MySQL uses AUTO_INCREMENT; PostgreSQL supports the SQL standard identity column.
-- MySQL
CREATE TABLE customers (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
name VARCHAR(100)
);
-- PostgreSQL
CREATE TABLE customers (
id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
email varchar(255) NOT NULL UNIQUE,
name varchar(100)
);Upsert. MySQL updates the row when the insert would violate any PRIMARY KEY or UNIQUE index; the current manual recommends a row alias over the deprecated VALUES() function. PostgreSQL names the conflict target, which needs a unique index or constraint, and refers to the proposed row as EXCLUDED. PostgreSQL also supports MERGE.
-- MySQL
INSERT INTO customers (email, name)
VALUES ('ana@example.com', 'Ana') AS new
ON DUPLICATE KEY UPDATE name = new.name;
-- PostgreSQL
INSERT INTO customers (email, name)
VALUES ('ana@example.com', 'Ana')
ON CONFLICT (email) DO UPDATE SET name = EXCLUDED.name;String aggregation. MySQL's GROUP_CONCAT output is truncated at group_concat_max_len, which defaults to 1024; PostgreSQL's string_agg takes the delimiter as an argument and an optional ORDER BY inside the call.
-- MySQL
SELECT customer_id,
GROUP_CONCAT(product ORDER BY product SEPARATOR ', ') AS products
FROM orders
GROUP BY customer_id;
-- PostgreSQL
SELECT customer_id,
string_agg(product, ', ' ORDER BY product) AS products
FROM orders
GROUP BY customer_id;Limiting rows. Both accept LIMIT ... OFFSET. MySQL also accepts LIMIT offset, count; PostgreSQL also accepts the SQL standard FETCH FIRST form.
-- MySQL and PostgreSQL
SELECT id, name FROM customers ORDER BY id LIMIT 10 OFFSET 20;
-- MySQL only
SELECT id, name FROM customers ORDER BY id LIMIT 20, 10;
-- PostgreSQL (SQL standard form)
SELECT id, name FROM customers ORDER BY id
OFFSET 20 ROWS FETCH FIRST 10 ROWS ONLY;For function-by-function differences, see the SQL functions library.
Pricing and licensing
MySQL: MySQL Community Server is free under the GPL v2. Oracle sells commercial licences for embedding MySQL in products distributed without GPL obligations, and commercial editions (MySQL Enterprise Edition, Standard Edition and NDB Cluster CGE are listed on mysql.com). We did not record prices for these editions; check Oracle's MySQL store or ask Oracle sales for current terms. MySQL HeatWave is Oracle's managed cloud service, priced separately.
PostgreSQL: free under the PostgreSQL Licence for any use, with no commercial edition from the core project. Commercial support and distributions are available from third-party companies.
Managed cloud: both engines are offered by Amazon RDS (and Aurora with MySQL or PostgreSQL compatibility), Microsoft Azure and Google Cloud SQL. Cloud pricing depends on region, instance size, storage and HA options; use each provider's pricing calculator.
Pricing checked on the vendors' official pages on 7 October 2026. Prices change; confirm before buying.
Where each one leads
MySQL strengths
- Built-in automatic primary election through Group Replication, with InnoDB Cluster and MySQL Router for client failover
- LTS release lines with 5 years premier and 3 years extended support under Oracle's lifetime policy
- Vendor-backed commercial editions and support from Oracle for organisations that want them
- Wide managed-cloud availability, including Oracle's own MySQL HeatWave
- Spatial types and a VECTOR data type built into the server
PostgreSQL strengths
- Permissive PostgreSQL Licence with no single owning company
- jsonb type with direct GIN indexing, recommended by the docs for most JSON use
- Extension ecosystem, including PostGIS for geospatial and pgvector for vector search
- Standard SQL features such as identity columns, FETCH FIRST and MERGE
- Predictable release cadence with five years of support per major version
Limitations
MySQL limitations
- GROUP_CONCAT results are truncated at 1024 by default unless group_concat_max_len is raised
- JSON columns cannot be indexed directly; you need generated columns or functional indexes
- Innovation releases may remove features or change behaviour between releases, per Oracle's release model
- Some features and tools are tied to Oracle commercial editions or HeatWave
PostgreSQL limitations
- No automatic failover in core; you need an external HA tool or a managed service
- MVCC leaves dead row versions that autovacuum must keep up with
- Major version upgrades need planning; a new major arrives every year and each is supported for five years
- No official GUI from the core project; tooling comes from the community or vendors
When to choose each
Choose MySQL if
- Your application, framework or hosting is already built around MySQL
- You want a documented, built-in path to automatic failover with InnoDB Cluster
- You want the option of commercial support and editions from the database vendor
- You plan to use MySQL HeatWave on Oracle Cloud
- Your team already knows MySQL or MariaDB
Choose PostgreSQL if
- You want a permissive licence with no single vendor in control
- You store and query a lot of JSON and want jsonb with GIN indexes
- You need geospatial work with PostGIS or vector search with pgvector
- You value standard SQL features such as identity columns, FETCH FIRST and MERGE
- You want to extend the database with custom types, functions or extensions
When neither is right
- You need an embedded, serverless database inside an app or device: SQLite is usually the better fit. See SQLite vs MySQL.
- Your organisation is standardised on Microsoft tooling and licensing: consider SQL Server. See MySQL vs SQL Server and SQL Server vs PostgreSQL.
- Your data is mostly schemaless documents with no relational joins: a document database may suit better. See MongoDB vs PostgreSQL.
- You want MySQL compatibility with a community-governed fork: look at MariaDB. See MariaDB vs MySQL.
Final recommendation
For most new applications either database will do the job, so decide on the factors that differ. Choose PostgreSQL when licence freedom, jsonb, standard SQL features or extensions such as PostGIS and pgvector matter, and accept that you will add an HA tool or use a managed service for failover. Choose MySQL when your stack and skills are already MySQL-based, when you want Oracle's built-in InnoDB Cluster route to high availability, or when vendor commercial support is a requirement. Pick an LTS line (MySQL 8.4 or 9.7) or a supported PostgreSQL major, and plan upgrades before end of support.
Frequently asked questions
Is MySQL or PostgreSQL better?
Neither is better in general. PostgreSQL leads on licence permissiveness, jsonb and extensions; MySQL leads on built-in HA through InnoDB Cluster and on vendor commercial support from Oracle. Choose on those differences and on what your team already runs.
Are MySQL and PostgreSQL free for commercial use?
Yes for running them. MySQL Community Server is free under the GPL v2, and Oracle sells commercial licences if you embed MySQL in software you distribute without GPL terms. PostgreSQL is free under the permissive PostgreSQL Licence for any use.
What are the current versions of MySQL and PostgreSQL?
In October 2026 MySQL 26.7 (July 2026) is the latest release and an Innovation release; MySQL 8.4 and 9.7 are the current LTS lines. PostgreSQL 18 is the current major version, with 18.6 the latest minor release.
Which has better JSON support?
PostgreSQL's jsonb type can be indexed directly with GIN indexes and is recommended by its documentation for most uses. MySQL's JSON type is binary-stored and validated but is indexed through generated columns, functional indexes or multi-valued indexes.
How do I write an upsert in MySQL vs PostgreSQL?
MySQL uses INSERT ... ON DUPLICATE KEY UPDATE, ideally with a row alias such as AS new. PostgreSQL uses INSERT ... ON CONFLICT (column) DO UPDATE SET column = EXCLUDED.column, which needs a unique index or constraint on the conflict column. See the examples in the SQL dialect section above.
Which GUI tools work with MySQL and PostgreSQL?
MySQL Workbench is Oracle's MySQL tool and pgAdmin is the common PostgreSQL tool. A multi-engine client such as DBeaver works with both. See the best MySQL GUI tools and best PostgreSQL GUI tools.
Sources
- MySQL Reference Manual: release model and calendar versioning
- MySQL licensing (GPL v2 and commercial licences)
- MySQL Reference Manual (InnoDB, JSON, replication, Group Replication)
- PostgreSQL versioning policy
- PostgreSQL Licence
- PostgreSQL documentation (MVCC, JSON types, replication, INSERT)
- PostGIS
- pgvector (GitHub)
- Amazon RDS
- Google Cloud SQL documentation
Checked October 2026.
How we research comparisons: our editorial method.