Postgres vs MySQL in 2016: A Practical Comparison

| 5 min read |
postgresql mysql databases architecture

A grounded look at PostgreSQL and MySQL as of April 2016, focusing on integrity, query power, and operational tradeoffs rather than benchmark hype.

Quick take

Pick Postgres. If your workload is dead-simple CRUD and your team already bleeds MySQL, fine, stay there. For everything else in 2016, PostgreSQL gives you more database and fewer workarounds.


The short answer

I’m building the fintech startup on PostgreSQL. Financial data, JSONB documents, full-text search across thousands of sources, strict schema enforcement for anything that touches money. I evaluated MySQL honestly. Postgres won on every axis that matters to me.

That doesn’t make MySQL bad. It makes the decision obvious for my workload. Here is how I see the tradeoffs.

The comparison

CapabilityPostgreSQLMySQL (InnoDB, 5.7)
Data integrityStrict by default. Type violations, overflows, and constraint breaches are errors. CHECK constraints enforced.Lenient by default. Will silently truncate or coerce unless you enable strict mode. CHECK constraints parsed but not enforced.
Transactional DDLYes. Failed migrations roll back cleanly.No. DDL auto-commits. A failed migration leaves you half-changed.
JSONBFirst-class. GIN-indexed, queryable with operators, fast.JSON type exists but no binary storage, limited indexing. Practical queries need generated columns.
Full-text searchBuilt in. Dictionaries, ranking, language support. Good enough to skip Elasticsearch for many cases.Basic keyword matching. Serviceable for simple search, but you will add Solr or Elastic quickly.
Window functionsYes, mature.No. Not until 8.0 (years away). Analytics queries become subquery nightmares.
CTEsYes. Recursive CTEs too.No. Same story as window functions.
Custom types/operatorsYes. You can build domain-specific behavior inside the database.Limited UDFs. No custom operators or types.
Concurrency modelMVCC with new row versions. Requires vacuum.MVCC via undo logs. Purge is less visible operationally.
Connection handlingProcess-per-connection. Needs PgBouncer at scale.Thread-per-connection. Handles high connection counts more easily out of the box.
ReplicationStreaming (physical). Reliable, simple, but replicates the whole cluster. Logical replication is third-party in 2016.Row-based, statement-based, or mixed. More flexible for partial replication. More edge cases.
Ecosystem/hostingSmaller managed ecosystem. RDS supports it well. Fewer one-click options.Everywhere. Every cheap host, every managed platform. Largest install base.
UpgradesMajor version upgrades need planning. pg_upgrade helps but it isn’t seamless.Generally smoother in-place upgrades.

Where Postgres pulls ahead

Correctness is the default. I don’t want my database silently truncating a currency field or accepting a string where an integer belongs. Postgres refuses bad data. MySQL lets it through unless you configure it not to. In financial systems, the database being strict isn’t a feature request. It’s the minimum.

JSONB changes what you can do. At the fintech startup we store semi-structured financial events alongside relational data. Postgres lets me index into JSONB, query nested fields, and join it with relational tables in one query. With MySQL I would be serializing JSON, pulling it into the application, and filtering there. That isn’t a comparison. That’s a generation gap.

Full-text search removes a dependency. We search across news sources, filings, and analyst content. Postgres full-text search with ts_vector, dictionaries, and ranking handles this without bolting on a separate search cluster. One fewer service to operate, monitor, and keep in sync.

Window functions and CTEs aren’t optional. If you do any reporting or analytics, you need them. MySQL not having them in 2016 means your choices are ugly subqueries, dumping data into a separate analytics tool, or doing the math in application code. Postgres just does it.

Where MySQL wins

I’ll give MySQL its due.

Connection scaling. Postgres forks a process per connection. At a few hundred connections, memory adds up fast and you need a pooler. MySQL handles thousands of threads without breaking a sweat. If your architecture has many direct database connections and you don’t want to manage PgBouncer, that matters.

Operational simplicity for upgrades. MySQL major version upgrades tend to be less painful. Postgres upgrades have gotten better, but they still require more planning and occasionally downtime.

Ubiquity. MySQL is everywhere. Every shared host, every tutorial, every legacy system. If you’re inheriting a MySQL codebase and the schema is simple, migrating to Postgres just because you prefer it is a waste of time. Use what is there.

My decision framework

Three questions:

  1. Does your data need to be correct, or just present? If correctness matters–financial data, health records, billing–Postgres. Its strictness isn’t friction. It’s protection.

  2. Do you need more than basic SELECT/INSERT/UPDATE? If you need JSONB, full-text search, window functions, CTEs, or custom types, Postgres gives you those today. MySQL will make you bolt on external tools or wait for features that aren’t shipping in 2016.

  3. Is your team already deep in MySQL? Then stay. Database expertise matters more than database features. A well-tuned MySQL with a team that knows it will outperform a poorly operated Postgres every time.

The honest take

Most of the “Postgres vs MySQL” content online bends over backward to be balanced. I won’t. For my workloads–financial data, mixed relational and document storage, search, reporting–Postgres isn’t a marginal winner. It’s the obvious choice.

MySQL is a fine database for simpler workloads and teams that know it well. But if you’re starting fresh in 2016 and your needs are anything beyond basic CRUD, pick Postgres. You will thank yourself when the first complex query lands and you don’t have to rewrite it as three subqueries and an application-side join.

The best database decision is the pragmatic one, not the tribal one. Pick the tool that does more of the work for you and stop arguing about logos.