Iceberg, Delta Lake e Hudi: qual formato de tabela escolher
Escolher um formato de tabela aberto é a decisão de arquitetura que define como as tabelas de um lakehouse ficam gravadas sobre o object storage, e ela pesa mais do que a maioria dos times imagina. Enquanto o Parquet resolve como cada arquivo guarda colunas e linhas, é o formato de tabela que transforma um monte de arquivos soltos no S3, no GCS ou no ADLS em algo que se comporta como uma tabela de banco de dados: com transações, histórico, evolução de schema e leitura consistente por vários motores ao mesmo tempo.
Apache Iceberg, Delta Lake e Apache Hudi são os três projetos que disputam essa camada. Os três entregam ACID, snapshots, time travel e operações de update, delete e merge sobre arquivos imutáveis. Mas cada um nasceu para resolver um problema um pouco diferente, e essas origens ainda aparecem no comportamento de cada um em produção. A pergunta prática, portanto, é mais específica do que "qual é o melhor": em que formato as tabelas do seu lakehouse deveriam ficar gravadas, dado o seu padrão de escrita, os motores que você usa e o quanto você quer se manter livre de uma plataforma específica.
Este guia compara os três por critérios verificáveis, mostra como a escolha afeta a portabilidade entre Databricks, Snowflake, BigQuery e Apache Spark, e detalha o que realmente acontece numa migração de formato. O objetivo é dar uma matriz de decisão, não um vencedor universal.
O que é um formato de tabela aberto e onde ele se encaixa
Antes de comparar, vale separar camadas que costumam ser confundidas. Um pipeline de lakehouse é feito de peças distintas, e trocar uma não implica trocar as outras.
O formato de arquivo (Parquet, ORC, Avro) define como bytes de uma partição de dados são serializados em disco. O Parquet é colunar e ótimo para leitura analítica, mas não sabe nada sobre transações, versões ou o conjunto de arquivos que compõe uma tabela. Tratar Parquet como se fosse uma tabela transacional é o mal-entendido mais comum nessa discussão: ele é a matéria-prima, não a tabela.
O formato de tabela (Iceberg, Delta, Hudi) é a camada de metadados que fica por cima desses arquivos e adiciona semântica de tabela: quais arquivos pertencem a qual versão, qual o schema atual, como a tabela é particionada, e como aplicar uma escrita de forma atômica. É essa camada que dá transações ACID, snapshots, time travel, evolução de schema e de particionamento, controle de concorrência, além de update, delete, merge e upsert sobre um armazenamento que, sozinho, só sabe gravar e sobrescrever arquivos.
Acima dela vêm o catálogo (que resolve o nome da tabela para o ponteiro de metadados atual, como o Iceberg REST Catalog, o Hive Metastore, o AWS Glue, o Nessie, o Apache Polaris ou o Unity Catalog), o motor de processamento (Spark, Flink, Trino, Presto) e, no topo, a plataforma comercial (Databricks, Snowflake, BigQuery) que empacota tudo isso como serviço. A arquitetura lakehouse é o desenho que junta essas peças; se você quer entender esse desenho em profundidade, vale a leitura sobre o que é um data lakehouse antes de descer ao nível do formato.
Um ponto importante para o resto do artigo: Iceberg, Delta e Hudi são formatos de tabela, não arquiteturas completas nem plataformas. Eles resolvem a camada transacional. Governança avançada, otimização de custo e serviços gerenciados vivem em cima deles, na plataforma e no catálogo.
As camadas de um lakehouse. O formato de tabela aberto fica entre os arquivos no object storage e o catálogo que os motores consultam. Trocar de formato não obriga a trocar de motor ou de plataforma, e é justamente essa independência que está em jogo na decisão.
O que a camada de formato resolve sobre object storage
Todo formato transacional aberto entrega um núcleo comum de garantias, e é esse núcleo que justifica adotá-lo no lugar de "só Parquet numa pasta":
- Transações ACID e concorrência: escritas viram commits atômicos, e leitores enxergam sempre um snapshot consistente. Os três usam controle otimista de concorrência (OCC), em que um escritor grava novos metadados e tenta trocar o ponteiro da tabela de forma atômica; se outro escritor chegou antes, a transação falha e tenta de novo em vez de corromper a tabela.
- Snapshots e time travel: cada commit gera uma versão consultável da tabela. Dá para ler a tabela "como estava" em um snapshot ou timestamp anterior, o que serve para auditoria, reprocessamento e recuperação de erros.
- Evolução de schema: adicionar, remover, renomear e reordenar colunas sem reescrever os dados, tratando a mudança como operação de metadados.
- Update, delete, merge e upsert: operações em nível de linha que o data lake cru nunca teve, essenciais para correções, deduplicação e conformidade com LGPD.
- Ingestão incremental e Change Data Capture (CDC): consumir apenas o que mudou desde o último ponto, em vez de reprocessar a tabela inteira.
- Catálogos, compactação e manutenção: rastreio de metadados, além de rotinas para juntar arquivos pequenos e expirar snapshots antigos, controlando custo de armazenamento e de leitura.
A diferença entre os três está em como cada um implementa esse núcleo, e no que cada um adiciona por cima. É aí que a decisão fica situacional.
Como Iceberg, Delta Lake e Hudi resolvem o problema
Apache Iceberg
O Apache Iceberg organiza o estado da tabela em uma hierarquia de metadados: um arquivo de metadados aponta para uma manifest list (uma por snapshot), que aponta para manifest files, que listam os data files. Ler um snapshot é uma operação O(1) de resolução de ponteiros, sem precisar listar diretórios no object storage, o que escala bem em tabelas com milhões de arquivos.
Dois diferenciais definem o Iceberg. O primeiro é o particionamento oculto (hidden partitioning): o consumidor não precisa saber como a tabela é particionada nem adicionar filtros manuais para a query ser rápida, porque o Iceberg deriva os valores de partição por transformações (por dia, mês, bucket, truncate) e faz o pruning automaticamente. O segundo é a evolução de particionamento: dá para mudar o esquema de partição de uma tabela existente sem reescrever os dados antigos nem quebrar as queries, já que cada layout ganha um spec próprio e o planejamento de leitura trata cada faixa com o filtro correto. Nenhum dos outros dois oferece evolução de particionamento nesse nível.
O Iceberg rastreia cada coluna por um ID único, o que torna a evolução de schema segura contra reaproveitamento acidental de dados. A especificação tem três versões adotadas pela comunidade: a v1 (tabelas analíticas sobre arquivos imutáveis), a v2 (deletes em nível de linha via delete files, habilitando merge-on-read) e a v3 (deletion vectors binários, novos tipos como variant e geoespacial, e row lineage). Por padrão, update, delete e merge usam copy-on-write; merge-on-read é opcional e exige a v2 ou superior. A governança é da Apache Software Foundation, e o catálogo REST padronizado, junto com o Apache Polaris (que virou projeto top-level da Apache em 2026), reforça a postura vendor-neutral.
Delta Lake
O Delta Lake registra o estado da tabela em um log de transações, o _delta_log, com commits em JSON numerados sequencialmente e checkpoints em Parquet para acelerar a leitura do estado. Cada commit registra o schema, os arquivos adicionados (com estatísticas) e os removidos logicamente, e o ACID vem do mesmo OCC dos demais: só uma transação vence cada número de versão.
Do lado das operações de linha, o Delta ganhou os deletion vectors, sua implementação de merge-on-read: em vez de reescrever um arquivo inteiro a cada delete ou update, ele marca as posições apagadas em um bitmap e resolve na leitura, o que acelera bastante as mutações. O Change Data Feed expõe as mudanças em nível de linha (inserts, updates com pré e pós-imagem, deletes) para consumo incremental, e precisa ser habilitado por tabela. O versionamento evoluiu das versões numéricas de protocolo para as Table Features nomeadas, que permitem ligar recursos individualmente. Fora do Spark, o Delta Kernel e o delta-rs amadureceram o acesso por outras linguagens e motores, com leitura estável desde o Delta 3.0 e escrita desde o 3.2.
Vale um registro honesto de contexto, sem exagero para nenhum lado: o formato Delta é aberto, sob a Linux Foundation, e usável fora do Databricks. Ao mesmo tempo, vários recursos de ponta de layout e governança, como o Liquid Clustering em disponibilidade geral e o CLUSTER BY AUTO, aparecem primeiro (ou apenas) no Databricks Runtime e no Unity Catalog. Convém tratar isso como um gradiente, não como um interruptor: o formato é aberto, e o ecossistema de recursos mais avançados ainda gravita em torno do Databricks.
Apache Hudi
O Apache Hudi nasceu no Uber em 2016 para um problema específico: ingestão incremental com upserts eficientes em pipelines quase em tempo real. Essa origem explica por que ele é o mais forte dos três em escrita mutável de alta frequência. O estado da tabela vive em uma timeline de ações (commits, compaction, cleaning, clustering), e a versão 1.0, lançada em dezembro de 2024, reescreveu essa timeline como uma estrutura log-structured merge-tree para escalar a milhões de commits.
O Hudi oferece dois tipos de tabela que deixam o trade-off explícito na mão do time. No Copy-on-Write (COW), cada mudança reescreve os arquivos base, o que favorece a leitura. Já o Merge-on-Read (MOR) grava as mudanças em log files que são mesclados na leitura e consolidados por compaction assíncrona, favorecendo a escrita e a latência de ingestão. O grande diferencial do Hudi é a indexação plugável (Bloom, Simple, Bucket e o Record Level Index guardado na metadata table), que localiza rapidamente o arquivo de um registro por chave, tornando os upserts muito mais baratos em tabelas grandes. A versão 1.0 ainda trouxe o Non-Blocking Concurrency Control (NBCC), que permite múltiplos escritores na mesma tabela sem locks serializando as escritas, hoje limitado a tabelas MOR com bucket index. Some a isso o gerenciamento automático de arquivos pequenos durante a escrita e o Hudi Streamer para ingestão contínua de fontes como Kafka e Debezium, e fica claro o perfil de carga em que ele se destaca. A contrapartida citada com frequência pelo mercado é uma superfície de configuração maior, algo a considerar quando o time é enxuto.
Comparativo por critérios verificáveis
A tabela abaixo resume as diferenças técnicas que mais pesam na decisão. Ela não aponta um vencedor: cada linha é um eixo em que um formato tende a se encaixar melhor conforme a carga de trabalho.
| Critério | Apache Iceberg | Delta Lake | Apache Hudi |
|---|---|---|---|
| Arquitetura de metadados | Metadata file, manifest list e manifests (por snapshot) | Log de transações _delta_log (JSON) com checkpoints Parquet | Timeline de ações, reescrita como LSM tree na v1.0 |
| Transações e concorrência | ACID com OCC | ACID com OCC (isolamento serializável) | ACID via timeline; OCC e NBCC sem lock (MOR + bucket index) |
| Snapshots e time travel | Por snapshot id ou timestamp | Por versão ou timestamp | Por timestamp, com savepoints |
| Evolução de schema | Add, drop, rename, reorder por ID de coluna | Suportada, com enforcement e mergeSchema | Compatível na escrita; evolução completa em modo schema-on-read |
| Evolução de particionamento | Sim, sem reescrever dados (diferencial) | Substituída por Liquid Clustering (ecossistema Databricks) | Sem evolução de spec; caminho via expression index na v1.0 |
| Update, delete e merge | COW por padrão, MOR opcional (v2+) | MERGE, UPDATE, DELETE com deletion vectors (MOR) | COW ou MOR, com merge parcial de campos na v1.0 |
| Upserts e CDC | Suportado; leitura incremental append-only | Change Data Feed por tabela | Foco original; upsert é a operação padrão, com query CDC e incremental |
| Streaming e batch | Ambos (Flink e Spark) | Ambos (source e sink no Structured Streaming) | Ambos, com forte pegada em streaming |
| Compactação e arquivos pequenos | rewrite_data_files, expire_snapshots | OPTIMIZE, ZORDER, auto compaction | Compaction, clustering e file sizing automático na escrita |
| Catálogos | REST, Hive, Glue, Nessie, JDBC, Polaris | Hive Metastore, Unity Catalog, catalog-managed | Hive sync, Glue sync, BigQuery sync |
| Interoperabilidade | Amplo suporte multi-engine e catálogo REST | UniForm expõe Iceberg (leitura) | XTable traduz metadados entre os três |
| Governança | ASF, vendor-neutral | Linux Foundation; recursos avançados no Databricks | ASF, vendor-neutral, autogerenciável |
| Perfil de carga | Analytics em larga escala, muitos engines | Pipelines Spark e ecossistema Databricks | Ingestão incremental e upserts de alta frequência |
Os três cobrem o mesmo núcleo transacional. A escolha se decide nas bordas: se você precisa mudar o particionamento de tabelas gigantes sem downtime, o Iceberg tem uma resposta que os outros não têm; se a carga é upsert de CDC de altíssima frequência, a indexação do Hudi foi feita para isso; se a operação já roda em Databricks e Spark, o Delta é o caminho de menor atrito. Aqui vale a postura que a BIX adota em qualquer projeto de dados: trabalhamos com múltiplas soluções, e a escolha certa depende da realidade de cada operação, não de uma preferência fixa.
Como a escolha afeta a portabilidade entre plataformas
O formato de tabela só entrega portabilidade de verdade se os motores e as plataformas que você usa souberem lê-lo e escrevê-lo. E aqui compatibilidade não é binária: quase toda plataforma lê mais formatos do que escreve, e muitos recursos ainda estão em preview. A tabela abaixo consolida o suporte, sempre distinguindo leitura de escrita e disponibilidade geral (GA) de prévia.
| Plataforma | Apache Iceberg | Delta Lake | Apache Hudi |
|---|---|---|---|
| Databricks | Leitura GA; escrita nativa em private preview; UniForm expõe Iceberg (leitura); Unity Catalog como Iceberg REST catalog (leitura e escrita) | Nativo e formato padrão (GA) | Apenas via UniForm (preview) |
| Snowflake | Gerenciado: leitura e escrita GA; externo via Iceberg REST catalog: escrita GA desde out/2025 | Leitura GA (via tabela Iceberg sobre arquivos Delta); sem escrita | Sem suporte nativo |
| BigQuery | Tabelas gerenciadas: leitura e escrita; externas: leitura (v2 GA, v3 em preview) | Externo, somente leitura (nativo) | Somente leitura, via manifest |
| Apache Spark | Primeira classe (GA) via runtime Iceberg | Primeira classe (GA) via delta-spark | Primeira classe (GA) via bundle Hudi |
Alguns pontos merecem destaque porque contrariam suposições comuns. No Snowflake, conforme sua documentação oficial, a escrita em tabelas Iceberg gerenciadas por catálogo externo passou a ser GA em outubro de 2025, desde que o catálogo seja um Iceberg REST catalog; a leitura de Delta acontece por baixo, expondo os arquivos Delta como uma tabela Iceberg, hoje com suporte a time travel. Já o Databricks trata o Delta como formato padrão de tudo: a leitura de Iceberg gerenciado é GA, mas a escrita nativa em Iceberg gerenciado ainda estava em private preview no início de 2026. No BigQuery, as tabelas gerenciadas para Iceberg leem e escrevem, enquanto Delta e Hudi entram apenas como tabelas externas de leitura. E o Apache Spark é o denominador comum: os três formatos são cidadãos de primeira classe nele, cada um via seu próprio plugin.
O que amarra tudo é o catálogo. O Iceberg REST Catalog virou a camada de portabilidade entre plataformas: qualquer motor que fale essa especificação interopera com o mesmo conjunto de tabelas. Tanto o Apache Polaris quanto o Unity Catalog em código aberto implementam esse endpoint, o que reduz a dependência de um único fornecedor. Se a sua estratégia de longo prazo é evitar lock-in, a pergunta deixa de ser só "qual formato" e passa a incluir "qual catálogo", e o REST catalog do Iceberg é hoje o padrão mais neutro. Para uma leitura vizinha sobre a escolha de plataforma em si, o comparativo entre Databricks e Snowflake em 2026 ajuda a enquadrar o trade-off no nível da plataforma.
Migração entre formatos sem quebrar o pipeline
Trocar de formato de tabela é viável, mas raramente é só rodar um comando. Uma migração séria começa por um inventário: quais tabelas existem, quais motores escrevem nelas, quais catálogos as registram e quais consumidores as leem. Sem esse mapa, é fácil migrar uma tabela e descobrir depois que um job de BI ou um pipeline de CDC apontava para ela.
O ponto mais importante é distinguir conversão somente de metadados de reescrita física. Boa parte das migrações não precisa reescrever os arquivos Parquet, porque os três formatos assentam sobre os mesmos data files. O Iceberg oferece procedures oficiais no Spark: snapshot cria uma cópia isolada para teste sem tocar na origem (um dry-run seguro), migrate substitui a tabela original in-place e deixa um backup para rollback, e add_files importa arquivos para uma tabela existente. O Delta tem o CONVERT TO DELTA, que converte Parquet e também tabelas Iceberg in-place, com limitações claras: não converte tabelas Iceberg registradas em metastore, nem tabelas que passaram por evolução de particionamento, nem tabelas merge-on-read que sofreram updates. Para interoperar sem migrar, o Delta UniForm expõe metadados Iceberg a partir de uma tabela Delta, e o Apache XTable (em incubação na Apache) traduz metadados nas três direções.
A reescrita física entra em cena quando há recursos incompatíveis no caminho. Deletion vectors, histórico de merge-on-read e evolução de particionamento são os gatilhos típicos: nesses casos, compactar ou reescrever passa a ser necessário para o formato de destino conseguir ler a tabela. O UniForm, por exemplo, não funciona em tabelas Delta com deletion vectors ligados, e a interoperabilidade que ele oferece é de leitura apenas. O XTable, por sua vez, não captura log files de MOR do Hudi nem deletion vectors de Delta e Iceberg. Ou seja, quanto mais você usa os recursos avançados de merge-on-read de um formato, menos "de graça" fica a interoperabilidade com os outros.
Depois de converter, o trabalho não acabou. É preciso atualizar os pipelines para apontar para o novo formato ou catálogo, avaliar o impacto sobre o CDC (que pode não sobreviver à conversão em alguns caminhos), e validar o resultado comparando schema, particionamento, contagem de registros e paridade de queries entre origem e destino. Observabilidade sobre a nova tabela, uma transição gradual mantendo a origem viva durante um período, e um plano de rollback (o backup do migrate ou um savepoint do Hudi) reduzem o risco. E há um risco que merece atenção redobrada: múltiplos motores escrevendo na mesma tabela ao mesmo tempo pode corromper os metadados. A recomendação oficial repetida em quase toda documentação de interoperabilidade é tratar a saída de uma tabela convertida como somente leitura para os motores externos, e manter um único escritor por tabela. Se a sua ingestão depende de pipelines contínuos de CDC, planeje a janela de corte com cuidado.
Matriz de decisão: qual formato para qual cenário
Reunindo os critérios técnicos, o suporte de plataforma e o custo de migração, a decisão fica mais clara quando amarrada a cenários concretos. A tabela abaixo é um ponto de partida situacional, não uma regra absoluta.
| Cenário | Formato que tende a encaixar | Por quê |
|---|---|---|
| Analytics em larga escala com muitos motores e necessidade de trocar particionamento sem downtime | Apache Iceberg | Particionamento oculto, evolução de partição sem reescrita e catálogo REST vendor-neutral |
| Operação já baseada em Databricks e Spark, com forte uso de MERGE | Delta Lake | Formato padrão do Databricks, deletion vectors e menor atrito no ecossistema |
| Ingestão incremental e upserts de CDC de altíssima frequência | Apache Hudi | Indexação por chave, NBCC sem lock e gerenciamento automático de arquivos pequenos |
| Prioridade máxima em evitar lock-in de plataforma | Apache Iceberg | Adoção ampla de leitura e escrita entre plataformas e padronização via Iceberg REST catalog |
| Data lake multi-plataforma que precisa ser lido como vários formatos | Qualquer um, com UniForm ou XTable | Interoperabilidade de metadados evita duplicar dados, respeitando o limite de leitura apenas |
Repare que o Iceberg aparece em mais linhas por um motivo prático: a interoperabilidade e a neutralidade de catálogo o tornam a aposta mais conservadora quando o futuro da stack é incerto. Isso não o consagra como superior no geral, apenas reduz risco quando a stack ainda não está fechada. Se a stack já está definida em torno do Databricks, o Delta reduz atrito; se o problema central é upsert de alta frequência, o Hudi foi desenhado para isso. A decisão correta depende do padrão de escrita, dos motores em uso e do apetite por lock-in, e essas três variáveis mudam de operação para operação. Uma base sólida de engenharia de dados e de governança de dados importa mais para o sucesso do lakehouse do que a escolha isolada do formato, porque é ela que sustenta a operação depois que a tabela está gravada. Para o contexto arquitetural mais amplo dessa decisão, o material sobre a evolução do data lakehouse para analytics e o comparativo entre data mesh e data lakehouse em 2026 complementam este guia no nível da arquitetura.
No fim, o formato de tabela é uma decisão de fundação: ela define o que sua plataforma consegue fazer amanhã sem reescrever o passado. Escolher com base no padrão de carga real e na estratégia de portabilidade, e não em modismo, é o que separa um lakehouse que evolui de um que trava na primeira mudança de requisito. Se a sua empresa está estruturando ou repensando a camada de armazenamento do lakehouse e quer decidir entre Iceberg, Delta Lake e Hudi com base no seu contexto, nossos especialistas podem ajudar a desenhar a melhor arquitetura para o seu caso. Fale com a nossa equipe e avance na maturidade dos seus dados. ⬇️
O que é um formato de tabela aberto? É a camada de metadados que fica sobre os arquivos de dados (em geral Parquet) no object storage e os transforma em uma tabela transacional, com ACID, snapshots, time travel, evolução de schema e operações de update, delete e merge. Apache Iceberg, Delta Lake e Apache Hudi são os três principais, todos de código aberto, e todos permitem que vários motores leiam a mesma tabela.
Qual a diferença entre Parquet e um formato de tabela como o Iceberg? O Parquet é um formato de arquivo: ele define como colunas e linhas de uma partição são gravadas em um arquivo. O Iceberg é um formato de tabela: ele fica acima de vários arquivos Parquet e adiciona transações, versões, schema e particionamento. Parquet guarda os dados; o formato de tabela guarda o estado da tabela. Um não substitui o outro, eles trabalham juntos.
Iceberg, Delta Lake ou Hudi: qual é o melhor formato de tabela? Não existe um vencedor universal. O Iceberg tende a encaixar em analytics multi-engine com necessidade de evolução de particionamento e menor lock-in; o Delta Lake reduz atrito em operações baseadas em Databricks e Spark; o Hudi foi desenhado para ingestão incremental e upserts de CDC de alta frequência. A escolha é situacional e depende do padrão de escrita, dos motores usados e da estratégia de portabilidade.
É possível migrar de um formato de tabela para outro? Sim, e boa parte das migrações é somente de metadados, sem reescrever os arquivos Parquet. O Iceberg tem procedures como migrate e add_files, o Delta tem o CONVERT TO DELTA, e o Apache XTable traduz metadados entre os três. A reescrita física só é necessária quando há recursos incompatíveis, como deletion vectors ou histórico de merge-on-read, e migrar exige validar schema, particionamento e paridade de queries.
Qual formato de tabela tem melhor portabilidade entre Databricks, Snowflake e BigQuery? O Apache Iceberg tem hoje a adoção mais ampla de leitura e escrita entre plataformas, especialmente por causa da padronização do Iceberg REST Catalog, implementado por catálogos abertos como o Apache Polaris e o Unity Catalog. Ainda assim, compatibilidade não é binária: muitas plataformas leem mais formatos do que escrevem, e vários recursos permanecem em preview, então sempre confirme leitura, escrita e status na documentação oficial atual.









