Skip to content

Data

MySQL

The database that quietly powers most of the web, run by engineers who understand its replication and its limits.

Overview

MySQL is the world’s most widely deployed open-source relational database, and it earned that position the hard way — by being the database behind an enormous slice of the web for the best part of three decades. It is the M in the LAMP stack (Linux, Apache, MySQL, PHP), the storage layer under WordPress, Magento and countless PHP applications, and the default a great many hosting providers hand you the moment you sign up. When people talk about MySQL’s ubiquity they are not exaggerating: the talent pool, the tooling, the tutorials and the operational knowledge around it are deeper than for almost any other database, and that depth is a genuine engineering asset, not a marketing line.

Under the surface, modern MySQL is built on the InnoDB storage engine, which gives it the things a serious application database needs: full ACID transactions, row-level locking so concurrent writes do not trip over each other, foreign keys, and crash recovery. Its source-replica replication is battle-tested at a scale few other systems have matched, and it is a large part of why MySQL scales reads so well — you point your read traffic at replicas and let the source handle writes. It reads fast, it is well understood, and its failure modes are documented by millions of engineers who hit them before you did.

We should be straight about the politics, because they matter to a long-lived system. MySQL is stewarded by Oracle, which acquired it through Sun in 2010. That ownership prompted the original authors to fork the project into MariaDB, a drop-in-compatible alternative that some teams prefer specifically to keep their database out of Oracle’s hands. For a brand-new project with no existing MySQL estate, we will often recommend PostgreSQL instead — it is stronger on advanced SQL, JSON, extensions and strict standards compliance — and we say so plainly on this page. But that recommendation is not universal, and where MySQL is the right answer, it is emphatically the right answer.

Best for — Teams running existing LAMP, WordPress or PHP estates, and read-heavy web applications where MySQL’s ubiquity, fast reads and proven replication pay off — staffed by engineers who know when it is the right database and when PostgreSQL is not.

Why teams choose MySQL

  • Ubiquity that lowers the cost of running it

    MySQL is everywhere — in hosting, in tooling, in the knowledge of nearly every backend developer alive. That ubiquity is a practical benefit: you can hire for it, host it cheaply, and find that whatever operational problem you hit has been solved and documented many times over. For a system you have to run for years, a deep talent pool and mature tooling are worth more than a feature checklist.

  • Fast reads and proven replication

    MySQL is quick at the read-heavy work most web applications actually do, and its source-replica replication is as battle-tested as anything in the database world. When traffic grows, you add read replicas and route lookups to them — a well-worn, well-understood scaling path that keeps your write source uncluttered and your read latency low.

  • The default under a huge share of the web

    WordPress, Magento and a vast body of PHP software assume MySQL, which means the plugins, themes and integrations you rely on are tested against it every day. If your product lives in that world, MySQL is not a compromise — it is the substrate the whole ecosystem is built and validated on, and going against the grain buys you problems, not benefits.

Why businesses choose MySQL

  • You already run MySQL — a LAMP stack, a WordPress or Magento estate, PHP applications built around it — and replacing a working, well-understood database would cost far more than it returns.
  • Your workload is read-heavy web traffic that scales naturally across replicas, so MySQL’s fast reads and proven replication play directly to its strengths.
  • Your team is already fluent in MySQL, and you value a large hiring pool and a deep well of operational knowledge over the advanced feature set of a less common database.
  • You want an honest steer: if a greenfield data model would be better served by PostgreSQL, we will say so — and if MySQL is genuinely the right call, we will back it without hedging.

What we build with MySQL

The capabilities this technology is genuinely strong at — and what we most often build with it.

  • The InnoDB storage engine

    InnoDB is what makes MySQL a serious application database rather than a flat store. It provides ACID transactions, row-level locking so concurrent writes do not block one another unnecessarily, foreign-key constraints, and crash recovery through its redo log. It is the default engine for good reason, and we configure it deliberately — buffer pool sizing, isolation levels, flush behaviour — because those settings are where real MySQL performance and durability are won or lost.

  • Source-replica replication

    MySQL’s replication is among the most battle-tested in the industry: a source server streams its changes to one or more replicas, which you use to spread read load, run backups without touching the source, and stand ready for failover. We design the topology to match the workload — how many replicas, how you route reads, how you handle replication lag — because replication is powerful but not free, and lag is a real behaviour you plan for rather than discover in production.

  • Strict SQL mode and data integrity controls

    MySQL’s reputation for laxness comes largely from permissive historical defaults. Modern MySQL can be strict — rejecting invalid values rather than silently truncating them — and we insist on it. We configure strict SQL mode, define proper constraints and foreign keys, and choose column types that reflect the data honestly, so the database enforces correctness instead of quietly accepting rubbish.

  • Mature indexing and the query optimiser

    MySQL’s B-tree indexing, covering indexes and composite indexes are the difference between a query that returns in a millisecond and one that scans a whole table. We read EXPLAIN output rather than guessing, design indexes around the queries that actually run, and are disciplined about not over-indexing, because every index is a cost on every write as well as a saving on reads.

  • Character sets and utf8mb4

    MySQL’s history includes a genuinely dangerous trap: the old “utf8” character set only stored three bytes and could not hold emoji or some characters, corrupting data silently. We use utf8mb4 as a matter of course, set collations deliberately, and treat character-set configuration as a correctness issue rather than an afterthought — because getting it wrong is the kind of bug that surfaces years later in someone’s name.

  • JSON columns, with realistic expectations

    MySQL does support a native JSON type and functions for querying into it, which is useful for genuinely semi-structured fields. We use it where it fits, but we are honest that MySQL’s JSON tooling is thinner than PostgreSQL’s jsonb, so if a data model is heavily document-shaped we will question whether a relational database is the right home for it at all rather than bending MySQL around the problem.

Use cases

  • WordPress, Magento and PHP estates

    The content sites, e-commerce stores and PHP applications that assume MySQL by default — where the plugins, themes and integrations are all tested against it and going elsewhere buys nothing but friction.

  • Read-heavy web application back ends

    Product back ends and APIs whose traffic is dominated by lookups and page renders, scaled by routing reads to replicas while the source handles the comparatively lighter write load.

  • LAMP-stack line-of-business software

    Internal tools, portals and back-office systems built on the Linux/Apache/MySQL/PHP stack, where the maturity, cheap hosting and broad familiarity of MySQL keep the total cost of ownership down.

  • Migrations, upgrades and rescues

    Existing MySQL databases that need version upgrades, schema cleanup, replication rebuilt, or performance recovered — work where deep familiarity with MySQL’s real behaviour matters more than any feature list.

When MySQL is the right choice

  • Right when you already run a LAMP or WordPress estate — an existing MySQL database, PHP applications, plugins and hosting all built around it. Ripping out a working, well-understood MySQL is rarely worth the disruption, and the ecosystem around it is a real advantage.
  • Right for read-heavy web applications where the workload is dominated by lookups and page renders rather than complex analytical queries. MySQL’s fast reads and mature source-replica replication are exactly built for spreading that load across replicas.
  • Right when your team — or the developers who will inherit the system — are already fluent in MySQL. Its ubiquity means you can hire for it easily and lean on an enormous body of operational knowledge, which lowers the long-term cost of running it.
  • Wrong for greenfield projects where you have a free choice and a data model that leans on advanced SQL, rich JSON handling, or extensions. For that we usually reach for PostgreSQL, and we will tell you so rather than default to MySQL out of habit.
  • Wrong for document storage, caching, or heavy analytics. MySQL is a general-purpose relational database; a document store, an in-memory cache such as Redis, or a columnar analytics engine will each beat it decisively at its own job, and we would use the right tool rather than force MySQL into a role it was never meant for.

MySQL: pros and cons

Strengths

  • Unmatched ubiquity: the deepest talent pool, the widest hosting support and the largest body of operational knowledge of any open-source database — hiring and running it are both cheap and easy.
  • Genuinely fast reads and mature, battle-tested source-replica replication that makes scaling read-heavy web workloads a well-understood exercise rather than a research project.
  • InnoDB gives you the serious fundamentals — ACID transactions, row-level locking, foreign keys and crash recovery — so it holds up as a real application database, not just a simple data dump.
  • The default for WordPress, Magento and the wider LAMP world, so the ecosystem of plugins, themes and integrations is tested against it continuously and works out of the box.

Trade-offs

  • Fewer advanced features than PostgreSQL: weaker support for advanced SQL, window functions historically arrived late, JSON handling is thinner, and there is no comparable ecosystem of powerful extensions. For a greenfield project we often prefer Postgres for exactly these reasons.
  • A history of laxness with data integrity — permissive defaults, silent truncation of invalid values in older or misconfigured setups, and looser standards compliance — which means the database will let bad data through unless you configure strict mode and constraints deliberately.
  • Oracle’s stewardship is a genuine concern for some teams and is the reason the original authors forked the project into MariaDB. If long-term open governance matters to you, that ownership question is worth weighing before you commit.
  • It is the wrong tool for document storage, caching, or heavy analytics — a document store, Redis, or a columnar analytics engine will each outclass MySQL at its own workload, and forcing MySQL into those roles is a false economy.

Architecture

A MySQL architecture is a set of deliberate choices, not a default you accept. The first is the storage engine: we use InnoDB for anything transactional, because its row-level locking and ACID guarantees are what let a real application run safely under concurrent load. On top of that we design the schema properly — sensible normalisation, honest column types, foreign keys and constraints that make the database enforce correctness rather than trusting the application to. MySQL will happily let a loose schema through, so the discipline has to come from the people designing it.

The second set of choices is topology. A single MySQL instance is fine until it is not; the well-worn path from there is a source with one or more read replicas, reads routed to the replicas and writes to the source. We plan that topology against the actual workload — how read-heavy it is, how much replication lag the application can tolerate, how failover happens when the source dies — rather than bolting replication on in a panic later. Backups, point-in-time recovery and a tested restore procedure are part of the architecture from the start, because a database you cannot reliably restore is a liability wearing the costume of an asset.

Performance

MySQL is fast at reads, and most of the performance work on a MySQL system is about staying out of its way. The two levers that matter most are indexing and the InnoDB buffer pool. We design indexes around the queries that actually run — reading EXPLAIN output rather than guessing — and size the buffer pool so the working set lives in memory instead of thrashing the disk. Most “MySQL is slow” complaints trace back to a missing index, a query doing a full table scan, or a buffer pool starved of RAM, not to any limit of the database itself.

The other common culprit is the application, not the database: N+1 query patterns, queries pulling far more data than they use, and work done synchronously that belongs in a background job. We profile with the slow query log and EXPLAIN before we change anything, fix the queries that dominate the load, and push read traffic onto replicas when a single source can no longer serve it comfortably. Where a workload is genuinely analytical — heavy aggregations across huge tables — we are honest that MySQL is the wrong engine for it, and the right move is a purpose-built analytics store rather than heroics on the transactional database.

Security

MySQL security starts with the boundary between the application and the database. The database should never be reachable from the public internet, connections should be encrypted with TLS, and application accounts should hold the least privilege that lets them do their job — not the root credentials that so many quick setups leave in place. We remove default and anonymous accounts, set real passwords, and separate the account the application uses from the account used for administration, so a compromised application cannot drop your schema.

The most common route into a MySQL-backed application is SQL injection, and the defence is not clever — it is parameterised queries, everywhere, without exception, so user input is never concatenated into SQL. Beyond that we enforce strict SQL mode so bad data is rejected rather than silently mangled, keep the server patched against known CVEs, encrypt data at rest and in transit where the data warrants it, and make sure backups are both encrypted and access-controlled. Security here is unglamorous and mostly about doing the ordinary things properly and consistently.

Scalability

MySQL scales reads gracefully and writes with more effort, and being honest about that asymmetry is the whole game. Read scaling is a solved problem: add replicas, route reads to them, and accept a small amount of replication lag as the price. For the read-heavy web workloads MySQL suits, this carries you a very long way on well-understood, boring infrastructure — which is exactly what you want from a database you have to run for years.

Write scaling is harder, because a single source can only absorb so much. Before reaching for sharding — which is a genuine step-change in complexity that partitions your data across multiple sources and complicates every query that crosses a shard — we exhaust the cheaper options: better indexing, moving hot read traffic onto a cache such as Redis so it never touches MySQL, archiving cold data, and tuning InnoDB. We treat sharding as a decision with real, lasting costs, not a default, and we will tell you plainly when a workload has outgrown what a single MySQL source should reasonably be asked to do.

MySQL integrations & ecosystem

The technologies we most often pair with it — each links to how we work with it.

How we work

We start with the data model and the workload, because those two things decide everything else about a MySQL system. We design the schema with honest types and real constraints, turn on strict SQL mode, and index around the queries that will actually run rather than the ones we imagine might. From the outset we treat backups and a tested restore as part of the build, not a chore for later, because the difference between a database and a disaster is whether you have ever proven you can bring it back.

The engineers who design your MySQL setup are the ones who run it afterwards — that is what we mean by operating what we build. The person choosing the replication topology is the person who will get paged when a replica falls behind, which is exactly the right incentive for keeping it simple and well understood. We favour boring, legible schemas over clever ones, tune InnoDB and indexing based on real profiling rather than folklore, and hand you a database your own team can operate without us on the phone.

The service behind it

Delivered throughData Engineering

What we build with MySQL

The disciplines this technology most often shows up in — from a first build to taking over and stabilising an existing one.

How we deliver

  1. 01

    Discover

    We map the system, the constraints and the business it serves — including the parts nobody documented.

    Architecture brief

  2. 02

    Architect

    Decisions get made, written down and defended before a line of production code exists.

    Decision records

  3. 03

    Build

    Short cycles against working software. You see progress in the product, not in a status deck.

    Shipping increments

  4. 04

    Operate

    Monitoring, incident response and iteration. The system is alive, so the engagement is too.

    Runbooks & SLOs

Industries we use MySQL in

Domain knowledge changes what gets built. A few of the sectors we know before the first meeting.

Also in Data

Why teams choose us for MySQL

  • Senior engineers only

    MySQL rewards judgement — knowing when to add a replica, when strict mode matters, when a query needs an index and when it needs rewriting. The people working on your database have run MySQL in production for years; there are no juniors learning replication on your system.

  • We operate what we build

    We run the MySQL systems we ship, so we optimise for the operational reality: tested backups, understood replication, deliberate indexing and a database your team can actually maintain rather than one that only we can decode.

  • Honest about MySQL versus PostgreSQL

    If your project is greenfield and would be better served by PostgreSQL’s advanced features, we will tell you before you commit. And where MySQL is genuinely the right call — an existing estate, a read-heavy web app — we will back it without hedging.

  • Right tool for the workload

    We will not force MySQL to be a document store, a cache or an analytics engine. Where a workload calls for Redis, a document database or a columnar store, we say so and design the system to use each tool for what it is genuinely good at.

Typical timeline

  1. 01

    Discovery and data modelling

    One to two weeks understanding the workload, the read/write balance and the integrations, and designing a schema with honest types, real constraints and strict mode from the start.

  2. 02

    Build and first slice

    Two to three weeks standing up the database, wiring the application against it with parameterised queries, and proving the schema and indexing against realistic data rather than a handful of rows.

  3. 03

    Replication and hardening

    Setting up source-replica replication where the workload needs it, tuning InnoDB and indexes against profiled load, and putting encrypted, tested backups and least-privilege accounts in place.

  4. 04

    Handover and operations

    Documenting the topology, the restore procedure and the tuning decisions so your team can run the database confidently, with us available if a genuinely hard problem lands.

How pricing works

  • Fixed-scope database work for well-defined needs — a schema design, a replication setup, a version upgrade, a migration onto or off MySQL — quoted once we understand the data and the workload.
  • Monthly senior engagement for ongoing work where MySQL sits inside a wider application build, and you want continuity and someone who operates the database rather than just standing it up.
  • Focused audits and rescues for existing MySQL estates — slow queries, replication lag, data-integrity problems, an upgrade that stalled — priced by the assessment.

Hire MySQL engineers

Need MySQL capacity on your own team? We embed named senior engineers into your existing team — reporting to your leads, working in your rituals — so you add capacity without a hiring cycle.

Hire MySQL engineers

Common questions

Should we use MySQL or PostgreSQL for a new project?

For a genuine greenfield project where you have a free choice, we usually lean towards PostgreSQL. It is stronger on advanced SQL, has richer JSON support through jsonb, a deep ecosystem of extensions, and stricter standards compliance out of the box. MySQL becomes the right answer when you already run it — a LAMP or WordPress estate — when your workload is read-heavy web traffic that scales cleanly across replicas, or when your team is fluent in it and you value the enormous hiring pool. We make the call on your specifics rather than defaulting either way.

What is the difference between MySQL and MariaDB?

MariaDB is a fork of MySQL, started by MySQL’s original authors after Oracle acquired the project, and designed to be largely drop-in compatible. Teams choose MariaDB mainly to keep their database under open, community governance rather than Oracle’s stewardship. In day-to-day use they are very similar, though the two have diverged over the years in some features and internals. We are comfortable with both and will help you weigh which fits your priorities — the governance question is a legitimate reason to consider MariaDB, but it is not the only factor.

Is MySQL’s reputation for poor data integrity still deserved?

It comes from genuinely permissive historical defaults — older setups would silently truncate or coerce invalid values rather than reject them. Modern MySQL can be strict, and we insist on it: strict SQL mode turned on, proper constraints and foreign keys defined, and honest column types chosen so the database enforces correctness rather than quietly accepting bad data. The reputation was earned, but a well-configured modern MySQL does not deserve it. The failures come from lax configuration, not from the database being incapable.

How does MySQL handle scaling when our traffic grows?

Reads scale gracefully: you add read replicas and route lookups to them while the source handles writes, which is a mature, well-understood path that suits the read-heavy web workloads MySQL is built for. Writes are harder, because a single source has a ceiling. Before reaching for sharding — which is a real step-change in complexity — we exhaust cheaper options: better indexing, caching hot reads in Redis so they never touch the database, archiving cold data, and tuning InnoDB. We will tell you honestly when a workload has genuinely outgrown a single source.

Can we run analytics or store documents in MySQL?

You can, but for anything serious you should not. MySQL is a general-purpose relational database optimised for transactional web workloads. Heavy analytics — large aggregations across huge tables — belong in a columnar analytics engine that will outperform it dramatically. Document-shaped data belongs in a document store or, if it is only mildly semi-structured, in PostgreSQL’s jsonb rather than MySQL’s thinner JSON tooling. And caching belongs in Redis. We would use MySQL for what it is excellent at and pair it with the right tool for the rest, rather than forcing it into a role it was never built for.

Building on MySQL?

A technical conversation with the engineers who would do the work. If we are not the right fit, we will say so on the call.

Two fields required. We reply to real enquiries — no list, no sequence.