MariaDB 13.0.2 Reaches General Availability, Adds DuckDB as a Storage Engine
The newest rolling series is production-ready. But MariaDB wants you to know it isn't an LTS, and to stay put if you care about long-term maintenance.
MariaDB Server 13.0.2 is now stable. The MariaDB Foundation posted its "now stable" notice on 17 September 2026, with the build itself dated two days earlier on 15 September. This is the latest point release in the 13.0 rolling series, which first showed up as a Preview back on 23 March.
Here's the thing worth getting straight before you plan any upgrade: 13.0 is not an LTS.
MariaDB draws a hard line here, and it matters if you're weighing a production move. Stable means maturity, the branch has run the full validation gauntlet and is clear for production. Rolling means update path. The 13.0 line ships on roughly a quarterly cadence and does not come with the long tail of an LTS series. So the guidance is blunt. Want slow upgrades and a long maintenance window? Stay on the 12.3 LTS line. Want the freshest SQL work and optimizer tweaks? Evaluate 13.0.
Keep in mind that MariaDB frames 13.0 as an evolution of 12.3 with "several entirely new features," not a rehash.
Descamps is also quick to temper expectations about the word "Stable" itself. "Stable does not mean that software has somehow reached perfection. Sadly, we still have no SQL statement for that: MAKE SERVER PERFECT," he wrote.
The announcement came from Frédéric Descamps, MariaDB's Director of Database Technology, and it quietly closes out a six-month arc from Preview to Release Candidate to Stable.
Between the Release Candidate and the final build alone, the 13.0 branch absorbed 604 more commits, changed 1,701 files, and added 23,748 test lines, of which 4,222 were actual test cases. All told, 335 MDEVs (Jira tickets) got closed out. There's also a round of security fixes bundled in, many reportedly caught through the HackerOne bug-bounty program. Full CVE details roll out incrementally across MariaDB's security docs and GitHub advisories, deliberately not turned into step-by-step exploitation guides.
That's a lot of test lines. For a database, coverage is honestly one of the better proxies for "will this survive Monday morning."
On the SQL side, the additions mostly make life easier for application code. You can now use REF CURSOR types inside package routines, RECORD types in parameters and return clauses, and reversed executable comments. There's also UPDATE ... RETURNING for single-table changes, which, paired with the new OLD_VALUE() function, lets an app read both the pre- and post-update values in a single round trip instead of bolting on a separate SELECT. Multi-table UPDATEs aren't supported yet, though.
Optimizer folks get QB_NAME(), a hint that lets you target nested query blocks directly. Every view, CTE, and derived table now gets an implicit name based on its alias, with a locator form for digging deeper.
The quiet operational stand-out is innodb_log_archive, a new global variable that keeps InnoDB's write-ahead log as a continuous stream of files instead of cycling through a ring buffer. That makes point-in-time recovery and incremental backups genuinely possible, flipped on at runtime with SET GLOBAL. But head here for the catch: mariadb-backup does not yet read the archive format and will fail against a server with it enabled, so manual PITR is the workaround for now.
Other tidbits include atomic CREATE OR REPLACE TABLE, a now-queryable init_rpl_role variable, configurable audit-plugin timestamp formats, and a PERFORMANCE_SCHEMA switch to the XXH3_128 hash, which looks like MD5 but runs much faster and plays nice in FIPS mode.
DuckDB, now a MariaDB storage engine
The feature hardest to look past is that MariaDB can now treat DuckDB as a pluggable storage engine, bringing columnar, vectorized analytical execution alongside InnoDB's transactional work, in-process, inside the same server.
It moved from alpha in June into gamma with 13.0.2, which is still early. Descamps framed it wryly, joking it isn't exactly a "ship it on a Friday afternoon" kind of thing, maybe Monday, at the earliest.
The engine ships as its own installable package. MariaDB-duckdb-engine 13.0.2 is out for RHEL 9 on x86_64, GPLv2-licensed, with DuckDB itself under MIT.
Create a table with ENGINE=DuckDB and its data lives in DuckDB's columnar format, with analytical queries run through DuckDB's multi-core engine right inside the MariaDB process. No separate cluster, no ETL pipeline, no new SQL dialect. You keep using the ordinary mariadb client, and InnoDB and DuckDB tables can sit side by side in the same database and be joined in a single statement.
MariaDB is careful to position it next to its older columnar engine, ColumnStore. ColumnStore is scale-out and multi-node. DuckDB is single-node, in-process, and "zero-ops," aimed at lightweight embedded analytics and HTAP.
The benchmarks are where this gets interesting. From Roman Nozdrin's June look, a full TPC-H SF10 run, roughly 11 GB, 86.6 million rows, 60 million in the lineitem table, ran end-to-end through DuckDB in about 4.3 seconds on an Intel i7-13700H with 20 threads and an 8 GB DuckDB memory cap.
Bulk loading those rows tells a starker story. Native parallel COPY through the run_in_duckdb() helper took about 33 seconds. Standard LOAD DATA LOCAL INFILE took roughly 400 seconds. That's about 12x slower, since every row gets serialized through MariaDB's SQL layer first.
A separate "airportdb" test (a 54.3 million-row booking table) put a cross-engine analytical join at 0.456 seconds on DuckDB versus 27.97 seconds on InnoDB. The stored data sat around 22x smaller, 333 MB of DuckDB against 7.2 GB of InnoDB, a 95.4% size cut, and exporting to Parquet via run_in_duckdb() produced a 703 MB file.
Those numbers are worth sitting with. They're vivid and they come from MariaDB's own testing, so keep them in the "impressive but verify your own workload" bucket.
The plugin approach is what makes this shipable without endangering the core. As Nozdrin put it, a storage engine plugin loads on demand behind well-defined interfaces, so it "can be added to a GA release without putting the stability of the core server at risk. If you don't load a plugin, nothing changes for you."
Descamps is equally clear-eyed about where DuckDB fits. "It won't replace InnoDB, and it may not replace ColumnStore either... Now we can have a sea lion that quacks… and exports Parquet too."
It's gamma, and it shows. No AUTO_INCREMENT. DuckDB tables need a PRIMARY KEY and reject non-UTF8 charsets. DECIMAL precision tops out at 38 digits. Several MariaDB functions like GROUP_CONCAT() and DATE_FORMAT() can't be pushed down yet and fall back to MariaDB's own execution. GROUP BY enforcement is stricter than MariaDB's default sql_mode. There's no XA transaction support, cross-engine external scans run single-threaded for now, and Parquet/Arrow reads plus DuckDB-specific syntax like FULL OUTER JOIN are only reachable through the run_in_duckdb() workaround rather than native parser support. A real parser is on the roadmap.
The engine's roadmap also calls for analytical GIS via the DuckDB Spatial extension, faster HTAP over InnoDB-only data through vectorized execution, partial query pushdown, and external data-lake access through DuckDB's extension ecosystem.
Head here for the download and here for the release notes.
If you're planning an upgrade and want the long haul, MariaDB still points you at the 12.3 LTS line. For the newest features, 13.0.2 is ready to go, just mind the gamma tags on the more experimental pieces like DuckDB before you put it anywhere near your most critical path.
