MariaDB Is Playing a Long Game, and It Might Be Winning

MariaDB vs MySQL in 2026 — what the Oracle acquisition changed, what MariaDB has been quietly building, and whether the fork is now the better choice.

Here's a story that I think about more than I probably should.

In 2010, Oracle acquired Sun Microsystems. Sun owned MySQL. The open source database community had a collective panic attack that lasted about four years. Oracle is a company whose entire business model is built on charging enterprise customers astronomical sums of money for database software. What were they going to do with the world's most popular open source database? Nothing good. The fear was real, the community was real, and the fork that came out of it – MariaDB – was absolutely the correct response.

Monty Widenius, one of the original MySQL creators (the "My" in MySQL is literally named after his daughter), forked the project and created MariaDB. That was 2009. Fifteen years later, MariaDB is on version 11.8 as its current long-term stable release, version 12.1 as its latest rolling release, and 12.2 and 12.3 sitting in preview. And the features it's been shipping are not the features of a project that's just trying to stay compatible with its upstream. These are the features of a database that's decided it wants to go somewhere.

Let me tell you what's been landing recently, and why some of it matters more than you'd expect.

First, The Version Numbering Situation

Before anything else, let me clarify where things stand because MariaDB's release cadence has changed and it's legitimately confusing.

  • MariaDB 11.8 — The current Long-Term Stable (LTS) release. This is what you run in production. Maintained for three years. The current stable patch is 11.8.6.
  • MariaDB 12.1 — The current rolling release. Stable, ships quarterly, gets dropped when 12.2 hits GA.
  • MariaDB 12.2 / 12.3 — In preview/RC as of writing. MariaDB 12.3, expected in Q2 2026, will be the next LTS release.

This matters because several of the features below landed in different versions across this chain. If you're on a managed hosting plan sitting on MariaDB 10.6 because your provider hasn't updated in three years... that's a separate conversation. Go have it with your provider.

Now. Features.

Oracle Compatibility Mode

This is either brilliant or cynical depending on how you look at it, and I think it's both.

Since MariaDB 10.3, the team has been incrementally adding Oracle SQL compatibility. Not "sort of similar" compatibility. Actual, intentional, targeted compatibility with Oracle's SQL dialect, because Oracle's SQL dialect diverges from ANSI SQL in ways that make migrating a real database off Oracle genuinely painful. MariaDB looked at that pain and said: what if we just... didn't make you feel that pain?

You flip it on with one command:

SET SQL_MODE='ORACLE';

That's it. From that point, MariaDB starts accepting Oracle SQL syntax. Things like calling stored procedures without the CALL keyword – which is normal Oracle, but MariaDB standard SQL requires it. You just write the procedure name and call it. MariaDB follows Oracle's lead.

The more recent and interesting addition came in MariaDB 12.0: single triggers can now fire on multiple DML events. So you can write one trigger that responds to INSERT, UPDATE, and DELETE. In Oracle SQL, this has always been possible. In MySQL-land you've always needed separate triggers for each event, which means more objects to manage, more places for logic to drift out of sync, more things to go wrong during migrations. MariaDB 12.0 fixed that.

And they built a migration tool. Not just documentation. An actual tool that takes your Oracle DDL export – your schema, your table definitions, your constraints – analyzes it, and tells you how well it'll run under MariaDB's Oracle compatibility mode before you commit to anything. You run the tool, you get a report, you know what you're walking into.

This is MariaDB saying, very clearly, to every DBA sitting on an Oracle license they resent paying for: we want your data. Come over. We've been making this easier for years. And they have. One version at a time. This is what patient, strategic development looks like.

Vector Support and MCP

Let me be honest about something. Every database vendor on the planet is adding "AI features" right now, and the vast majority of them are garbage. A badge on the website. A function that calls an external API you didn't need the database to call. Marketing dressed up as product.

MariaDB's AI additions are not that. Let me explain why.

The VECTOR Type (MariaDB 11.8)

MariaDB 11.8 added a native VECTOR data type. This is for storing embeddings – fixed-size arrays of floating-point numbers that encode semantic meaning in a form that can be compared mathematically. This is the foundational building block of AI-powered search, recommendation systems, and anything involving language model outputs.

Why does it matter that it's native? Because when the database understands the type, the database can optimize operations on it. You can build vector indexes. You can run similarity searches entirely inside the database query engine rather than loading data into application memory, doing the math there, and shipping results back. You're keeping the computation close to the data, which is almost always faster.

The use cases are real and practical. A support ticket system where you search by semantic meaning, not keyword. A product catalog where "show me things similar to this item" actually understands what similar means in context. A document store where you can ask natural-language questions and get results ranked by relevance, not just string matching. All of this becomes possible when your database has a VECTOR type with proper indexing.

This is not a toy. pgvector for PostgreSQL proved the market for this. MariaDB adding native vector support is them deciding they want that market too.

MCP Server Support

The Model Context Protocol – if you haven't run into it yet, you will – is an open standard that lets large language models talk to external tools in a standardized way. Think of it as USB-C for AI integrations. Instead of every AI application having to write custom code to connect to every data source, MCP gives you a standard plug.

MariaDB now ships its own MCP server components. What this means practically: you can wire up an LLM agent to your MariaDB instance and the model can query your data as part of its reasoning process. You ask the AI a question, the AI figures out it needs to look something up in your database, it queries MariaDB through the MCP interface, gets the results, incorporates them into its answer.

It also supports using embeddings – via OpenAI, Gemini, or open Hugging Face models – to run semantic searches directly against documents stored in MariaDB. Your database becomes a RAG (Retrieval-Augmented Generation) backend without requiring a separate vector store service.

Is every MariaDB user going to use this? No. But for the people who want to add AI capabilities to applications already built on MariaDB, this is the difference between "you need to add three new services to your infrastructure" and "you connect your existing database to your LLM pipeline and it works." That's not nothing.

JSON and MariaDB

NoSQL had its moment. The "everything is a document, schemas are for cowards" era of 2012-2018 produced some genuinely useful tools and some genuinely catastrophic production databases with no structure whatsoever. The pendulum has mostly swung back. What we actually want is a relational database with good JSON support – the best of both approaches, no theological commitment to either.

MariaDB's JSON implementation is solid and worth understanding in detail.

You have a JSON column type that accepts and automatically validates JSON text. You can slap a JSON_VALID CHECK constraint on it and the database will reject malformed JSON at write time, before it becomes your future problem. You can add constraints for specific key types:

CREATE TABLE movies (
    id INT PRIMARY KEY,
    name VARCHAR(255),
    attr JSON,
    CHECK (JSON_TYPE(JSON_QUERY(attr, '$.year')) = 'INTEGER')
);

Now year is always an integer, enforced at the database level, not pinky-promised in application code.

Querying is clean. Extract a value by key path:

SELECT id, name, JSON_QUERY(attr, '$.dates.release') AS release_year 
FROM movies;

Filter on nested values:

SELECT id, name 
FROM movies 
WHERE JSON_VALUE(attr, '$.dates.release') = 1981;

Here's the move that actually matters for performance: virtual columns and indexes. Instead of making the database parse JSON on every query, you can define a virtual column that maps to a key in the document:

ALTER TABLE movies 
ADD COLUMN release_year SMALLINT 
AS (JSON_VALUE(attr, '$.dates.release'));

CREATE INDEX idx_releaseyears ON movies(release_year);

Now release_year is a computed column that the database indexes. Your queries against the release year hit an index. They're fast. You got NoSQL's schema flexibility and SQL's index performance, in the same table.

And you don't have to pull data out to modify it. JSON_INSERT(), JSON_ARRAY_APPEND(), JSON_REMOVE() – these functions let you surgically modify JSON values in-place inside the database. No round trip. No "deserialize, modify, reserialize, write back." The database just does it.

Expanded Optimizer Hints

This one's aimed squarely at experienced database developers, and if you're not one yet, bookmark this section for later.

Query planners are impressive. MariaDB's optimizer has gotten genuinely good at figuring out the best way to execute a query. But "generally good" doesn't mean "perfect for your specific query on your specific data distribution." There are cases where you know something about your data that the statistics don't capture, and you want to override what the planner decided.

MariaDB 12.0 added new-style optimizer hints that let you do exactly this. The syntax uses inline comments with special delimiters so they're invisible to databases that don't understand them:

SELECT /*+ INDEX_MERGE(orders idx_user_id, idx_status) */ 
    * 
FROM orders 
WHERE user_id = 42 AND status = 'pending';

That INDEX_MERGE hint tells the planner: for this query, use exactly these indexes when scanning. No substitutions. You're overriding the optimizer's choice about which indexes to combine.

The practical use cases are real. A table with many indexes where the planner consistently chooses the wrong combination for a specific high-traffic query. A composite query where the statistics are stale and the planner is making wrong assumptions about selectivity. A query that ran fine for months and then started running wild after a data distribution shift.

The MAX_EXECUTION_TIME() hint is the one I'd hand to every developer who's ever had a rogue query kill a database at 2am. You can now annotate specific queries with a millisecond timeout:

SELECT /*+ MAX_EXECUTION_TIME(5000) */ 
    complex_aggregation 
FROM enormous_table 
GROUP BY many_columns;

If that query takes more than 5 seconds, MariaDB aborts it. It returns an error instead of sitting there eating CPU while everything else grinds to a halt. You use this for debugging wild queries. You use it as a safety net in application code for operations where you'd rather fail fast than tie up the connection pool.

One honest warning about optimizer hints: they're seductive and they're dangerous in equal measure. A hint that helps today can hurt next month when your data distribution changes and the plan you forced is no longer the right plan. Always run EXPLAIN before and after. Measure. Don't assume your intuition is right just because the hint makes the query feel faster in development.

The XMLTYPE Placeholder

MariaDB 12.3 added an XMLTYPE column type, and I'll be upfront: right now it doesn't do much. It accepts up to 4GB of text and lets you use the UPDATEXML function on it for selective replacement. It does not validate XML. It does not enforce a schema. It does not do most of the things that make an XML column type useful.

So why mention it?

Because it's a commitment. Adding a type to a database is not free – you're making a promise about the storage format, the wire protocol, the query parser, the type system. MariaDB added XMLTYPE specifically because Oracle's SQL has XMLTYPE and they're building toward feature parity in Oracle compatibility mode. The validation, the schema enforcement, the XQuery support – those are coming in future versions. The type exists now so that Oracle DDL exports that include XMLTYPE columns don't immediately fail, and so the future features have somewhere to land.

Is it a feature you'd use today? Probably not. Is it a signal about where MariaDB is headed on Oracle compatibility? Absolutely.

The Things That Are Still Missing

MariaDB has diverged from MySQL, which means the two databases have different strengths and different gaps. Let's be real about the gaps.

MySQL Resource Groups have been proposed in MariaDB's issue tracker since 2018. Still not implemented. Resource groups let you cap the CPU and I/O that specific connections or query types can consume. This matters for multi-tenant systems and systems where you need to ensure reporting queries don't starve transactional queries. MariaDB doesn't have this yet.

Binary JSON storage isn't compatible. MySQL stores JSON in a packed binary format that's faster to parse. MariaDB stores it as text. This means if you're running a MySQL replica of a MariaDB primary (or vice versa), JSON columns can cause replication problems. Speaking of replication...

Global Transaction IDs are not cross-compatible. MariaDB and MySQL implement GTIDs differently and incompatibly. You can use a MariaDB server as a replica of a MySQL primary – useful if you want to migrate from MySQL to MariaDB using replication as the mechanism. But you cannot go the other way. A MySQL server cannot replicate from a MariaDB primary. Keep this in mind when planning migrations.

These aren't dealbreakers, but they're real, and a MariaDB feature article that doesn't mention them is doing you a disservice.

So Who Is MariaDB Actually For Right Now?

Let me give you a straight answer rather than a vague "it depends."

  • MariaDB is the obvious choice if you're running an existing MySQL application and you want a drop-in replacement with a more active open source community and features MySQL hasn't shipped yet. The migration path is well-understood, replication lets you migrate with minimal downtime, and you get vector support, better JSON, and Oracle compatibility as bonuses.
  • MariaDB is worth serious evaluation if you're running Oracle and paying Oracle's pricing and you're willing to do the migration work. The Oracle compatibility mode is not magic – there will be things to fix – but the migration tool and years of targeted Oracle compatibility work make it a more realistic option than it was five years ago.
  • MariaDB is a natural fit if you're self-hosting on a VPS or dedicated server (especially European providers like Hetzner or OVH where MySQL isn't always the default). Many distributions and control panels default to MariaDB, and for most web applications – forums, CMS, e-commerce – it just works, it's fast, and you never think about it.
  • MariaDB might not be the right call if you need features MySQL has that MariaDB hasn't caught up on yet (resource groups being the main one), or if you're already deep in a PostgreSQL ecosystem and you're looking at this as a potential migration target. PostgreSQL has a decade head start on advanced features and MariaDB isn't catching PostgreSQL; it's catching MySQL and Oracle.

The Conclusion

MariaDB has been playing a long game since the day Monty forked MySQL and said "fine, we'll do our own thing." The Oracle compatibility mode, the vector type, the MCP server support, the expanded optimizer hints – none of these are features born from panic. These are features born from a roadmap. There's a clear strategy here: be the migration destination for people who are tired of Oracle's pricing, be competitive with MySQL for everyone else, and don't be left behind when AI infrastructure becomes table stakes for databases.

The latest long-term stable series is MariaDB 11.8, the current rolling release is MariaDB 12.1, and the current development releases are MariaDB 12.2 and MariaDB 12.3. That's a lot of active development for a database that people sometimes dismiss as "just a MySQL fork."

It hasn't been just a MySQL fork for years. The sooner you update your mental model of what MariaDB is, the better decisions you'll make about where it fits in your stack.

Go read the release notes. Run the migration tool against your Oracle schema just to see what comes back. Spin up an 11.8 instance and play with vector columns. The database you ignored because it sounded derivative might be the most interesting relational database story in the open source world right now.

And if nothing else: it's free, it's fast, and at least it's not Oracle.