Configure ClickHouse® for low memory environments
While Clickhouse® it’s typically deployed on powerful servers with ample memory and CPU, it can be deployed in resource-constrained environments like a Raspberry Pi. Whether you’re working on edge computing, IoT data collection, or simply experimenting with ClickHouse in a small-scale setup, running it efficiently on low-memory hardware can be a rewarding challenge.
TLDR;
Some interesting settings to explain:
- Disabling both postgres/mysql interfaces will release some CPU/memory resources.
- Disabling some system tables like
processor_profile_log
,opentelemetry_span_log
, orquery_thread_log
will help reducing write amplification. Those tables write a lot of data very frequently. In a Raspi4 with 4 GB of RAM and a simple USB3.1 storage they can spend some needed resources. - Decrease mark caches. Defaults are 5GB and they are loaded into RAM (in newer versions this behavior of loading them completely in RAM can be tuned with a prewarm setting https://github.com/ClickHouse/ClickHouse/pull/71053 ) so better to reserve a reasonable amount of space in line with the total amount of RAM. For example for 4/8GB 256MB is a good value.
- Tune server memory and leave 25% for OS ops (
max_server_memory_usage_to_ram_ratio
) - Tune the thread pools and queues for merges and mutations:
merge_max_block_size
will reduce the number of rows per block when merging. Default is 8192 and this will reduce the memory usage of merges.- The
number_of_free_entries_in_pool
settings are very nice to tune how much concurrent merges are allowed in the queue. When there is less than specified number of free entries in pool , start to lower maximum size of merge to process (or to put in queue) or do not execute part mutations to leave free threads for regular merges . This is to allow small merges to process - not filling the pool with long running merges or multiple mutations. You can check clickhouse documentation to get more insights.
- Reduce the background pools and be conservative. In a Raspi4 with 4 cores and 4 GB or ram, background pool should be not bigger than the number of cores and even less if possible.
- Tune some profile settings to enable disk spilling (
max_bytes_before_external_group_by
andmax_bytes_before_external_sort
) and reduce the number of threads per query plus enable queuing of queries (queue_max_wait_ms
) if themax_concurrent_queries
limit is exceeded.