惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Cloudflare Blog
Microsoft Security Blog
Microsoft Security Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
LangChain Blog
W
WeLiveSecurity
P
Proofpoint News Feed
月光博客
月光博客
NISL@THU
NISL@THU
L
LINUX DO - 最新话题
Webroot Blog
Webroot Blog
T
Threatpost
Y
Y Combinator Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Threat Research - Cisco Blogs
Vercel News
Vercel News
Jina AI
Jina AI
阮一峰的网络日志
阮一峰的网络日志
S
Schneier on Security
J
Java Code Geeks
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
小众软件
小众软件
MyScale Blog
MyScale Blog
N
News and Events Feed by Topic
Stack Overflow Blog
Stack Overflow Blog
有赞技术团队
有赞技术团队
The Hacker News
The Hacker News
Schneier on Security
Schneier on Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Help Net Security
Help Net Security
Recent Announcements
Recent Announcements
S
Security @ Cisco Blogs
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Securelist
T
The Exploit Database - CXSecurity.com
云风的 BLOG
云风的 BLOG
C
Cisco Blogs
雷峰网
雷峰网
量子位
Google DeepMind News
Google DeepMind News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Spread Privacy
Spread Privacy
L
Lohrmann on Cybersecurity
I
Intezer
T
The Blog of Author Tim Ferriss
G
GRAHAM CLULEY
D
DataBreaches.Net
V
Vulnerabilities – Threatpost
P
Privacy & Cybersecurity Law Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
罗磊的独立博客

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
From Glue to Horizon: Our Real Journey Building an Iceberg Lakehouse on Snowflake
Krishna Tang · 2026-05-04 · via DEV Community

We set out to build an open lakehouse: Iceberg tables on AWS S3, Spark/Glue for pipelines, Snowflake for analytics compute power. What could go wrong? Everything—from query performance implosions to uncloneable dynamic tables. Here's the unfiltered journey, including why we pivoted to Snowflake-managed Iceberg via Horizon Catalog and abandoned automated dynamic tables for explicit, observable incremental processing.

TL;DR

  • Phase 1 failed: Glue-generated Iceberg files (32-64MB) caused 5-10x slower Snowflake queries
  • Phase 2 wins: Snowflake-managed Iceberg auto-compacts to 256-512MB, 2-5x faster, ~35% cost savings
  • ⚠️ Dynamic Tables gotcha: Cannot clone, opaque refresh timing—unusable for production DevOps
  • Solution: Explicit Streams + Tasks on log tables—boring, debuggable, production-ready
  • 🎯 Key decision: Data team owns Bronze→Silver only; business owns Gold (saved endless remodeling debates)
  • 💰 Reality check: "Cloud-neutral" = readable across engines, not free migration

Our Team Context (Yours Will Differ)

Before diving into architecture decisions, here's who we are:

  • Skills: Strong SQL/dbt, limited Spark/Scala experience
  • Priorities: Ship fast, avoid operational black boxes
  • Constraint: No dedicated DevOps for Glue cluster tuning

This shaped every decision below. A team fluent in Spark would have made different trade-offs.


🎯 The Goal

Unify data from SAP HANA (change data capture), Salesforce Data Cloud, and raw event streams into a single cloud-neutral lakehouse—no proprietary lock-in, full cross-tool interoperability.

Why Iceberg?

We evaluated Delta Lake, Apache Hudi, and Apache Iceberg a couple of years ago. Here's the comprehensive comparison that drove our decision:

Criterion Iceberg Delta Lake Hudi
Partition Evolution Change without rewrite ❌ Requires full table rewrite ❌ Not supported
Primary Keys ✅ Native support ❌ Not supported ✅ Supported
Automated Compaction MAINTAIN ICEBERG TABLE ⚠️ Manual (OPTIMIZE tuning) ⚠️ Manual/semi-auto
Schema Evolution ✅ Full (add/drop/rename/reorder) ✅ Add/drop columns ⚠️ Limited
Engine Compatibility ✅ Spark, Trino, Flink, Snowflake, Dremio ⚠️ Spark-first, limited others ⚠️ Spark-first
Platform Support ✅ AWS Glue/Athena, Azure, GCP, Snowflake ✅ AWS, Azure (Fabric native), Databricks ⚠️ AWS, limited Azure
File Format Flexibility ✅ Parquet, ORC, Avro ⚠️ Parquet only ✅ Parquet, ORC, Avro
Community Governance ✅ Apache Foundation (vendor-neutral) ⚠️ Databricks-controlled ✅ Apache Foundation

Why We Chose Iceberg (and Ruled Out Delta/Hudi)

Iceberg's winning factors for our context:

  1. Partition evolution without rewrites: Our SAP data's partitioning strategy evolved over time (daily → monthly as data matured). Iceberg lets us change partition specs without rewriting billions of rows. Delta requires full table rewrite—a multi-day, multi-TB operation we couldn't afford.

  2. Snowflake-managed support: Only Iceberg offers native managed tables in Snowflake Horizon Catalog with automatic compaction. Delta/Hudi would lock us into external table limitations with the Phase 1 performance issues.

  3. Automated compaction: Snowflake's MAINTAIN ICEBERG TABLE handles file optimization automatically. Delta requires manual compaction tuning in Spark—expertise our SQL-first team doesn't have.

  4. Primary key enforcement: Iceberg supports primary keys natively, critical for our SAP source data integrity (customer IDs, order numbers). Delta lacks this—you must enforce it in application logic.

  5. Vendor-neutral governance: Apache Foundation stewardship means no single vendor controls the spec. Delta's governance is tied to Databricks' business interests.

Bottom line: Iceberg was the safe bet for multi-engine flexibility without vendor lock-in. If you're Azure-only with Fabric, Delta is pragmatic. If you're Databricks-native, Delta is the path of least resistance. But for AWS + Snowflake + future optionality, Iceberg was the only choice.

Why Snowflake for Compute?

Three differentiators that closed the decision:

3. Compute Billing Precision

POC result: Our thousands of BI dashboards were only charged for calculation time—not data transfer to BI tools. Estimated 40–60% cost savings vs. **competitors **billing full query duration.


🏛️ Medallion Architecture

Our lakehouse follows the classic three-layer medallion model, tailored for SAP source systems:

┌─────────────────────────────────────────────────────────────┐
│                    DATA SOURCES                             │
│   SAP HANA (CDC)  │  Salesforce Data Cloud  │  Raw Streams │
└────────────┬──────────────────┬─────────────────────┬───────┘
             │                  │                     │
             ▼                  ▼                     ▼
┌─────────────────────────────────────────────────────────────┐
│  🥉 BRONZE LAYER — AWS Glue Spark → Iceberg writes to S3   │
│  Raw ingestion, no transformation, full fidelity            │
└─────────────────────────┬───────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────────┐
│  🥈 SILVER LAYER — Iceberg Tables (AWS-hosted, S3)         │
│  Matches source table structures                            │
│  e.g., KNA1 (Customers), MARA (Materials), VBAK (Orders)   │
└─────────────────────────┬───────────────────────────────────┘
                          │  Stream on log_table
                          ▼
┌─────────────────────────────────────────────────────────────┐
│  🥇 GOLD LAYER — Snowflake-Managed Iceberg (Horizon Cat.)  │
│  Proper dimensions & facts with business names             │
│  e.g., DIM_CUSTOMER, FACT_SALES_ORDER, DIM_PRODUCT         │
└─────────────────────────┬───────────────────────────────────┘
                          │
                          ▼
              BI Tools / ML / Fabric Export

Enter fullscreen mode Exit fullscreen mode

Sounds ideal? Early reality: Snowflake choked on our Glue-generated files.


The Architecture Decision Nobody Talks About: Layer Ownership

Here's what we learned the hard way: Don't own Gold if you don't have to.

Why this boundary matters:

  • Silver = Source truth: Matches SAP table structures (KNA1, MARA, VBAK). Data engineering controls quality, structure, and change tracking.
  • Gold = Business semantics: DIM_CUSTOMER, FACT_SALES_ORDER. Business teams decide how to model, aggregate, and interpret.
  • Boundary = Contract: Silver provides clean, change-tracked source data with explicit SLAs; business teams own downstream transformations.

This Decision Saved Us From:

❌ Endless "why did the customer count change?" debates (business definition shifts, not data quality issues)

❌ Remodeling dimensions every quarter when business logic evolves

❌ Being the bottleneck for every dashboard request

❌ Owning interpretations of business rules we don't fully understand

Your team may differ, but define the ownership boundary early or you'll own every downstream interpretation forever. The tools (dbt, Iceberg, Snowflake) don't enforce this—you must.


Phase 1: Glue-Managed Iceberg + Snowflake External Tables ❌

The Performance Trap

We started simple: Spark jobs in Glue created Iceberg tables stored in Glue Catalog; Snowflake linked them as external Iceberg tables.

What Broke: File Size Mismatch

Snowflake's Iceberg scanner is optimized for specific file characteristics per official recommendations:

Parameter Snowflake Recommendation What Glue Produced
File size 256 – 512 MB 32 – 64 MB (many small files)
Row group size 16 – 256 MB < 16 MB
Row groups per file Multiple (for parallelism) Often 1

The result: Full table scans instead of pruned reads, query times 5–10x slower than expected.

┌──────────────────────────────────────────────────────┐
│              PHASE 1 ARCHITECTURE                    │
│                                                      │
│  AWS Glue Spark ──writes──▶ Iceberg (Glue Catalog)  │
│                                    │                 │
│                             S3 Parquet files         │
│                          (small, fragmented)         │
│                                    │                 │
│  Snowflake ◀──external table──────┘                 │
│  (slow scans, no auto-compaction)                    │
└──────────────────────────────────────────────────────┘

Enter fullscreen mode Exit fullscreen mode

🔀 Decision Point: Invest in Spark Tuning or Snowflake-Managed?

Option A: Hire Spark expertise, tune file compaction settings

  • Timeline: 3-6 months
  • Ongoing cost: Maintain Spark expertise, monitor file sizes
  • Risk: Our team lacks Spark internals experience

Option B: Snowflake-managed Iceberg via Horizon Catalog

  • Timeline: 2 weeks
  • Ongoing cost: Snowflake MAINTAIN ICEBERG TABLE compute
  • Upside: Handles compaction automatically, team stays in SQL/dbt comfort zone

We chose Option B: Our team's strength is SQL/dbt, not Spark internals. Let Snowflake handle the file lifecycle.


Phase 2: Snowflake-Managed Iceberg + Horizon Catalog ✅

The Pivot

Snowflake-managed Iceberg tables put Snowflake in charge of the table lifecycle on your S3 bucket—Horizon Catalog governs metadata, access, and interoperability.

┌──────────────────────────────────────────────────────────┐
│               PHASE 2 ARCHITECTURE                       │
│                                                          │
│  AWS Glue Spark ──writes──▶ Snowflake Horizon Catalog   │
│                                    │                     │
│                    Horizon manages Iceberg metadata      │
│                    Auto-compaction to 256-512MB files    │
│                                    │                     │
│                             S3 (your bucket)             │
│                          Optimal Parquet layout          │
│                                    │                     │
│  Snowflake ◀──native read─────────┘                     │
│  (2–5x faster, full pruning, cloneable*)                 │
│                                                          │
│  BI Tools ◀── Snowflake compute                         │
│  Glue/Spark ◀── Iceberg open format (bidirectional)     │
└──────────────────────────────────────────────────────────┘

Enter fullscreen mode Exit fullscreen mode

Wins

2–5x query speedup vs. Phase 1 external tables

Automatic compaction to optimal file sizes via MAINTAIN ICEBERG TABLE

Bidirectional access: Glue/Spark can write, Snowflake reads natively; BI tools use Snowflake compute

Open format preserved: Gold layer exportable to Fabric/Polaris later

Trade-off: Snowflake compute is billed for maintenance runs—but total ops cost is lower than Phase 1's slow queries burning warehouse credits.


⚠️ Why We Abandoned Dynamic Tables for Production

Dynamic Tables on Iceberg sounded perfect—zero-code pipelines, automatic refresh. We hit two walls that forced us back to explicit patterns:

Problem 1 — No Cloning Support:

-- This FAILS silently on dynamic Iceberg tables
CREATE DATABASE prod_clone CLONE prod_db;
-- Dynamic Iceberg tables are simply skipped in the clone

Enter fullscreen mode Exit fullscreen mode

DB/schema clones skip dynamic Iceberg tables entirely. This is a DevOps killer—no dev/test environment parity, no blue-green deploys.

Problem 2 — Opaque Refresh Timing:

Incremental refresh latency was unpredictable and nearly impossible to debug for SLA enforcement. Monitoring refresh lag and debugging failures was guesswork with no visibility into what triggered refreshes or why they were delayed.

🔀 Trade-off: Zero-Code vs. Zero-Surprise

Dynamic Tables promise automation but hide:

  • When refreshes actually run
  • What triggered the refresh
  • How to debug failures in production at 3am

Streams + Tasks = More code, but debuggable in production.

Architecture decision-makers: Optimize for production support, not dev convenience.

Resolution: Abandoned dynamic tables for Silver → Gold. Back to explicit Streams + Tasks.

Our Solution: Log Table Pattern

┌─────────────────────────────────────────────────────┐
           SILVER  GOLD PIPELINE (Current)          
                                                      
  Silver Layer                                        
                                                    
     ├──▶ silver.log_table (tracks all changes)      
                                                    
                                                    
     CREATE STREAM log_changes                       
     ON TABLE silver.log_table;          ◀── stream  
                                                    
                                                    
     CREATE TASK gold_refresh            ◀── task    
       SCHEDULE = '5 MINUTE'                         
       AS MERGE INTO gold.customer_360               
          USING log_changes ...;                     
                                                    
                                                    
     Gold Layer (Snowflake-Managed Iceberg)          
└─────────────────────────────────────────────────────┘

Enter fullscreen mode Exit fullscreen mode

-- The explicit, cloneable, debuggable pattern
CREATE STREAM log_changes ON TABLE silver.log_table;

CREATE TASK gold_refresh
  WAREHOUSE = compute_xs
  SCHEDULE = '5 MINUTE'
  WHEN SYSTEM$STREAM_HAS_DATA('log_changes')
  AS
  MERGE INTO gold.customer_360 tgt
  USING (
    SELECT * FROM log_changes WHERE metadata$action = 'INSERT'
  ) src
  ON tgt.customer_id = src.customer_id
  WHEN MATCHED THEN UPDATE SET ...
  WHEN NOT MATCHED THEN INSERT ...;

Enter fullscreen mode Exit fullscreen mode

Why This Wins:

Full cloning support (dev/prod parity restored)

Transparent costs — every execution logged in TASK_HISTORY

Debuggable — stream offset visible, failures isolated

Fabric-friendly — Gold can be exported as Iceberg/Parquet later


🌐 Cross-Platform Reality: Why We Can (and Can't) Pivot

Current State: AWS + Snowflake, Iceberg on S3

Open format preserved: Can read Iceberg from Spark, Trino, Athena

Gold exportable: Stream to Parquet → Fabric mirroring works

⚠️ Fabric constraint: OneLake wants Delta + same Azure region for zero-copy

⚠️ Horizon lock-in: Snowflake-managed Iceberg metadata tied to Horizon Catalog

What "Cloud-Neutral" Actually Means

Not: "Deploy anywhere tomorrow with zero effort"

Actually: "Readable by multiple engines, movable with effort"

If We Had to Migrate to Fabric:

Layer Migration Effort Estimated Timeline
Bronze → Silver ingestion Rewrite Glue jobs to Delta 2-3 weeks
Silver → Gold dbt models Port to Fabric SQL (syntax diffs) 1-2 months
Gold Iceberg tables Export as Parquet, re-create in Fabric Warehouse 1-2 weeks
┌────────────────────────────────────────────────────────────┐
│                  CATALOG LANDSCAPE                         │
│                                                            │
│  Our Setup: AWS us-east-1                                  │
│  ┌────────────────────────────────────────────────────┐   │
│  │  Snowflake Horizon Catalog (current)               │   │
│  │  + AWS Glue Catalog (bronze/silver ingestion)      │   │
│  └────────────────────────────────────────────────────┘   │
│                                                            │
│  Future Options:                                           │
│  ┌─────────────────┐    ┌──────────────────────────────┐  │
│  │ Polaris Catalog │    │ Microsoft Fabric OneLake      │  │
│  │ (Snowflake SaaS)│    │ (wants Delta; Azure-region   │  │
│  │ Maturing fast   │    │  only for zero-copy)          │  │
│  └─────────────────┘    └──────────────────────────────┘  │
│                                                            │
│  Gold Streams → Parquet export → Fabric compatible ✅      │
└────────────────────────────────────────────────────────────┘

Enter fullscreen mode Exit fullscreen mode

Our Decision:

We prioritized Snowflake ecosystem depth over day-1 multi-cloud portability.

Iceberg gave us an exit path, not a free exit. For teams needing Fabric OneLake zero-copy, starting with Delta on Azure is the pragmatic choice.


💰 Cost Reality Check

Phase 1 (Glue + External Iceberg):

  • Glue: costs to write and maintain iceberg tables
  • Snowflake query costs: 3x higher due to full scans

Phase 2 (Snowflake-managed Iceberg):

  • MAINTAIN ICEBERG TABLE: in warehouse credits
  • Query costs: 60% reduction (pruning + caching works correctly)
  • Net savings: 35% monthly vs. Phase 1

Takeaway: Optimize for query performance where your users actually spend time, not just ingestion costs.


🔑 Lessons for Your Lakehouse

1. File sizes first

Target 256-512MB Parquets or let Snowflake MAINTAIN ICEBERG TABLE handle it automatically. Small files kill Snowflake performance.

2. Clone-test early

Dynamic Iceberg tables are powerful but not clone-safe for databases/schemas. Test your DevOps workflow before committing to production.

3. Horizon bidirectional is a game-changer

If your team uses both Spark and Snowflake, Horizon gives you the best of both without choosing sides. Write with Spark, read with Snowflake—all on the same Iceberg tables.

4. Streams > automation black boxes

Explicit Streams + Tasks always win in production ops: observable at 3am, debuggable from logs, cloneable for dev/test.

5. Phase your migration

Don't try to migrate all layers at once. Start with Gold (highest query frequency), validate performance, then move Silver.

6. Define ownership boundaries early

Bronze→Silver→Gold isn't just technical layers—it's organizational boundaries. Decide who owns what before the first production table.


When to Use What: Decision Matrix

Your Situation Recommendation Why
Team strong in Spark, need multi-engine Glue-managed Iceberg + External tables Keep expertise where it is
Team SQL-first, Snowflake primary engine Snowflake-managed Iceberg Let Snowflake handle file lifecycle
Must support Fabric OneLake zero-copy Delta Lake on Azure Iceberg works but not zero-copy on Fabric
Need dev/prod clones + SLA guarantees Streams + Tasks (avoid Dynamic Tables) Observable, debuggable
Bronze/Silver only (like us) dbt incremental + Developer Toolkit Explicit watermark control

Bottom line: Cloud-neutral means readable across tools, not free migration. Choose the platform that matches your team's strengths, use open formats for portability insurance.


What's Next for Us

  • Investigate Polaris Catalog or wait for Horizon Catalog for true multi-vendor Iceberg metadata management
  • Evaluate cost/performance of streaming directly from Kafka → Snowflake Iceberg
  • Explore Iceberg v3 features for enhanced BCDR and CDC capabilities

🆕 Update: Iceberg v3 Features (March 2026) That Could Change Your Decision

Since our original evaluation, Snowflake released Apache Iceberg v3 support in public preview (March 2026) with capabilities that address several of our pain points and unlock new architectural patterns.

What's New in Iceberg v3

1. Cross-Region Replication for Snowflake-Managed Tables

  • What it enables: BCDR failover and replication groups for Iceberg tables across regions
  • Why it matters: Previously, our DR strategy required complex Parquet exports. Now, Snowflake-managed Iceberg tables can replicate with full consistency (including row lineage and deletion vectors)
  • Architecture impact: We can now deploy active-passive DR without custom tooling
  • 📖 Replication Config Docs

2. Catalog-Linked Databases

  • What it enables: Connect to remote Iceberg catalogs (AWS Glue, Polaris, etc.) with automatic namespace discovery and read/write support
  • Why it matters: Our Phase 1 external table limitations are eliminated—we can now write back to Glue Catalog-managed tables from Snowflake
  • Architecture impact: True bidirectional catalog federation; could unblock our "Glue as ingestion, Snowflake as analytics" hybrid
  • 📖 CREATE Catalog-Linked Database Docs

Which Features Would Have Changed Our Decision?

Would have stayed with our choice (Iceberg + Horizon):

  • Cross-region replication validates our bet on Snowflake-managed Iceberg (Delta still doesn't have this)
  • Catalog-linked databases eliminate the Phase 1 external table pain without abandoning Glue ingestion

Bottom Line: Iceberg v3 Strengthens the "Safe Bet"

For SQL-first teams on Snowflake, Iceberg v3 eliminates the last major operational friction points we encountered. The combination of Horizon Catalog + v3 features delivers the "cloud-neutral with vendor optimization" balance we were seeking.


What's your biggest Iceberg-on-Snowflake headache? Drop it below 👇

Snowflake #ApacheIceberg #Lakehouse #DataEngineering #HorizonCatalog #DataArchitecture #AWS #OpenLakehouse