←  Insights

Databases

Choosing between PostgreSQL and MySQL for a new product

How we pick a relational database at the start of a build, and why the answer is usually less interesting than the question.

Xen IV 14 August 2026 4 min read

Both databases will serve a new product perfectly well for years. That is the uncomfortable starting point for an article like this. The decision is rarely about throughput. It is about what your team already operates, what the application needs, what managed hosting exists where you serve, and what it costs if the first answer turns out to be wrong.

The first of those is the main factor and not a tie-breaker: the gap a team’s existing experience creates is wider than any feature difference below. The ecosystem question is the most absolute. If the product is WordPress or Magento, there is no decision to make.

The version landscape moved in 2026

PostgreSQL is deliberately boring: five years of support per major version, end date published on release. 18 is current and 14 goes end of life in November 2026. MySQL moved to calendar versioning from 26.7 in July 2026, and 8.0 dropped to Sustaining Support that April, which is Oracle telling you to leave. The trap is that MySQL 9.x is not generally available on Amazon RDS, which offers 8.0 on Extended Support and 8.4 while listing PostgreSQL 15 through 18 as GA.

Where PostgreSQL genuinely leads

Some standard arguments are five years stale. MySQL 8.0 has CTEs, window functions and LATERAL. What still differs:

Partial indexes, which are a correctness feature. A unique index with a WHERE clause enforces one successful row per pair with unlimited failures. MySQL has no translation, and on migration that constraint does not fail loudly. It just stops existing.

Transactional DDL. A failed migration in PostgreSQL rolls back cleanly. In MySQL it leaves the schema half-applied, which shapes every migration you write.

Row-level security and extensions. pgvector supports HNSW indexes and vectors to 16,000 dimensions. MySQL 9.7’s VECTOR type cannot be used as any kind of key, and its distance function lives in HeatWave, not the community server.

Where MySQL and MariaDB genuinely lead

High availability in the box, which PostgreSQL’s own manual concedes: it does not ship the software to detect a primary failure and notify a standby, so you add Patroni and etcd, or a managed provider. MySQL ships Group Replication with automatic failover in Community Edition, and MariaDB bundles Galera.

Cheaper connections, because PostgreSQL is still process-per-connection.

Regional full-text search. MySQL has an ngram parser and a MeCab plugin for CJK; PostgreSQL needs a third-party extension. Test it against your own corpus.

The default that surprises people

PostgreSQL defaults to READ COMMITTED and MySQL to REPEATABLE READ, which looks like MySQL shipping the safer default. It is not. PostgreSQL’s REPEATABLE READ is snapshot isolation and does not permit phantom reads. MySQL’s is a half snapshot, and its own documentation gives a worked example where a count returns zero and the update immediately after affects ten rows. Jepsen tested MySQL 8.0.34 and found write skew and 198 lost updates on one healthy node. Whichever you pick, know what your isolation level guarantees and write the retry wrapper.

Managed hosting in the regions we work in

Singapore is the only Southeast Asia option on every provider we checked, with two exceptions. AWS Thailand launched in January 2025 with RDS PostgreSQL, MySQL, MariaDB and both Aurora engines, though it needs an account opt-in and lacks around 58 services Singapore has. Google Cloud’s Bangkok region followed a year later with AlloyDB and explicit PDPA residency framing.

Which migration direction is harder

Nobody credible publishes a migration timeline with a team size attached, so treat any such number sceptically. The tooling settles the direction question on its own: pgloader only goes one way.

MySQL to PostgreSQL problems are data problems, and they are finite: zero dates, identifiers over the 63-byte limit, TINYINT(1) that might be a boolean, junk admitted under non-strict mode. The one that catches people is collation. MySQL’s default is case and accent insensitive, so a unique email index that rejected a capitalised duplicate accepts both after migration. Nothing errors. Users simply cannot log in.

PostgreSQL to MySQL problems are missing features, and they have no mechanical fix: partial indexes, arrays, materialised views, RETURNING, sequences, row-level security, the extensions. Across every first-hand account the finding is the same: the data copy is the automatable part, and the application layer is the cost.

What we recommend

For a new product with no team preference and no ecosystem constraint, we default to PostgreSQL. Extensions absorb requirements that would otherwise become separate infrastructure, transactional DDL changes the risk profile of every schema change you will ever make, and the migration asymmetry is option value.

We recommend MySQL or MariaDB without hesitation when the team already runs it, when the product sits in the WordPress or Magento ecosystem, when community edition failover is a hard requirement, or when regional full-text search is central.

What we would not do is spend a week on it. The cases where it is genuinely close are the cases where it does not much matter, and a week spent on schema design repays itself far more.

Working on something like this?

Describe the system and the constraints. We reply with questions, not a proposal template.