Skip to main content

Tuning a database for the hardware it has

A freshly installed database ships with cautious, generic defaults. On a box you've sized deliberately (4 vCPU, 4 GiB RAM, SSD-backed disk), a little tuning goes a long way. The themes are the same across all three engines:

  • Let it use the RAM. Tell the engine how much memory it may use for caching data pages — the single biggest lever. (Postgres shared_buffers ~25% of RAM + a generous effective_cache_size; MariaDB and MySQL innodb_buffer_pool_size ~60%.)
  • Tell it the disk is an SSD. Defaults assume spinning rust. On SSD you lower the "random access is expensive" hints and raise the I/O concurrency the engine is willing to use (Postgres random_page_cost, effective_io_concurrency; MariaDB/MySQL innodb_io_capacity, innodb_flush_neighbors=0).
  • Right-size parallelism to the core count.
  • Turn on slow-query logging. A one-line setting that quietly becomes invaluable the first time something is slow — and, conveniently, those logs ship to Loki (next page).

Lesson learned (a real one): MariaDB and MySQL are not the same product — and running both, side by side, makes the gap concrete. The buffer pool is spelled the same on both, but the redo log isn't: MySQL 8 wants innodb_redo_log_capacity, while MariaDB wants innodb_log_file_size. Set the wrong one and the server refuses to start with a flat "unknown variable." There's a subtler trap on MySQL too: I dropped my overrides in a file named 99-tuning.cnf expecting it to win — but the include directory loads in filename order, and 99-… actually sorts before the packaged mysqld.cnf, which then quietly clobbered half my settings. Renaming it z99-tuning.cnf (so it genuinely loads last) fixed it. The lesson, both times: verify against your engine's docs and your config's load order — not the first answer for "the other" database.