Updating and deleting data in ClickHouse

ClickHouse is built for append-heavy analytics, so changing rows costs more than in a transactional database. This page explains which method fits each correction pattern, what each costs on large tables, and how to plan it.

On this page

Updating and deleting data in ClickHouse: which method fits your corrections

Choose the method by how often you correct data and how many rows each correction touches. A few corrections a day across a small slice of a large table point toward lightweight UPDATE and DELETE. Regular corrections that rewrite a whole time range, such as reprocessed or re-keyed records, point toward ALTER mutations or partition drops, which remove or replace whole partitions in one operation. Frequent upserts of the same entity usually belong in a ReplacingMergeTree design rather than in row-level edits. Teams need any of this only when source systems send late corrections, duplicates or deletion requests that must reach analytical history, because most event and telemetry data is append-only by nature.

The reason these choices differ from an OLTP database is storage layout. ClickHouse keeps each column in separate files, organizes data into immutable parts, and merges parts in the background. An in-place change does not overwrite a row. It is recorded and applied later, so the cost of a change depends on how much data must be rewritten and when the merges run. This is why a DELETE on a large table can look instant to a query while the underlying data still exists until merges or mutations complete. Before you choose, confirm with your ClickHouse version's documentation how each statement is applied, whether it is visible to queries immediately, and how it interacts with replicas and backups.

Test the chosen pattern on a copy of production-sized data before it runs against live tables. Measure the rows and parts a correction touches, how long until queries stop seeing old values, and whether the same statement is safe to rerun after a failure. Also confirm how the correction is handled by ClickHouse replication, and make sure your backup schedule covers the window in which a mistaken delete could be applied. Your team should record which method applies to which kind of correction, so that routine fixes do not default to an expensive mutation.

How each update and delete method works

Lightweight DELETE and UPDATE statements mark affected rows with a mask so that later queries skip them, instead of rewriting every data part when the statement runs. Masked rows stop appearing in SELECT results once the statement completes, but their bytes stay on disk until background merges process the affected parts. Storage is reclaimed on a merge schedule, which is why disk usage can stay flat right after a large delete.

  • Visibility: Affected rows disappear from subsequent queries once the statement finishes, so application reads see the correction quickly.
  • Physical removal: Disk space is recovered only when merges rewrite the affected parts, so do not expect an immediate drop in storage.
  • Engine and type support: Confirm which table engines and column types accept lightweight operations in your version, since support varies across MergeTree variants.
  • Cost on large tables: Work grows with the number of parts and the volume of data the predicate touches, so measure a broad filter on a copy before running it in production.
  • Replicas and backups: Confirm how the statement propagates across replicas and what a backup taken while merges are pending will contain.

Check the documented limitations, supported engines and any mask-related settings for your version in the ClickHouse production FAQ and the current release notes before you write a runbook around these statements.

Which method to use for which correction

This table compares five ways to change or remove rows in self-managed ClickHouse by scope, visibility to queries, write and rewrite cost, and typical use. Read each row to see when a correction appears to the next query and when the work lands in background merges. The main takeaway is that row-level erasure, field-level fixes and late-arriving corrections have different costs, so match the method to the unit of change.

MethodScope and visibilityWrite and rewrite costTypical use
Lightweight DELETEIndividual matching rows, hidden from later queries once the statement completes; physical removal waits for mergesLow at statement time; deleted rows stay on disk until merges runRemoving a small set of bad rows or single-subject erasure requests in recent data
Lightweight UPDATESpecific column values on matching rows, visible to subsequent queriesLow to moderate; depends on release and storage behavior, so confirm for your versionCorrecting a few fields on known rows, such as a status or misclassified label
ALTER TABLE mutationsAny rows matching a predicate across all parts; changes appear part by part as rewrites finishHigh; rewrites affected parts in the background and competes with reads and insertsBulk corrections or erasure across older data where lightweight options are impractical
ReplacingMergeTree with version columnNewest row version wins per sorting key; duplicates collapse during merges, so queries need FINAL or equivalentWrites are plain inserts; reads pay deduplication cost until merges catch upFrequent or late corrections to records identified by a stable key
Partition dropWhole partition at once, so the partition key must match the unit of removalLow; removes data by dropping parts with no row-level rewriteRetention cleanup, or replacing a full day or month after a bad load

What makes updates and deletes expensive on large tables

Mutations in ClickHouse rewrite data parts, so their cost follows how much stored data they touch, not how many rows the statement changes. An ALTER TABLE ... UPDATE or ALTER TABLE ... DELETE mutation finds every data part that contains matching rows and writes new versions of those parts without the old values. A single corrected row in a part holding millions of rows still forces the whole part to be rewritten. This is why the cost grows with table size and with how widely the affected rows are spread across partitions and parts. A correction that falls into one recent partition is a very different job from one that matches a few rows in every partition of a multi-year table.

The ordering key and the partitioning key decide how much data a mutation has to read and rewrite. When the WHERE clause of a mutation uses columns that lead the ORDER BY key or the partition key, ClickHouse can narrow the work to fewer parts. When the filter uses a column outside both keys, the mutation scans broadly and touches parts that contain no matching rows at all. Before running a large correction, check the table's ORDER BY and PARTITION BY definitions against the predicate you plan to use, and confirm the expected scope with a SELECT count() over the same filter, grouped by partition. Those two checks tell you more about cost than any general rule. Mutations also queue behind one another on a table, so a backlog of corrections can delay the ones that matter most.

Frequent corrections cost more than the individual statements suggest because each rewrite creates new parts that the background merge process must combine and clean up. Many small mutations on the same data keep that merge work active, consume I/O and CPU that dashboards and ingestion also need, and leave more parts for queries to read until merges catch up. The system.mutations table shows which mutations are still pending and whether they have failed, so it is the first place to look when a correction seems stuck. If your corrections arrive continuously, plan for them in the schema, using patterns such as versioned rows or partition-level replacement, rather than treating each one as a standalone rewrite. Measure the merge backlog in your own environment with your own correction volume before you commit to a design.

Patterns for frequent corrections

Frequent corrections rarely need a single mechanism. Each pattern below trades query complexity, storage growth and merge behavior differently, so the right choice depends on how often corrections arrive, how large the affected data is and how much of it dashboards read. Check each pattern against your own correction volume on a copy of production data before standardizing on one.

Append-only correction rows

Write each correction as a new row with a version or timestamp column rather than changing the original. The original data stays intact for audit, and the latest value is selected at query time. The cost is storage growth and queries that must pick the newest version of each key. Check how many corrections a key typically receives before this pattern gets expensive to query.

ReplacingMergeTree with FINAL

Store corrected rows in a ReplacingMergeTree table keyed by the sorting key, with a version column that identifies the newest row. Deduplication happens during background merges, so duplicates can remain visible until a merge runs. Queries that need exact results add FINAL, which costs CPU on every read. Confirm the sorting key and version column with the ClickHouse documentation before you rely on it.

Partition-scoped rewrites

When a correction affects a known time range, rewrite only the partition that holds it, for example by inserting corrected rows and dropping or replacing the old partition. Work stays bounded to the affected data instead of the full table. Partition boundaries must match the correction window, or the rewrite touches more data than intended. Test the partition expression on a copy first.

Staging and swapping a corrected partition

Build the corrected partition in a staging table with the same structure, verify row counts and checksums against the source, then move it into the live table. Readers see either the old data or the corrected data, never a half-applied state. Plan for the extra storage the staging copy occupies during the build, and keep the old partition until the swap is verified and a backup exists.

Batching corrections

Group many small corrections into fewer, larger writes instead of issuing one statement per row. Each ALTER mutation or lightweight update rewrites or marks data, so batching reduces the number of rewrite passes and the merge pressure they create. The trade-off is latency: corrections wait for the batch window before they become visible. Agree on that delay with the teams that depend on the data.

Keeping corrections out of hot dashboards

Route corrections into a separate ingestion path and promote them to the dashboard tables on a schedule that suits the report owners. Interactive dashboards then avoid FINAL, mutations and duplicate rows during busy hours. The cost is that dashboards can lag corrections, so label the freshness of each dashboard and confirm with its owners which lag is acceptable.

How to plan and test a correction workflow

This sequence turns ad hoc corrections into a repeatable, measured process, so the team knows which method fits each table, what a correction costs in rows and time, and what the restored or corrected data looks like before production changes.

  1. Inventory tables that take corrections

    List every table that receives updates, deletes or late-arriving duplicates, and record the source of each correction, how often it happens, and the typical number of rows involved. Include the owner of each table and whether downstream dashboards or exports read it directly. The step is done when the team has a short register with one row per table and a correction frequency it can defend. Confirm the frequencies with the people who file the correction requests, not only with the engineers who run the pipeline.

  2. Pick a method for each use case

    For each row in the register, choose between a lightweight DELETE or UPDATE, an ALTER mutation, a ReplacingMergeTree table that deduplicates during merges, or a partition drop when whole time ranges are replaced. Write down the reason for each choice, including how the query side will handle rows that are not yet merged. Check the chosen method against the ClickHouse documentation for your installed version, because statement behavior and visibility rules change between releases. Done when every table has one method, one owner and one written reason.

  3. Build a representative copy

    Create a test cluster or a schema-equivalent test database loaded with a representative sample: same table engines, ordering keys, partitioning, and a data slice that includes the largest partitions and the oldest rows. Use the same ClickHouse version you run in production. Run a few queries that production dashboards use so you can compare results later. The check is that row counts and key distributions in the copy match production within the sample you chose, and you can state that sample's date range in writing.

  4. Reproduce a correction and measure it

    Run the chosen correction on the copy and record rows affected, elapsed time, and the time until the change is visible to a plain SELECT. Check system.mutations for the status and any failure reason when you use ALTER mutations, and watch merge activity on the affected partitions. Repeat the run at the size of your largest expected correction, not only with a small example. The step closes when you have a measured table of rows, duration and visibility delay for each method and each correction size.

  5. Compare query results with and without FINAL

    For ReplacingMergeTree tables, run the same business query with and without FINAL and compare the results against a known-good expected output. Note any difference in totals, counts or latest-version values, and decide which query form the dashboards and APIs will use. Also confirm how the query behaves before a background merge has run. The check is that the team has written, for each table, which query form is correct and why, and that the expected output matches for every correction in the test set.

  6. Verify restore before production runs

    Take a backup of the test copy and of the production tables that the correction will touch, using BACKUP to storage you control. Restore the backup to a spare cluster and confirm row counts and a sample of checksums or key queries match. The ClickHouse backup documentation advises regular restore tests because an untested backup may not restore when needed, so this is the point to prove the restore path, not assume it. Done when the restored copy matches the source for the affected tables.

  7. Run the production correction with a rollback plan

    Schedule the production change in a window agreed with the table owners, apply the same statement you tested, and watch mutation status, merges, and the query checks you wrote in earlier steps. Keep the pre-change backup available until the owners have signed off on the results. Record the actual rows affected and visibility time next to the test measurements. The step is done when the post-change checks match the expected output and the measurements are filed with the correction record, so the next run starts from evidence.

Security and audit considerations for deletions

Deletions in ClickHouse are easy to run and hard to undo, so the controls around them matter as much as the statement itself. The cards below cover who may run destructive statements, how to see them afterward, what happens between a logical delete and physical removal, and how backups and replicas respond to a mistake.

Limit who can run destructive statements

ALTER, DELETE and DROP PARTITION are granted through users, roles and settings profiles, so only a small operator role should hold them. The default user starts with all permissions, so restrict or disable it before any application or analyst account exists. Check grants with SHOW GRANTS for each service account, and confirm that dashboard and ingestion accounts cannot issue mutations at all.

Trace every mutation in query logs

Mutations and partition drops appear in system.query_log with the user, client address and statement text, which gives you the basis for an audit trail. Confirm that query logging is enabled on every replica, since each node records only the queries it receives. Ship these records to storage outside the cluster, because a compromised operator can otherwise alter the same tables they used to delete data.

Separate logical deletion from physical removal

A lightweight DELETE hides rows at once, but the bytes can remain on disk until parts are rewritten, and an ALTER mutation rewrites affected parts asynchronously. Track mutation progress in system.mutations until each one completes, and do not treat a query returning no rows as proof that data is gone. Ask your compliance owner which removal standard applies, then verify it against the part files and any frozen backups.

Account for backups before deleting

A BACKUP taken before a deletion still holds the deleted rows, so retention and erasure policies must cover backup sets as well as live tables. Define who may restore, how long backups are kept and how restored data is re-deleted if it must not persist. The backup documentation warns that a backup never test-restored will probably not restore properly when needed, so schedule restore tests on a spare cluster.

Expect replicas to copy mistakes

ReplicatedMergeTree keeps replicas in sync, so a mistaken DROP PARTITION or mutation is applied on every healthy copy within minutes. The replication documentation's point holds here: replication does not protect against human error or corruption. Gate destructive statements behind a change ticket, run them first on a non-production replica set with the same schema, and rely on backups, not replicas, as the recovery path.

Prepare evidence for auditors

Assessors typically ask for the deletion procedure, the list of accounts able to run it, logs of past runs and proof that restores were tested. DeployOpen can help assemble and configure these controls and evidence, but it does not issue audit reports, attestations or certifications. Confirm with your auditor which records they will accept, and agree with them in advance how long query log and backup evidence must be kept.

Questions teams ask before changing data in ClickHouse

Is DELETE in ClickHouse safe for GDPR erasure requests?

Yes, a lightweight DELETE or an ALTER mutation removes the rows from query results, but the erasure is only complete once the change has been applied to every replica and every copy of the data has been handled. Lightweight deletes mark rows and are cheap to issue, while mutations rewrite affected data parts and cost more on large tables. The team must also account for backups, because a restore from an older backup can bring erased rows back. Ask your compliance lead to define what counts as erased for your records, then document how deletes, replicas and backup retention work together. Our compliance guidance on erasure and retention explains that evidence in more detail.

How long does a correction take to appear in query results?

It depends on the method. A lightweight UPDATE or DELETE is visible to new queries once it completes, but mutations run asynchronously, so a large ALTER can take a long time to finish across all parts. ReplacingMergeTree deduplicates only during background merges, so older versions can remain visible until a merge happens or a query uses FINAL. The main drivers are table size, the number of affected parts, merge activity, replica lag and the concurrent insert load. Measure completion on a copy of your data using the system tables that track mutations before you commit to a schedule.

Is OPTIMIZE FINAL required after a correction?

No, it is not required, and running it routinely is usually a poor choice. OPTIMIZE FINAL forces a merge of many parts, which consumes significant CPU and IO on large tables and can slow ingestion and dashboards while it runs. Most teams instead rely on background merges and use the FINAL modifier in queries where exact results matter, accepting the extra read cost. Reserve manual merges for specific partitions after a planned backfill, and test the impact on a staging copy first. Confirm the behavior against the ClickHouse documentation for your release.

What does the internal team need to run correction workflows?

The team needs working knowledge of MergeTree tables, ordering keys and partitions, plus the ability to read system tables that show mutation and merge progress. Engineers should also own the correction contract, meaning which tables accept updates, which use deletes or partition drops, and who approves a mutation on production data. Operations staff need monitoring for stuck mutations and replica lag, and a tested restore path. Access rights should be scoped so that ad hoc ALTER statements do not run under a broad default user. Plan time for these skills before the first production correction, not during an incident.

What drives the effort of a correction design?

The effort depends on how many tables receive corrections, how often corrections arrive, and how large those tables are. A design that uses ReplacingMergeTree with a version column is simpler than one that mutates history in place, but it requires careful choice of the sorting key so duplicates are identified correctly. Partition drops are fast for bulk retirement but only fit data organized by time or tenant. Other cost drivers include the number of downstream materialized views that must be rebuilt, the replica count, backup retention rules and the amount of testing against representative data. Ask any provider to itemize the design work by table group, so you can see what scales with data volume and what is fixed.

Can our team handle corrections alone, or do we need a partner?

A capable platform team can handle simple corrections alone, especially if the data model is stable and changes are rare. A partner adds the most value when the design spans many tables, when corrections touch regulated personal data, or when the team lacks time to build tests and runbooks. Consider the cost of learning on production data against the cost of a fixed-scope engagement that delivers the design, the tested procedures and the handover. Engagements are usually agreed in writing before work starts, so ask for the deliverables, the test evidence and the operational documentation in any quote.

How do backups fit into a change or deletion plan?

Backups are the recovery path when a correction goes wrong, and replication does not provide that protection. ClickHouse BACKUP and RESTORE can take full or incremental backups of tables, partitions or databases, and the backup documentation notes that replication alone does not protect against human error or corruption. Take a backup or a frozen snapshot before large mutations or partition drops, and make sure retention rules do not conflict with erasure obligations. Most importantly, restore to a spare cluster on a regular schedule, because an untested backup often fails when it is needed. The backup documentation recommends exactly this practice.

How DeployOpen scopes and delivers ClickHouse correction workflows

DeployOpen plans, implements, tests and documents correction workflows for self-managed ClickHouse inside your own infrastructure. Engagements are fixed-scope, with the written scope fixing which tables, correction patterns and tests are covered before work starts.

How we scope

  • Inventory which tables receive corrections, how often, and whether rows change in place or arrive as later versions.
  • Map each correction type to lightweight DELETE, ALTER mutations, ReplacingMergeTree or partition drops, with visibility and cost notes.
  • Agree in writing which replicated tables, retention rules and backup dependencies the correction design must respect.

How we build

  • Build and benchmark each correction pattern on a copy of production-shaped data before any change touches live tables.
  • Set up ingestion patterns for corrections, including version columns and query-time handling of duplicate rows.
  • Validate that corrections replicate correctly across ClickHouse Keeper-coordinated replicas and that backups capture the result.

How we hand over

  • Document each correction runbook, including which statements are safe to run during business hours and which need a window.
  • Provide monitoring checks for stuck or long-running mutations and for merges that have not yet removed superseded rows.
  • Run a handover session with your operators and record the restore test results against the backup design.

How we support

  • Review the correction design when schemas, query patterns or ClickHouse versions change, against the release notes you plan to adopt.
  • Available as a retainer for ongoing support, scheduled upgrades and periodic restore tests after handover.
  • Ask for the support scope, response expectations and change control terms in the written quote before signing.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.