Scaling Data Infrastructure for AI Features and RAG

notion · Tech · 2024 · source Agentic: no · promotional bias: low · source-backed · extracted with prompt 0.5.6 (schema v2)

Generated from extraction.json — do not edit by hand. Every claim cites verbatim source evidence; stated means the quote directly asserts the claim, implied means it supports it indirectly.

Problem

Domain: data infrastructure for AI and search

Notion needed a scalable data lake to support fast-growing block data, update-heavy workloads, analytics, search, and AI/RAG features.

Constraints:

Architecture

Notion built an in-house data lake using Debezium CDC connectors on EKS, Kafka, Apache Hudi Deltastreamer, Spark, and S3. Incremental Postgres changes flow through Kafka and Hudi into S3, where Spark jobs transform and denormalize raw data before downstream analytics, Search, AI, vector database, and key-value systems consume cleaned datasets.

Diagram confidence: explicit (topology described by the source).

flowchart LR
  A["Postgres shards"] --> B["Debezium CDC connectors"]
  B --> C["Kafka topics"]
  C --> D["Hudi Deltastreamer"]
  D --> E["S3 data lake"]
  A --> G["RDS snapshot export"]
  G --> E
  E --> F["Spark processing jobs"]
  F --> H["Downstream product stores"]
  E --> H
Drag to pan · scroll or use +/− to zoom · reconstructed from the source's described component topology

Components

Component Role Interacts with
Postgres shards Source databases containing Notion block data. Debezium CDC connectors, RDS snapshot export
Debezium CDC connectors Capture incrementally changed Postgres data and publish it to Kafka. Postgres shards, Kafka topics
Kafka topics Transport changed rows from CDC connectors to downstream ingestion jobs. Debezium CDC connectors, Hudi Deltastreamer
Hudi Deltastreamer Consumes Kafka messages and replicates Postgres table state in S3. Kafka topics, S3 data lake
S3 data lake Stores raw, intermediate, and processed datasets as the single data repository. Hudi Deltastreamer, Spark processing jobs, Downstream product stores, RDS snapshot export
Spark processing jobs Transform, denormalize, enrich, and compute permission-aware datasets. S3 data lake, Downstream product stores
RDS snapshot export Bootstraps tables into S3 when full snapshots are needed. Postgres shards, S3 data lake
Downstream product stores Snowflake, Elasticsearch, vector database, key-value stores, analytics, Search, and AI feature consumers. S3 data lake, Spark processing jobs

Data flow

Postgres changes are captured by Debezium connectors, written to Kafka topics, consumed by Hudi Deltastreamer into S3, transformed and denormalized by Spark, then written back to S3 or downstream systems for analytics, reporting, AI, Search, and product features. Rare full snapshots bootstrap new tables, with Kafka replay preserving changes made during the snapshot.

3 supporting quotes
“We ingest incrementally updated data from Postgres to Kafka using Debezium CDC connectors, then use Apache Hudi, an open-source data processing and storage framework”article, stated
“With this raw data we can then do transformation, denormalization (e.g., tree traversal and permission data construction for each block), and enrichment”article, stated
“Finally, we ensure that all changes made during the snapshotting process are captured by setting up Deltastreamer to read from Kafka messages from t.”article, stated

Why this architecture

Notion chose a data-lake architecture because update-heavy block data, permission denormalization, and AI/Search freshness needs outgrew warehouse-centric ingestion. S3 provided cheap scalable storage, Spark provided flexible transformations, and Hudi matched Debezium CDC for update-heavy ingestion.

3 supporting quotes
“This causes block data to be predominantly update-heavy—90% of Notion upserts are updates.”article, stated
“S3 has proven its ability to store large amounts of data and support various data processing engines (like Spark) at low cost.”article, stated
“we chose Hudi for its excellent performance with our update-heavy workload and its open-source nature and native [integration with Debezium CDC messages]”article, stated

Scale

Alternatives considered (roads not taken)

Continue Snowflake-centric ingestion

Rejected because: Snowflake ingestion became slower and more costly for Notion's update-heavy workload.

“Ingesting data to Snowflake became slower and more costly, primarily due to Notion's unique update-heavy workload.”article, stated

Periodic full snapshots as the normal path

Rejected because: Full snapshots took more than 10 hours and cost twice as much, so Notion used them only for rare bootstraps.

“Taking a full snapshot and dumping to S3, by contrast, takes more than 10 hours and costs twice as much, so we do so infrequently”article, stated

Iceberg or Delta Lake for ingestion

Rejected because: At the time, they were less suited to the Debezium/update-heavy requirements or lacked an open-source Debezium-ready path.

“Iceberg and Delta Lake, on the other hand, weren’t optimized for our update-heavy workload when we considered them in 2022.”article, stated

Patterns

batch-offline-processing (data-infrastructure)

Spark jobs transform, denormalize, and enrich raw S3 data for analytics, reporting, Search, and AI features.

“Once raw data is in S3, we then do transformation, denormalization, enrichment, and other types of data processing.”article, stated

rag-retrieval (retrieval)

The data lake became foundation infrastructure for Search and AI Embedding RAG systems.

“enabling the successful rollout of Notion AI features in 2023 and 2024. Stay tuned for a detailed post on our Search and AI Embedding RAG Infra built on top of the data lake!”article, stated

Tradeoffs

Data repository

Chose S3 as raw and processed data lake over keeping all heavy ingestion and compute in Snowflake/product stores.

Rationale: S3 fit Notion's AWS stack, storage scale, Spark processing, cost, and downstream product requirements.

“offloading heavy ingestion and compute workloads to S3 and only ingesting highly cleaned and business-critical data to Snowflake and product-facing data stores”article, stated

Ingestion strategy

Chose incremental CDC plus rare snapshots over periodic full snapshots.

Rationale: Incremental ingestion is fresher and cheaper, while snapshots are useful only for bootstrap and resync scenarios.

“* During normal operations, incrementally ingest and continuously apply changed Postgres data to S3.”article, stated

Lake table format

Chose Apache Hudi over Apache Iceberg or Delta Lake.

Rationale: Hudi matched the update-heavy workload and provided native Debezium CDC integration.

“we chose Hudi for its excellent performance with our update-heavy workload and its open-source nature and native [integration with Debezium CDC messages]”article, stated

Gotchas (what bit them)

Warehouses struggled with Notion's update-heavy workload.

Root cause: Most data warehouses are optimized for inserts, while Notion's block data is dominated by updates.

Resolution: Use Debezium CDC, Kafka, and Hudi to apply changed rows into S3.

“Most data warehouses, including Snowflake, are optimized for insert-heavy workloads, which makes it increasingly challenging for them to ingest block data.”article, stated

Permission-aware AI/Search datasets required expensive denormalization.

Root cause: Block permissions are not statically stored and require tree traversal computation.

Resolution: Move raw data into S3 and use Spark transformations for denormalized product datasets.

“a block’s permission isn’t statically stored in the associated Postgres—it has to be constructed on the fly via expensive tree traversal computation.”article, stated

Full snapshots were too expensive and slow for routine ingestion.

Root cause: Dumping full Postgres snapshots to S3 took more than 10 hours and cost twice as much as incremental ingestion.

Resolution: Use incremental CDC during normal operation and reserve snapshots for bootstrapping new S3 tables.

“The incremental approach ensures fresher data at lower cost and with minimal delay (a few minutes to a couple hours, depending on table size).”article, stated

Evaluation

Notion evaluated the infrastructure through ingestion latency, operational smoothness, cost savings, ability to handle data growth, and successful rollout of AI/Search features.

Metrics: data growth rate · row-change throughput · ingestion delay · resync time · cost savings · AI/Search feature enablement

“This setup provides a delay of just a few minutes for most tables, and up to two hours for the largest one, the block table”article, stated
“* For these datasets, the end-to-end ingestion time from Postgres to S3 and Snowflake decreased from more than a day to a few minutes for small tables and up to a couple of hours for large ones. Re-syncs, when necessary, can be completed within 24 hours without overloading live databases.”article, stated

Outcomes

The system handles hundreds of billions of block rows, 480 shards, and tens of MB/sec of row changes.

3 supporting quotes
“the end-to-end ingestion time from Postgres to S3 and Snowflake decreased from more than a day to a few minutes for small tables and up to a couple of hours for large ones.”article, stated
“Moving several large, crucial Postgres datasets (some of them tens of TB large) to data lake gave us a net savings of over a million dollars for 2022”article, stated
“enabling the successful rollout of Notion AI features in 2023 and 2024.”article, stated