Last updated: November 9 2024
In this article, I conduct original research into the performance of MySQL and MariaDB using Reserva, a custom benchmarking tool I created to simulate a high volume digital payments system.
MariaDB is 304% faster than MySQL in my most recent tests. Both systems are mature, modern, and reliable databases, but MariaDB is so much faster that I’d recommend using it unless you have a specific reason for using MySQL.
Reserva is a system I made to simulate a streamlined, high volume payments processing system. It is written in Go and supports arbitrary amounts of concurrency.
On start, Reserva loads all users and authentication tokens into memory, then attempts to make as many funds transfers as possible in a loop. Each funds transfer requires 4 round trips to the database and touches 6 tables. The workflow is as follows:
Reserva allows you to select whether or not you want deletes to be part of the workload. The results on this page do include deletes as part of the workload.
Let’s talk about the hardware, database versions, and configurations that were used to conduct this test.
I plan on running a lot of database benchmarks in the near future, and constantly paying for cloud services was starting to get expensive. So, I decided to purchase a few mini PCs and a networking switch to simulate a modern cloud environment.
Also, I like buying computer stuff 😃.
The mini PCs were 11th gen Intel NUCS. Specifically, they are:
I put the database servers on the computer with the i7 processor, because Reserva is less CPU intensive than the database programs it’s designed to test.
Both chips have 4 hyperthreaded cores for a total of 8 threads. This makes them comparable to an 8 vCPU VM that you might rent in the cloud. They also have a TDP of 28 watts, which I measured during load. In fact, these computers are well cooled and sometimes even surpass 28 watts!
I purchased high quality RAM and SSDs to get the most out of these mini PCs. They are both outfitted with:
It is well known that databases can become bottlenecked by slow disks, so I paid particular attention to my choice of SSD. The Samsung 990 Pro is, as far as I’m aware, one of the fastest PCIe 4 disks available on the market.
I initially conducted these tests using my M1 MacBook Air connected to one of the mini PCs via WiFi. However, I noticed right away how much that relatively poor connection slowed down the benchmark results. Over WiFi 6 with a strong connection, PostgreSQL was only able to complete 300-500 transfers per second. This was 30X slower than I eventually achieved!
So, I decided to go all in and buy another mini PC, plus:
This brought my network latency, as measured with ping, from several milliseconds down to around 0.65 milliseconds. This imperceptibly small difference in latency made a huge difference in my end test results. So, pay attention to networking, folks!
Here are a couple of comparable database servers with 8 vCPUs and 64 GB of RAM from AWS and Azure:
Before storage, it would cost about $846.72 per month to rent a similar machine on AWS.
Despite their size, these are powerful computers with resources that resemble a busy, production quality system.
Now, let’s discuss the databases used and how they were configured.
MySQL and MariaDB both use the InnoDB storage engine by default, and largely share the same config parameters.
The most important setting to change is the amount of RAM dedicated to buffers. Both databases recommends setting this to ~75% of RAM, so I set innodb_buffer_pool_size
to 48GB. I spent a lot of time messing around with other parameters, but none of them seemed to make an appreciable difference to the query throughput of my workload.
[mysqld] <OR> [mariadb]
innodb_buffer_pool_size = 48G
Next we run the DB preparation SQL scripts to create:
You can see the SQL setup scripts, along with the rest of the code, on Reserva’s Github page.
I ran Reserva with the following settings for both databases:
At the end of the test, I executed the following queries to show how many payments were made. The results of those queries are visualized below.
SELECT
hour(CREATED_AT) AS hour_created_at,
minute(CREATED_AT) AS minute_created_at,
COUNT(*) AS NUMBER_OF_TRANSFERS
FROM
transfers
GROUP BY
hour_created_at, minute_created_at
ORDER BY
hour_created_at, minute_created_at;
As you can see, MariaDB was quite a bit faster overall.
A few things to note:
I also aggregated the last hour of the test in a spreadsheet to create a simple “payments per second” bar chart, shown below. MariaDB is over 304% faster in the time frame that I selected.
MariaDB is significantly faster than MySQL in this particular use case, and I recommend using it if you can make that choice.