NEW

Pulse 2025 Product Roundup: From Monitoring to AI-Native Control Plane

ClickHouse Disk Encryption at Rest: Setup Guide

ClickHouse provides encryption at rest through an encrypted virtual disk type that wraps an underlying physical disk. Data is encrypted as it lands on disk and decrypted on read using a configurable AES cipher. The feature integrates with the standard storage policy mechanism, so MergeTree tables opt in by selecting an encrypted policy at creation time. This guide covers the configuration layout, key management options, table setup, monitoring, and observed performance impact.

Configuration layout

Encryption configuration lives in a config file under /etc/clickhouse-server/config.d/, for example encrypted_storage.xml. It has two pieces: a <disks> block that defines a physical disk and an encrypted overlay, and a <policies> block that references the overlay.

<storage_configuration>
    <disks>
        <disk1>
            <type>local</type>
            <path>/data/clickhouse_encrypted/</path>
        </disk1>
        <encrypted_disk>
            <type>encrypted</type>
            <disk>disk1</disk>
            <path>encrypted/</path>
            <algorithm>AES_128_CTR</algorithm>
            <key_hex id="0">00112233445566778899aabbccddeeff</key_hex>
            <current_key_id>0</current_key_id>
        </encrypted_disk>
    </disks>
    <policies>
        <encrypted>
            <volumes>
                <encrypted_volume>
                    <disk>encrypted_disk</disk>
                </encrypted_volume>
            </volumes>
        </encrypted>
    </policies>
</storage_configuration>

The path inside encrypted_disk is relative to disk1. Data written through the encrypted disk lands at /data/clickhouse_encrypted/encrypted/.

Preparing the storage directory

Create the target directory and give the ClickHouse user ownership before restarting:

mkdir -p /data/clickhouse_encrypted
chown clickhouse:clickhouse /data/clickhouse_encrypted
systemctl restart clickhouse-server

Key management

Inline hexadecimal keys

The simplest option is embedding the key directly in the config with <key_hex id="N">. The id attribute supports rotation: add a new key with a new id, set <current_key_id> to the new value, and existing data still decrypts using the older key while new writes use the current one.

<key_hex id="0">00112233445566778899aabbccddeeff</key_hex>
<key_hex id="1">ffeeddccbbaa99887766554433221100</key_hex>
<current_key_id>1</current_key_id>

Environment variables

Storing keys in the config file ships them with backups. Reading from the environment keeps the key out of config:

<key_hex from_env="DiskKey"/>

Set the variable in /etc/default/clickhouse-server:

DiskKey=00112233445566778899aabbccddeeff

Restart clickhouse-server for the variable to be picked up.

Creating an encrypted table

Bind a MergeTree table to the encrypted policy with storage_policy:

CREATE TABLE bench_encrypted
(
    c_int Int64,
    c_str varchar(255),
    c_float Float64
)
ENGINE = MergeTree
ORDER BY c_int
SETTINGS storage_policy = 'encrypted';

All parts written for this table are encrypted on disk. The catalog, system tables, and logs are not affected, so plan separately for protecting those if your threat model requires it.

Verifying encryption is active

Query system.disks to see which disks report as encrypted:

SELECT name, path, type, is_encrypted
FROM system.disks;

Inspect storage policies and their volumes:

SELECT *
FROM system.storage_policies;

For a single table, check the policy column in system.tables:

SELECT name, storage_policy
FROM system.tables
WHERE database = 'default' AND name = 'bench_encrypted';

Performance impact

Benchmarks with 100M rows show small overhead for writes and a single-digit percentage hit on reads:

Operation Observation
Bulk insert Comparable to unencrypted
Single-threaded SELECT Roughly 6 to 9 percent slower
Mixed read workload Around 10 to 15 percent slower due to decryption

Decryption happens per granule on read paths, so workloads dominated by primary-key lookups and partition pruning see less overhead than full scans.

Common Pitfalls

  • Storing the key in the same place as backups. Encrypting data with a key sitting next to the backup defeats the purpose. Use from_env or an external secret store.
  • Forgetting current_key_id after adding a new key. Reads will still work, but new writes continue using the previous key.
  • Mismatched key length and algorithm. AES_128_CTR expects a 16-byte (32 hex char) key; AES_256_CTR expects 32 bytes (64 hex char). The server refuses to start on mismatch.
  • Permissions on the underlying path. Without chown clickhouse:clickhouse, the server cannot write through to the wrapped disk.
  • Expecting in-memory data to be encrypted. Encryption applies only to data at rest. Logs, caches, and the query path operate on plaintext.
  • Mixing encrypted and unencrypted volumes inside one policy without understanding tier behavior. Parts move between volumes by storage policy rules and may end up unencrypted on the wrong tier.

Frequently Asked Questions

Q: Which algorithms are supported? A: AES in CTR mode, with 128, 192, or 256 bit keys (AES_128_CTR, AES_192_CTR, AES_256_CTR). Key length must match the algorithm.

Q: Can I encrypt an existing table? A: Not in place. Create a new table with the encrypted policy and copy data with INSERT INTO new SELECT * FROM old, then swap names with RENAME TABLE.

Q: Does encryption protect logs and system tables? A: Only if those paths sit on an encrypted disk too. Configure system_log storage policies and the server log directory accordingly.

Q: How do I rotate keys without re-encrypting existing data? A: Add a new <key_hex> with a higher id, then update <current_key_id>. New parts use the new key, existing parts continue using their original key id stored in part metadata.

Q: Does encryption affect replication? A: No. Replication transfers parts as bytes; the receiving replica decrypts and re-encrypts under its own configured key. Both replicas need their own encryption configured.

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.