For most new applications either MySQL or PostgreSQL is a safe choice, because both are mature open source relational databases with ACID transactions, foreign keys and multi-version concurrency control. The differences that usually decide the question are licensing, the release and support model, how each handles JSON and richer data types, and what your team and hosting platform already know. If none of those points clearly to one, choose the one your team can operate and back up confidently, then verify it with your own schema and queries.
This guide is for developers, architects and small-team leads picking a database for a new web or line-of-business application. It compares the two on facts taken from the official documentation, gives a decision table, and ends with a checklist for a short proof of concept. Details were checked on 28 October 2026; versions move on, so confirm current releases on each project's site.
Quick comparison
| Area | MySQL | PostgreSQL |
|---|---|---|
| Licence | Dual: GPL (Community) or commercial licence from Oracle | PostgreSQL License, permissive and BSD/MIT-like |
| Release model | LTS and Innovation tracks | One major release about once a year |
| Support period | LTS: Oracle Lifetime Support, 5 years premier plus 3 years extended; Innovation: until the next Innovation release | 5 years per major version |
| Default storage | InnoDB: ACID, row-level locking, foreign keys, MVCC | Single built-in transactional storage with MVCC |
| JSON | Native JSON type; index via generated columns or multi-valued indexes | json and jsonb; jsonb supports GIN, btree and hash indexes |
| Major upgrade tooling | Upgrade to the next LTS series is supported; skipping an LTS series is not | Dump and reload, or pg_upgrade |
Licensing: what it means for your app
PostgreSQL is released under the PostgreSQL License, a liberal licence similar to BSD or MIT. It permits use, copying, modification and distribution for any purpose without a fee or a written agreement, provided the copyright notice and licence paragraphs appear in all copies. The project states it is committed to keeping PostgreSQL free and open source and has no plans to change the licence.
MySQL is dual-licensed. Oracle distributes the server and client libraries under the GPL and under a commercial licence. For most teams that simply run MySQL as the database behind their own application, the GPL edition is what they download. The commercial licence matters mainly when you distribute software that embeds or bundles MySQL and do not want to release that software's source under the GPL. Oracle also sells commercial editions (such as Enterprise Edition) that add paid support. Because licence questions depend on how you distribute software, read Oracle's licensing pages and, if in doubt, get legal advice.
Release cycles and support
PostgreSQL
The PostgreSQL project releases a new major version about once a year, and each major version receives bug and security fixes in minor releases at least once every three months for 5 years. As of the project's versioning page on 28 October 2026, versions 14 through 18 are supported, and version 14 reaches end of life on 12 November 2026. Version 18 was first released on 25 September 2025 and is supported until November 2030. Minor upgrades only require replacing binaries and restarting; major upgrades need a dump and reload or pg_upgrade. For the upgrade procedure see PostgreSQL Major Version Upgrade with pg_upgrade.
MySQL
MySQL has two tracks. LTS releases suit environments that want stable features and a long support period; only necessary fixes are included, and no features are removed within an LTS series. Innovation releases suit teams that want the newest features and can test and upgrade quickly; they may introduce behaviour changes affecting SQL syntax or performance. LTS support is covered by Oracle Lifetime Support (5 years premier plus 3 years extended). Innovation releases are supported until the next Innovation release. You can upgrade to the next LTS series (for example, 8.4.x to 9.7.x) but not skip one. The documentation lists 8.4 and 9.7 as LTS series. For a production app that you do not plan to upgrade often, the LTS track is the conservative choice.
Storage engine and transactions
In MySQL 8.4, InnoDB is the default storage engine: a CREATE TABLE without an ENGINE clause creates an InnoDB table. Its DML operations follow the ACID model, with commit, rollback and crash recovery, and it provides row-level locking, foreign key constraints and consistent reads based on MVCC. For a new application using current MySQL, these guarantees are the default rather than something you configure.
PostgreSQL provides transactions, foreign keys and MVCC as part of its core engine. In practice both give you what a typical business application needs. Where they differ is at the edges, such as the data types and index types available, and how each handles maintenance. PostgreSQL's vacuum process, for instance, needs attention on write-heavy tables; see PostgreSQL Autovacuum Tuning to Fix Table Bloat.
JSON and flexible data
Both databases handle JSON, but they differ in indexing.
PostgreSQL has json and jsonb. The documentation recommends jsonb for most applications: it stores a decomposed binary form that is significantly faster to process, supports containment (@>) and existence (?) operators, and can be indexed with GIN. A GIN index on a whole document looks like this:
CREATE INDEX idxgin ON api USING GIN (jdoc);
SELECT jdoc->'guid', jdoc->'name' FROM api
WHERE jdoc @> '{"company": "Magnafone"}';MySQL has a native JSON type that validates documents on insert and stores them in an optimised binary format. The documentation states that JSON columns cannot be indexed directly. Instead, you index a generated column that extracts a scalar value, or use a multi-valued index for arrays:
CREATE TABLE t1 (
jdoc JSON,
name VARCHAR(100) GENERATED ALWAYS AS (JSON_UNQUOTE(JSON_EXTRACT(jdoc, '$.name'))) STORED,
INDEX idx_name (name)
);If your application searches deeply inside JSON documents with varying keys, PostgreSQL's jsonb with GIN is the more direct fit. If you store JSON mostly as an attribute and query a few known fields, MySQL's generated-column approach works well.
Extensions and specialised workloads
PostgreSQL is built to be extended, and many specialised features ship as extensions. One example is vector search: see pgvector with PostgreSQL: HNSW and IVFFlat Index Tuning. PostgreSQL 18, the latest major version on the feature matrix, lists features such as UUIDv7 support, OAuth authentication and returning OLD and NEW values from modified rows. If you need a specific capability, check the feature matrix for the version you plan to run rather than assuming parity.
MySQL's strengths include widespread availability on shared and managed hosting and support in many web frameworks and tools. Check your hosting provider's supported versions before you decide; managed services often lag the latest releases and may restrict extensions or settings.
Decision guide
| If your situation is... | Lean towards |
|---|---|
| You distribute software that bundles the database and want permissive terms | PostgreSQL |
| You need to query deep inside JSON documents with GIN indexes | PostgreSQL |
| You want an explicit LTS track with a long vendor support period | MySQL LTS (or PostgreSQL's fixed 5-year policy; both are predictable) |
| Your host, CMS or framework is built around one of them | That one |
| Your team already operates and backs up one of them well | That one |
| You need a specific extension or data type | Whichever lists it for your target version |
The last two rows matter more than any feature comparison: operational skill, backups you have tested and a hosting platform that supports your version are what keep a database healthy.
Run a short proof of concept
Before committing, spend a day testing with your own data:
- Create the real schema in both databases, using each one's recommended data types.
- Load a realistic sample of data.
- Write your five most important queries and your heaviest write path, and test them on both.
- Check the execution plans. In PostgreSQL see How to Read EXPLAIN ANALYZE Query Plans; in MySQL use
EXPLAIN. - Practise a backup and restore, and a minor version upgrade.
- Check what your hosting provider offers for each: versions, backups, replicas and extensions.
Checklist
- Licence terms reviewed for how you will distribute or host the app.
- Version chosen has years of support left (not a version nearing end of life).
- For MySQL, LTS or Innovation track chosen deliberately.
- JSON usage and indexing strategy tested.
- Backup, restore and upgrade procedures rehearsed.
- Hosting provider supports the version and features you need.
References
- PostgreSQL, versioning policy and supported versions: https://www.postgresql.org/support/versioning/
- PostgreSQL, licence: https://www.postgresql.org/about/licence/
- PostgreSQL, feature matrix: https://www.postgresql.org/about/featurematrix/
- PostgreSQL documentation, JSON types: https://www.postgresql.org/docs/current/datatype-json.html
- MySQL 8.4 Reference Manual, release model (LTS and Innovation): https://dev.mysql.com/doc/refman/8.4/en/mysql-releases.html
- MySQL 8.4 Reference Manual, InnoDB introduction: https://dev.mysql.com/doc/refman/8.4/en/innodb-introduction.html
- MySQL 8.4 Reference Manual, the JSON data type: https://dev.mysql.com/doc/refman/8.4/en/json.html
- MySQL, licensing and OEM: https://www.mysql.com/about/legal/licensing/oem/
- MySQL, supported platforms: https://www.mysql.com/support/supportedplatforms/database.html
Comments
Questions and tips are welcome. Comments are checked by the EpiFive team before they appear; please do not share passwords, phone numbers or other private details.