Improve Your Home Assistant Performance with MariaDB Tuning

Edit: Currently the best way to implement these changes is to follow this post: Improve Your Home Assistant Performance with MariaDB Tuning - #21 by jmrplens

Turbocharge Your Home Assistant with MariaDB Tuning

Over the past few months, I noticed that my Home Assistant instance was becoming slower over time. A few hours to days after restarting Home Assistant, I’d see delays in response times, especially when switching lights. I decided to investigate further and began monitoring the ping response times on my Shelly devices (flashed with ESPHome). To my surprise, these devices became increasingly unreliable over time, even though CPU usage and power draw on my host device remained stable, as you can see in the screenshot below:

Upgrading my RAM from 8GB to 32GB to reduce swap usage didn’t help, so I dove deeper and eventually found the culprit: MariaDB settings.

If you’re using the MariaDB add-on for your recorder, maybe you’ve encountered similar frustrations. In this guide, I’ll explain how to tune MariaDB to make the most of your hardware—and why it’s not as straightforward as you’d think.

A Word of Warning

I’m not a database expert—everything I’ve learned has been through trial and error with Home Assistant. Before you start, back up your database! While these changes shouldn’t corrupt your data, I’d rather be safe than sorry.

This guide assumes you’re using the MariaDB add-on and have at least an entry-level understanding of databases.

I also learned a lot from some topics on the forums/github, which I want to give a shout-out to:


Default MariaDB Settings: Tuned for Low-End Devices

The default MariaDB settings are designed for devices like the Raspberry Pi. Here’s an excerpt from the default mariadb-server.cnf:

port=3306
log_error=mariadb.err
	
# Persistent storage location
datadir=/data/databases
	
# Use a proper collation set
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
	
# Do not resolve DNS names
skip-name-resolve
	
# Tune for low-end devices (Like a Raspberry Pi)
key_buffer_size = 16M
max_connections = 64
myisam_recover_options = FORCE
myisam_sort_buffer_size = 8M
net_buffer_length = 16K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
sort_buffer_size = 512K
join_buffer_size = 128K
table_open_cache = 64
thread_cache_size = 8
thread_stack = 192K
tmp_table_size = 16M
	
# Disable query cache
query_cache_limit = 1M
query_cache_size = 0M
query_cache_type = 0
	
# InnoDB Tweaks
innodb_buffer_pool_size = 128M
innodb_log_buffer_size = 8M
innodb_log_file_size = 48M
max_binlog_size = 96M

These settings are not ideal for a more powerful setup, like my Intel NUC8 with an i5 CPU and 32GB of RAM, which can easily handle larger databases in memory.


Why Tuning is Tricky

While you can modify mariadb-server.cnf on disk, the MariaDB add-on reverts to its default settings on restart. Here’s why:

  1. Supervisor-Controlled Add-on:

    • The MariaDB add-on is managed by Home Assistant Supervisor. It’s built from a preconfigured Docker image, and changes to configuration files inside the container don’t persist across restarts.
  2. No Rebuild Option:

    • The ha addons rebuild command doesn’t work for image-based add-ons like MariaDB.
  3. Temporary Changes:

    • You can manually apply changes at runtime, but they will be lost on restart unless you use specific techniques (e.g., SQL commands).

How to Tune MariaDB Settings

Since persistent changes via mariadb-server.cnf aren’t feasible, we’ll focus on runtime changes using SQL commands. These changes are immediate but likely will need to be reapplied after each restart.
edit: I found that after a Home Assistant update, changes set through the phpMyAdmin variable editor do persist.

edit2: Changes to the MariaDB container only persist as long as the container itself is not restarted. So a Home Assistant restart will not remove the changes, but a complete host restart will. I recommend to use the mysql command custom integration suggested by @jmrplens to re-apply these changes on reboot.

Step 1: Accessing MariaDB

  1. Install and configure phpMyAdmin (available via the community add-ons store).
  2. Open the phpMyAdmin web interface.
  3. Log in with the credentials you set for the MariaDB add-on.
    Alternatively, connect via a MySQL client if you prefer the command line.

Step 2: Modify Runtime Variables

Use the following SQL commands to apply optimized settings:
Alternatively, you can go to the variables tab in the phpMyAdmin home page and edit these variables manually.

-- Set InnoDB Buffer Pool Size to 12 GB (12​884901888 bytes)
SET GLOBAL innodb_buffer_pool_size = 12 * 1024 * 1024 * 1024;

-- Set InnoDB Log Buffer Size to 8 MB (8388608 bytes)
SET GLOBAL innodb_log_buffer_size = 8 * 1024 * 1024;

-- Set Max Connections to 128
SET GLOBAL max_connections = 128;

-- Set Thread Cache Size to 32
SET GLOBAL thread_cache_size = 32;

-- Set Temporary Table Size to 256 MB (268435456 bytes)
SET GLOBAL tmp_table_size = 256 * 1024 * 1024;

-- Set Query Cache Size to 64 MB (67108864 bytes)
SET GLOBAL query_cache_size = 64 * 1024 * 1024;

-- Enable Query Cache
SET GLOBAL query_cache_type = 1;

Step 3: Verify Changes

To confirm your changes, run:

SHOW VARIABLES WHERE Variable_name IN (
    'innodb_buffer_pool_size',
    'innodb_log_buffer_size',
    'max_connections',
    'thread_cache_size',
    'tmp_table_size',
    'query_cache_size',
    'query_cache_type'
);

The Results

After applying these changes, I observed:

  1. Improved Performance:
    • Dashboards with multiple ApexCharts cards became significantly faster.
  2. Snappy Light Responses:
    • Light switching now happens almost instantly.
  3. Increased Memory Usage:
    • Host memory usage increased steadily, indicating that MariaDB was caching more data in memory.

Here’s a screenshot of my memory usage.


Final Thoughts

I hope this guide helps you optimize your Home Assistant setup. For those using the MariaDB add-on, tuning these settings can make a world of difference.

Suggestions for the Developers

It would be great if the MariaDB add-on provided predefined configuration profiles (e.g., Raspberry Pi, NUC, server) or exposed more settings in the UI for advanced users.

If you found this guide helpful or have suggestions to improve it, especially with advice on which additional settings to change or better suggestions of values, feel free to comment below!

3 Likes

Next month’s release has some significant improvements for larger MariaDB databases.

1 Like

What Tom said, and it will likely change many of your optimization numbers.

Will it work with HA add-on only or also with separate MariaDB instance (e.g. Synology package or docker installation on NAS)?

Any external MariaDB database.

1 Like

But particularly if you have 1000 or more entities.

1 Like

N.p. :slight_smile:

Do you have a quick overview of what the improvements will be?

1 Like

+1 For any link to view improvements

Some big improvements on my setup with occupancy related automations and page load times, thanks for sharing :+1:

If anyone knows if it’s possible to get these to survive a reboot then that would be ace.

Just installed 2025.1 and do not see anything related to database tuning in release blog. I checked HA log and it seems that there is some change DB in schema:

2025-01-04 09:21:27.393 WARNING (Recorder) [homeassistant.components.recorder.migration] The database is about to upgrade from schema version 47 to 48
2025-01-04 09:21:27.393 WARNING (Recorder) [homeassistant.components.recorder.migration] Upgrading recorder db schema to version 48
2025-01-04 09:21:27.414 WARNING (Recorder) [homeassistant.components.recorder.migration] Upgrade to version 48 done

but given the fact that it was completed in 0.021 sec I’m not sure if this is what you were referring to… Unless it is indeed only some DB parameters changing. I checked some data intensive dashboards, but to be honest I do not see any difference in loading times. Any verification method?

1 Like

I have been testing different options to execute the SQL commands at each boot and I have managed to make it work using the integration (HACS) GitHub - qrioniclabs/homeassistant-mysql_command: A Home Assistant custom component that creates a Notify service to send commands (e.g. INSERT) to a MySQL server.

After creating the entity notify, my automation looks like this (modify it to your needs):

alias: Configure MariaDB at startup
description: Configure MariaDB parameters after startup
triggers:
  - event: start
    trigger: homeassistant
actions:
  - delay:
      minutes: 1
  - data:
      message: SET GLOBAL innodb_buffer_pool_size = 8 * 1024 * 1024 * 1024;
    action: notify.mariadb_command
  - data:
      message: SET GLOBAL max_connections = 256;
    action: notify.mariadb_command
  - data:
      message: SET GLOBAL thread_cache_size = 32;
    action: notify.mariadb_command
  - data:
      message: SET GLOBAL tmp_table_size = 256 * 1024 * 1024;
    action: notify.mariadb_command
  - data:
      message: SET GLOBAL query_cache_size = 64 * 1024 * 1024;
    action: notify.mariadb_command
  - data:
      message: SET GLOBAL query_cache_type = 1;
    action: notify.mariadb_command
mode: single
1 Like

I have now also implemented this. I think this is the cleanest way of automatically setting these variables.

1 Like

I did these changes in phpmyadmin and like DrBlokmeister mentioned: The changes are carried through a restart and even through a update of HA. So no need to set these every time the system is restarted.

@DrBlokmeister Thanks for sharing these settings. My system is much snapier and the lights are blazing fast :smiley:

Changes do not persist after a restart (from the host, not from Home Assistant)

You can check it by going to developer tools->restart->advanced options->Restart System

If you restart the host, the configuration restarts, it is necessary to run the SQL commands again.

To confirm the above posts: the changes do not persist if the MariaDB container is restarted. This means that a Home Assistant restart itself will not affect your changes, but for example a host restart will.

1 Like

Thanks for explaining it :slight_smile:
And thanks @jmrplens for sharing the solution. I did setup it with your template and it is working like a charm :smiley:

1 Like

Check the latest version of mariadb addon 2.7.2. It has support for injecting parameters as arguments to mysqld. This version has been released today.
Here is an example how I improved mariadb to be used along with Nextcloud:

mariadb_server_args:
  - "--key_buffer_size=64M"
  - "--max_connections=200"
  - "--myisam_sort_buffer_size=16M"
  - "--net_buffer_length=32K"
  - "--read_buffer_size=512K"
  - "--read_rnd_buffer_size=1M"
  - "--sort_buffer_size=1M"
  - "--join_buffer_size=512K"
  - "--table_open_cache=200"
  - "--thread_cache_size=200"
  - "--thread_stack=256K"
  - "--tmp_table_size=64M"
  - "--innodb_buffer_pool_size=2G"
  - "--innodb_log_buffer_size=16M"
  - "--innodb_log_file_size=256M"
  - "--innodb_flush_log_at_trx_commit=2"
  - "--innodb_flush_method=O_DIRECT"
  - "--max_binlog_size=256M"
1 Like

I came to say the same thing, I haven’t tried it yet but it seems that it can finally be done.