Replication protects against a machine dying. It does nothing against a bad ALTER TABLE, an accidental DROP TABLE, or a bug that quietly corrupts data — those mistakes replicate just as faithfully as good data does. Backups are the only defense against mistakes, not just hardware failure.
Native BACKUP / RESTORE
ClickHouse has built-in SQL statements for this — no external tool required for the basic case:
BACKUP TABLE analytics.events
TO Disk('backups', 'events_2026_08_05.zip');
-- or straight to S3
BACKUP TABLE analytics.events
TO S3('https://my-bucket.s3.amazonaws.com/backups/events', 'key', 'secret');
RESTORE TABLE analytics.events
FROM Disk('backups', 'events_2026_08_05.zip');Because parts are immutable, a backup taken while a table is under active insert load doesn't need to freeze writes to get a consistent snapshot — it just references the parts that existed at that instant, the same property that makes concurrent reads safe without locking. Repeated backups of a slowly-changing table can also be meaningfully incremental, since unchanged parts don't need to be copied again.
Where most production setups actually land: clickhouse-backup
clickhouse-backup is a widely used community tool (not an official ClickHouse project) built on top of the same underlying mechanics, adding what the bare SQL statements don't: scheduled backups, retention policies, easier full-cluster/multi-table coordination, and simpler restore workflows across environments. Most teams running ClickHouse in production reach for it rather than scripting BACKUP statements themselves.
What backups don't cover on their own
- Table structure/DDL history — back up your migration scripts too, not just data, so a restored table's schema isn't a guess.
- Users, roles, and quotas — access control state generally needs its own backup path, separate from table data.
- Dictionaries and their external sources — a dictionary definition backs up fine, but the reference data it loads from lives elsewhere and needs its own plan.