Postgres vs MySQL in 2026: the choice I actually make — and the one I stopped overthinking
James Okonkwo
August 28, 2026
I used to run a bake-off. Two local boxes, a synthetic load, a slide about storage engines, a week I will not get back. In 2026 I do not do that for a new product. I pick Postgres unless a constraint I can name is already in the building. The overthinking I retired was the idea that the database choice is where we would win. We win on the schema, the indexes we actually look at, and the queries we do not hide behind an ORM. The engine is a default. Defaults should be boring.
I still respect MySQL. I have kept it. I have been glad I kept it. I have also been glad I stopped pretending the two are a personality test.
The choice I actually make
Greenfield, general product, SQL team, hosted is fine: Postgres. Not because it is morally better. Because the extras I keep needing — JSON that is not a dare, full text that is good enough, a sane extension story, logical replication I can explain — showed up on the Postgres side first and stayed there. Hiring is easier when the resume says Postgres and the job is Postgres. The hosted market in 2026 is a pile of Postgres-shaped offerings. I do not fight a pile for sport.
I do not pick it because of a benchmark tweet. I have seen MySQL win a read-heavy microbenchmark and still be the wrong operational choice for a team that wanted a particular backup story. I have seen Postgres win a feature argument and still be wrong in a shop whose entire on-call already dreams in InnoDB.
What I stopped overthinking
Charset drama. Collation essays. “Which is faster for simple CRUD.” For the first two years of a product, both are fast enough if you have a primary key and you are not doing accidental table scans. The scan is the problem. The logo on the port is not.
I stopped overthinking JSON-as-a-reason. Both can store JSON. Postgres made it less of a side quest. If JSON is your entire data model, I will ask why you are not in a document store, and then I will still often pick Postgres because you will want joins next quarter.
I stopped overthinking “we might need to scale writes like a unicorn.” If you need Vitess or a similar story, you will know because you have a number, not a fear. Fear is how people pick a harder operational path on day one and then never reach the number.
I stopped overthinking extensions as a religion. pgvector, PostGIS, good full text: those are reasons when they are the product. They are not reasons to rewrite a healthy MySQL app. They are reasons I start new work on Postgres so I do not adopt a second database when the feature shows up.

When I still pick MySQL without a debate
The company already runs it well. On-call knows it. The backups restore. The tooling is paid for. I will not migrate a working estate to feel 2026. I will add Postgres next to it only if a new system has a feature we cannot honestly do, and even then I will ask whether we are ready for two databases. Two databases is a tax. I have paid it. I only pay it for a noun.
The team is a MySQL team and the hire pipeline is MySQL. Language gravity applies to SQL too. A mid-level who can read EXPLAIN in the dialect they have is more valuable than a theoretically nicer engine they will misuse.
A managed offering you already standardized on — a particular host, a particular branching workflow, a particular compliance story — that happens to be MySQL. I pick the host we can staff. I do not pick a logo and then discover the host is a science project.
A specific compatibility need: software that only speaks MySQL, an analytics tool, a vendor dump. Ugly and real. I will not fight a vendor’s dump with a principle.
When I still pick Postgres without a debate
New SaaS. New internal system with mixed relational and document-shaped data. Anything that might want a reasonable queue in the same database for a while. Anything that might want full text before we buy a search cluster. Anything that might want vectors without standing up a second product on week two. I can leave those features on the table. I like them in the default.
A team that already thinks in Postgres. Same gravity, other direction.
A need for logical decoding, a cleaner publication story, or a replica shape I have already operated. This is scar tissue, not a brochure.

The operational facts I actually check
Not the engine war. The restore. When did we last restore. How long. Who knows how. If the answer is “the host does it” I still want a drill. I have seen both engines survive a host and die in a human process.
Migration discipline. Both will punish a lock you did not expect. Postgres and MySQL have different sharp edges. I care that the team knows the edge they have, not that we picked the fashionable edge.
Observability. Can I see the query that is killing us. Both can. If we cannot, the problem is our setup, not the logo.
Cost of the host we will actually use. Serverless-shaped Postgres and always-on MySQL (or the reverse) can invert a spreadsheet. I pick the bill I understand. I do not pick a name and then get surprised by connections or compute units.
What I tell a founder who wants a bake-off
If you have no constraint, pick Postgres and spend the week on the schema. If you have a MySQL estate, stay and spend the week on the slow query. If you have a compliance host that only blesses one, pick that one. A bake-off between healthy defaults is how we avoid talking about data ownership. I have run that bake-off. It produced a slide. The slide did not fix an N+1.
If you are choosing because a blog in 2014 said one was for the web and one was for serious people, throw the blog out. That map is dead. Both are serious. Both are for the web. The serious part is the person who reads the plan.
ORMs do not change the default
I have been asked whether Prisma or Hibernate should pick the engine. No. The ORM will hide the dialect until it cannot. Then you will debug the dialect anyway. Pick the engine the on-call can debug. Configure the ORM after. If an ORM only shines on one engine, that is a point, not a strategy. I have switched ORMs more often than I have switched engines. That should tell you where the fashion lives.
I also stopped using “MySQL for WordPress, Postgres for everything else” as a thought-terminating sentence. WordPress is a constraint. Your API is not WordPress. If you inherited MySQL from a CMS, you still do not have to inherit it for the next service. You also do not have to split on day one. Constraints are local.
The overthinking I will allow
I will overthink a migration off a working database. That is expensive and rare. I will overthink a second database for a real workload. I will overthink an extension that becomes a production dependency. I will not overthink the first logo on a new product that looks like every other CRUD-plus-webhooks app I have shipped. That logo is Postgres in my shop. MySQL if the shop already is. I sleep either way if the restore works and the slow query has a name.
That is the choice I actually make. The one I stopped overthinking is which mascot will save us. None of them will. The query will. I would rather be wrong in a default I can hire for than right in a benchmark I cannot staff at 3 a.m. I have been right in the benchmark. I was still the person who got the page. The page does not care about the slide. It cares whether we picked something the team can still explain. If a candidate asks me “Postgres or MySQL,” I tell them which one we run and why we did not run a bake-off. If they want a holy war, they can have it in a comments thread. I want the explain plan. I want the restore drill. I want to go home. That is the 2026 version of the choice, and it is less exciting than the old one. Less exciting is how I know I finally stopped overthinking it.