Hi Huaxin,

Thanks for reviving the discussion on deprecating equality deletes.
Equality deletes are the number one pain for streaming use cases. Many
users give up when they see the merge-on-read costs, or they build
custom solutions which move them further away from core Iceberg. That
said, we've made great progress since the initial conversation in
2024.

Just to add what you said: The index we maintain in
ConvertEqualityDeletes is not ephemeral. The index is persisted in
Flink's managed state (RocksDB). It is continuously updated as new
data arrives and checkpointed periodically. However, even though the
conversion works for data written by any engine, we currently require
Flink for the conversion itself. Storing the index directly in Iceberg
and enabling all engines access would be the next logical step towards
a fully engine-agnostic solution.

The reality is that we don't yet have a working solution to avoid
writing equality deletes across all engines, but given the recent
progress, the proposed plan seems realistic. So +1 for deprecating
equality deletes in V4.

Cheers,
Max



On Tue, Jul 14, 2026 at 3:25 AM huaxin gao <[email protected]> wrote:
>
> Hi all,
>
> I'd like to restart the conversation about deprecating equality deletes, now 
> in the context of the V4 spec.
>
> Background
>
> This isn't a new idea. Russell proposed deprecating equality deletes in V3 
> and removing them from the spec in V4, back in October 2024 in "[DISCUSS] - 
> Deprecate Equality Deletes". The main blocker at the time was that equality 
> deletes served real use cases (especially Flink streaming upserts) with no 
> efficient alternative. Two developments since then make the V4 removal worth 
> acting on now.
>
> Why equality deletes are costly
>
> Equality deletes are cheap to write but expensive to read: a reader must load 
> the equality-delete files and join them against every candidate row in the 
> delete's sequence-number range. Positional deletes skip that per-row join by 
> marking exact positions, so they have always read faster, and V3 deletion 
> vectors make them faster still, one compact bitmap per data file, applied by 
> an O(1) position check, instead of V2's many position-delete files. So 
> equality deletes' only real edge is the cheap write, and both background 
> conversion and a write-time key-lookup index can recover that.
>
> Beyond performance
>
> Equality deletes also block other features. CDC and row lineage are 
> effectively impossible while they are in use, because the true state of the 
> table can only be determined with a full scan. That same property means 
> differential structures such as materialized views and secondary indexes have 
> to be fully rebuilt whenever an equality delete is added, rather than 
> maintained incrementally. So removing equality deletes is close to a 
> prerequisite for the index work to stay incrementally maintainable.
>
> Evidence the alternatives are practical
>
> 1. Converting equality deletes to DVs works today. Max Michels' 
> ConvertEqualityDeletes maintenance task (16831, 16844, 16858, 16874, 16889, 
> 16948) rewrites equality deletes into deletion vectors as a background Flink 
> job: the writer keeps appending equality deletes to a staging branch, and the 
> task converts them to DVs on the target branch so reads apply deletes by 
> position. Notably, the task resolves each delete to a position using a 
> primary-key index that it builds and maintains inside the job, demonstrating 
> the full "key -> position -> DV" path end to end.
>
> 2. A persistent key-lookup index removes the need to write them at all. The 
> secondary index spec we're working on (#16961) includes a key-lookup index 
> mapping a key to its data file and row position. This is essentially the 
> persistent, catalog-managed form of the index Max's task builds ephemerally. 
> With it, a writer can resolve positions at write time and emit DVs directly, 
> without ever producing an equality delete.
>
> How these two efforts fit together
>
> They're complementary, and they cover the two things we need to deprecate 
> equality deletes:
>
> Migration (existing data): ConvertEqualityDeletes cleans up tables that 
> already contain equality deletes, and supports writers that still emit them, 
> converting them to DVs in the background.
> Going forward (new writes): the persistent key-lookup index lets writers skip 
> equality deletes entirely by looking up positions directly.
> The connection is that Max's task already proves the core mechanism (resolve 
> key -> position, write a DV); it just rebuilds a throwaway index each cycle. 
> A durable, shared index both enables write-time elimination and removes that 
> rebuild cost from the conversion path.
>
>
> Proposal
>
> I propose that we deprecate equality deletes in V4. The blocker from 2024 was 
> the lack of a viable alternative, and we now have the pieces: background 
> conversion to DVs works today, and the key-lookup index gives us a path to 
> eliminating them at write time. Deletion vectors should be the going-forward 
> mechanism for row-level deletes and upserts, produced by background 
> conversion now and directly by writers once the index is available. Readers 
> would continue to support equality deletes for backward compatibility with 
> existing V2/V3 tables.
>
> Migration path
>
> Existing tables keep working; readers continue to apply equality deletes.
> ConvertEqualityDeletes (Flink) rewrites existing equality deletes into DVs so 
> tables can be cleared of them over time.
>
>
> I'd love people's thoughts, especially from those running large 
> streaming-upsert workloads.
>
> Thanks,
> Huaxin

Reply via email to