Notionのベクトル検索は優れている。彼らの次の課題はさらに難しい。
「Notionにおけるベクトル検索の2年間」を読んで — そして、それが次に来るものについて予測していること
Notionは、2年間にわたるベクトル検索インフラを扱ったエンジニアリング記事を公開した。私はそれを心からの称賛と強い既視感をもって読んだ。彼らが説明するほぼすべての問題、実行した移行、構築した回避策には、ビッグデータの歴史における近い並行例がある。ビッグデータは、その長期的なアーキテクチャへ収束するまでに、およそ15年を要した。
私が最も強く印象を受けたのは、実行の質だけではなかった。より完全なアーキテクチャであればプロダクトエンジニアリングではなくインフラに属するべき、プラットフォームレベルの関心事に、どれほど多くの労力が注がれていたかだった。
もし彼らの次のエンジニアリング記事のタイトルを推測するなら、「埋め込みモデルのアップグレードに6か月を費やした方法」 かもしれない。あるいは 「ダウンタイムなしで1億のワークスペースを新しいベクトル空間へ移行した方法」。あるいは 「Notion AIに永続的な記憶を与えるために、オフラインのコンテキストエンジニアリングを構築した方法」。
これまでに解決されたことはすべて第1章だ。第2章はもっと難しい。
Notionが構築したもの
物語は2023年11月に始まる。NotionはAI Q&Aをリリースし、ほぼ即座に数百万のワークスペースからなるウェイトリストを抱えることになった。彼らのベクトルデータベースはポッドクラスタ上で動いていた — ストレージとコンピュートが一体化し、ワークスペースIDでシャーディングされていた。1か月もしないうちに、容量上限に近づいていた。
本番トラフィック下で再シャーディングするのではなく、彼らは実用的な道を選んだ。generation IDでタグ付けされた新しいインデックスクラスタを立ち上げ、新しいワークスペースを新しい世代へルーティングし、既存のワークスペースはそのまま残す、という方法だ。SparkとAirflowのチューニングと組み合わせることで、彼らは4か月でウェイトリストを解消した。1日あたりのオンボーディング能力は600倍になった。
プレッシャー下での見事なエンジニアリングだった。その代償は、以後2年間ついて回ることになる、複数世代のルーティングロジックだった。
その後、2つの大きな移行があった。
2024年5月 — ポッドアーキテクチャからサーバーレスへ。ストレージとコンピュートが分離された。コストは即座に50%低下し、世代ルーティングの複雑さもそれとともに解消した — 容量が、もはや事前に計画しなければならない有限のリソースではなくなったからだ。
2024年後半から2025年前半 — 彼らのサーバーレスプロバイダからturbopufferへ。彼らのデータはベンダー独自のストレージシステムに保存されていたため、切り替えには完全な再インデックスが必要だった。彼らはその機会を使って、埋め込みモデルもアップグレードした。
2025年半ば、彼らはPage Stateをリリースした。すべてのテキストスパンはxxHash(64-bit)でハッシュ化され、DynamoDBに保存される。ページが更新されると、システムは再埋め込みするかどうかを判断する前にハッシュを比較する。メタデータだけが変更された場合は、ベクトルを再計算せずに、ベクトルデータベースへ直接パッチを当てる。
その少し後、埋め込み生成はSpark + external APIから、Ray via Anyscale上のセルフホストモデルへ移行した。CPUの前処理とGPU推論はいまや単一のパイプラインで実行され、システム間のS3受け渡しは不要になった。
2年間。5つの大きな賭け。コストはピーク時から90%減少。これは本当に印象的な歩みだ。
これはビッグデータがすでに語った物語である
各段階で、私は注釈としてこう書き込みたくなった。ビッグデータのエコシステムはこれを[year]に解決した。これは偶然ではない。同じ制約は、同じアーキテクチャ上の動きを生む。
1. ストレージとコンピュートの分離、そしてサーバーレス:存在ではなく作業に支払う
Notionの2つのコスト移行 — ポッドクラスタからサーバーレスへ、そしてオブジェクトストレージを基盤とするサーバーレス構成へ — は、1つのアーキテクチャ上の動きとして読める。インフラの存在に対して支払うのをやめ、実際の作業に対して支払い始めるということだ。ワークスペースがアクティブにクエリされていようと、何週間もアイドル状態であろうと、古いモデルではクラスタが稼働し続け、課金され続けていた。
このように見ると、重要な変化はストレージとコンピュートの分離です。インデックスはオブジェクトストレージに置かれ、コールドなコレクションはほとんどコンピュートを保持せず、ホットなコレクションはオンデマンドでロードされ、支出は実際の使用量により密接に連動します。ビッグデータにおいて、これは単なるHDFSからS3への置き換えではありませんでした。ストレージとコンピュートの統合から、ストレージとコンピュートの分離への、より広範な移行だったのです。
順序が重要でした。まず、独立したスケーリングが伸縮性とキャパシティプランニングの痛みを解消しました。その後、一時的なコンピュートと永続的なオブジェクトストレージによって利用コストが削減されました。Hadoopのデフォルトのデプロイメントでは、データローカリティのためにストレージとコンピュートが同じ場所に配置されていたため、独立したスケーリングが困難でした。データがS3に移ると、Sparkクラスターはジョブごとに起動し、完了後にシャットダウンできる一方で、ストレージは永続的に残りました。
トレードオフも構造的です。 オブジェクトストレージへのアクセスは、コールドスタートのレイテンシに下限を設定します。複数のGETリクエスト、デシリアライズ、インデックスの再構築です。これはパラメータ調整の問題というより、ストレージの物理的制約の問題です。Notionの現在のワークロードでは、ほとんどのワークスペースが頻繁にはクエリされないため、これは良いトレードオフです。しかしAIの利用が深まるにつれ、2つの限界が無視しにくくなります。継続的に高いクエリ量を持つ大規模テナントと、コールドなワークスペースに戻ってきたユーザーにとってテールレイテンシが目に見える形になることです。その時点では、単一階層のS3ネイティブキャッシュだけでは不十分なことが多く、ウォームデータをローカルSSD上に保持することが実質的により重要になります。
2. Lambda Architecture: リアルタイムは必要であり、断片化はコストである
Notionのインデックスシステムは2つの経路で動作します。大規模なバックフィルのためのオフラインSparkパイプラインと、リアルタイム更新のためのKafkaコンシューマーです。これは典型的なLambda構成です。
データの鮮度を重視するなら、この設計は自然な出発点です。問題はその後に起こります。同じロジックが複数のシステムに広がり始め、チームは経路間の一貫性を保つことにより多くの時間を費やすようになります。
Notionの場合、その分断はいまやSpark、Kafkaコンシューマー、Page State用のDynamoDB、埋め込み用のRay、そして別個のサービングレイヤーにまたがっています。
各コンポーネントは正しい役割を果たしています。隠れた税は統合面にあります。
- より多くのグルーコード
- より多くの状態の受け渡し
- オフラインとオンラインの挙動がずれる可能性の増加
この多くは、サービングのためのクローズドなストレージによって増幅されます。プロバイダー移行には完全な再インデックスが必要です。部分更新のサポートには外部の追跡テーブルが必要です。オフラインでの改善は、別の同期ステップが完了するまでオンライン検索には役立ちません。
Kappaの核はシンプルです。1つの処理モデルです。より強い形はOne Engineです。バッチとストリーミングを、接着された2つのシステムではなく、1つのシステムの2つのモードとして扱うことです。
まさにそこにLakebaseが適合します。 LakebaseはこのOne Engineの考え方をレイクネイティブな基盤にもたらし、OLTP/OLAPのギャップを埋めることで、リアルタイム更新、オンラインサービング、オフライン処理を単一のテーブル上で実行できるようにします。
3. 欠けているレイヤー: ベクトル操作のための宣言的インターフェース
Spark + 外部埋め込みAPIから統合Rayパイプラインへの移行は正しい判断です。S3を介して通信していた2つのシステムを単一のコンピュートグラフに統合することは実際の簡素化であり、埋め込みコストの90%超の削減見込みは本物のアーキテクチャ改善を反映しています。しかし、それはインフラ配線レベルでの簡素化であり、まだ欠けているのはセマンティックレベルでの簡素化です。
Hadoopの時代には、データを使って何かを行うにはMapReduceジョブを書く必要がありました。MapperとReducerのライフサイクル、シャッフルの仕組み、障害への対処、ステージの連結方法を理解しなければなりませんでした。Hiveは宣言的レイヤーを追加しました。SQLで欲しい結果を表現すると、システムがそれをMapReduce実行に変換する方法を判断します。この変化は単に処理を速くしただけではありません。そもそも誰がデータを扱えるのかを変え、新しいデータ操作のエンジニアリングコストを、分散システムを書くコストではなく、クエリを書くコストにずっと近づけました。
しかし、ベクトルデータと非構造化データには、まだこのレイヤーがありません。
- モデルトレーニングの実行前に10億ベクトルのコーパスを重複排除したい場合、Sparkジョブを書き、適切な距離計算演算子を選び、出力フォーマットを管理し、その結果をサービングレイヤーが存在する場所へ戻す方法を考え出す必要があります。
- 数億件のドキュメント全体で、ある埋め込みモデルから新しい埋め込みモデルへアップグレードしたい場合、バックフィルパイプラインを構築し、切り替え中に古い埋め込みと新しい埋め込みが共存する状態を管理し、その後クリーンアップします。そしてこのプロセスは、日常的な運用ではなく、数か月規模のエンジニアリングプロジェクトになります。
- セッションをまたいで圧縮されたユーザーメモリを維持したい場合、圧縮ロジックを設計し、バージョン付き書き込みを管理し、その出力を手作業で検索経路に組み込みます。これらの一つひとつが、データ操作ではなくシステムエンジニアリングプロジェクトです。
宣言的な同等物は、「このコレクションをコサイン許容値0.05で重複排除して結果を書き戻す」「この新しいモデルを使って埋め込みをバックフィルする」「90日より古いインタラクション履歴を密なメモリ表現に圧縮する」といった意図を表現し、システムに実行計画、リソース管理、一貫性を処理させることです。これこそが、Context Engineeringを毎回カスタムエンジニアリングプロジェクトにするのではなく、大規模に扱いやすくするレイヤーです。そしてそれは、サービングバックエンドに関係なく、現在のベクトルインフラスタックにはまだ大部分が欠けています。
| Notionの意思決定 | アーキテクチャパターン |
|---|---|
| Podクラスター → serverless → オブジェクトストレージバックエンドのserverless | ストレージとコンピュートの分離:ベクトルインデックスに適用されたライフサイクルの分離 |
| デュアルパスインデックス作成 + Page State + 世代ルーティング | リアルタイム優先のLambda設計:高速な鮮度。ただしオンライン/オフライン経路間の同期コストは上昇 |
| Spark + S3ハンドオフ → Ray | システム間I/Oの統合。ただし、その上にある宣言的インターフェースレイヤーはまだ欠けている |
ビッグデータは、ストレージ、コンピュート、処理セマンティクスが明確に分離され、組み合わせ可能なアーキテクチャへ収束するまでに15年かかりました。Notionはその弧の大部分を2年で進んでおり、これは本当に印象的です。まだ着地していない要素は、今後2年間の構築コストを大幅に下げるはずのものです。
しかし、これは第一章にすぎません
Notionが解決してきたものはすべて、1つのAI機能のためのインフラです。
これらすべてのエンジニアリング――世代ルーティング、プロバイダー移行、Page State、Rayによるコンピュート統合――は、AI Q&Aをうまく、安く、信頼性高く動かすために存在します。彼らはそれを成し遂げました。この1つの機能のためのインフラは、今や成熟しています。Notionが出荷するAI機能が1つだけで終わることはありません。
次のエンジニアリング記事で私が予想する3つの問題
問題1:大規模環境におけるserverless + コールド/ホット分離の上限
Notionの現在の選択は、現在のワークロードにとっては優れたトレードオフです。数百万のワークスペースがあり、そのほとんどはクエリ頻度が低く、S3ネイティブの経済性が強く効くからです。制約は、ここでの性能上限が、調整可能なソフトウェア上のノブよりも、オブジェクトストレージの挙動によって大きく決まることです。
S3のファーストバイトレイテンシは、多くの場合10〜100msの範囲です。コールドインデックスは、クエリ可能になる前に複数のGETリクエストとデシリアライズを必要とすることがあります。本番環境では、コールドクエリのp99が数秒台に達することがあります。これは通常、モデルの問題ではなく、インデックスのウォームアップの問題です。
主な痛点は予測可能です。
- 第一に、クエリ量が多く持続的な大規模テナントは、単一階層キャッシュの限界を感じ始めます。
- 第二に、コールドなワークスペースに戻ってきたユーザーは、目に見えるレイテンシのスパイクを経験する可能性があります。多階層キャッシュ(メモリ + ローカルSSD + オブジェクトストレージ)は、このテールの形状を、単一階層設計では通常不可能な形で変えます。
課金モデルもチームにとって意外なものになり得る。クエリのワークロードではなく名前空間のサイズに基づいて課金されるため、個々のクエリが小さなサブセットしかスキャンしない場合でも、大きなワークスペースは高額に見えることがある。偏りのあるマルチテナント分布では、支出がクエリレベルの直感から乖離する可能性がある。
フィルターのリコールも、ANN-plus-post-filter アプローチにおける潜在的な問題だ。 フィルターが狭い場合 — ページタイプ、共同編集者、期間 — 候補プールが小さくなりすぎ、リコールの低下につながることがある。Notion がフィルター付きの AI 検索経路をさらに追加するにつれて、このトレードオフはより頻繁に表面化しやすくなる。
つまり、現在のトレードオフは良いものだ。限界が明確なだけである。大規模テナントとコールドクエリのレイテンシが最初の亀裂になる。
問題 2: リアルタイム/オフラインの分断はますます高コストになっている
Notion の現在のスタック: オフラインのバッチ処理に Spark + Airflow、リアルタイム更新に Kafka consumers、埋め込みに Ray、クエリに Turbopuffer。4 つのシステムがそれぞれの役割をうまく果たし、すべて同じ基盤データ — ユーザーのページコンテンツ — に対して動作している。
これは典型的なデータサイロ構造である。同じソースデータが異なるシステムによって複数のビューとして維持され、アプリケーション層のロジックがそれらの同期を担っている。Page State の xxHash + DynamoDB は、バッチ処理ビューとリアルタイムビューの一貫性を維持するために特別に存在している。そのロジックは正しいが、その複雑さは AI 機能の数に比例して増大する。新しい機能が増えるたびに、リアルタイム経路とオフライン経路の間で維持しなければならない同期ロジックのセットがもう 1 つ追加される。
より深い問題は、オフライン処理は同期ステップなしにはオンライン serving を直接改善できない ということだ。Notion のオフラインパイプラインがワークスペース内のドキュメント間に強い意味的関係を発見したとしても、その結果がオンラインのクエリロジックから読める場所に書き込まれるまでは、それらの関係は AI Q&A 検索を改善できない。その間にはシステム境界があり、レイテンシと一貫性リスクが伴う。
これが、データフライホイールを回しにくくしている理由だ。オンライン利用から生成されるシグナルは、双方向にシステム境界を越えなければ、オフラインモデルを継続的に改善できない。
アーキテクチャ上の答えは OneData である。オンライン serving とオフライン処理が同じ基盤テーブルを共有する。同期すべき複数のビューはなく、アプリケーション層の一貫性ロジックもない。1 つの Iceberg テーブル、異なる計算モード、同じ場所への読み書き。オフライン層がオンライン層を賢くし、オンライン層がオフライン層で処理されるシグナルを生み出す。フライホイールは単一の基盤上で回る。
問題 3: オフラインのコンテキストエンジニアリング — 本当の堀が築かれる場所
現在の Notion AI: ユーザーが質問する → 関連するチャンクをリアルタイムで検索する → LLM に渡す → 回答を返す。このパイプラインの品質上限は、インデックスに何が入っているかによって決まる。
オフラインのコンテキストエンジニアリングが埋めるギャップは、クエリ時の検索品質ではない。クエリが到着する前に 何を構築しておいたかの品質である。
メモリ。 Notion AI とのすべての会話にはシグナルが含まれている。ユーザーが何を重視しているか、どのように働いているか、どの知識がその人にとって重要か。そのシグナルをベクトル化し、検索可能なユーザーメモリとして整理することは難しくない。難しいのはそれを維持することだ。古いメモリには圧縮が必要であり(6 か月前の会話はより密な表現にする必要がある)、古くなったメモリには更新が必要であり(新しいコンテンツが古い記録と矛盾する場合)、関連するメモリは階層的に整理する必要がある。これらはすべて、ベクトルデータに対する継続的なオフラインバッチ処理である。クエリ時には実行できない。
事前計算されたナレッジグラフ。 毎回新たに「このクエリに関連するドキュメントはどれか」を検索するのではなく、オフライン処理によってワークスペースのセマンティックなトポロジーのモデルを構築できます。つまり、どのドキュメントが同じ概念を扱っているのか、どの意思決定に依存関係があるのか、アイデアが時間の経過とともにどのように進化してきたのか、というモデルです。そのモデルがAIがすでに持っているコンテキストとなるため、AIはゼロから新たに検索するのではなく、あなたのワークスペースへの理解に基づいて推論します。
データフライホイール。 どの検索結果が使われたのか。満足のいく回答がないまま繰り返し出てくる質問はどれか。異なるクエリ間で繰り返し参照されるドキュメントはどれか。これらのシグナルをオフラインで処理することで、検索を継続的にチューニングできます。チャンク化戦略を調整し、関連性があることを繰り返し証明しているナレッジを浮上させ、盲点を特定するのです。シグナルをベクトルレイヤーの改善へと変換するインフラがあって初めて、フライホイールは回ります。それがなければ、シグナルはログファイル内の単なるバイトにすぎません。
Notionは、存在する中でも最も興味深いAIデータセットの一つの上に位置しています。数千万ものワークスペースにわたる、意図的に整理された構造化ナレッジです。これは並外れた原材料です。しかし、データの堀はデータを持っていることによって築かれるのではありません。データを継続的に能力へと変換するインフラを持つことによって築かれるのです。 同社の現在のベクトルインフラは、オンライン提供向けに設計されています。メモリ保守、ナレッジグラフの事前計算、シグナル処理フライホイール――これらは大規模なバッチ問題であり、現在のアーキテクチャには自然な受け皿がありません。
Lakebase Positioning
この時点で、パターンは明確です。次のボトルネックは、単一のクエリエンジンに関する意思決定ではありません。リアルタイム提供とオフライン処理の間にあるギャップです。
Vector Lakebaseは、その橋渡しとして位置づけられています。
OLTPとOLAPのための1つの統合プラットフォーム: リアルタイム提供、反復的な探索、バッチ分析が、同じレイクネイティブなデータ基盤と単一の真実のソース上で実行されます。
デュアルパス同期ではなく、1つのインクリメンタルなフロー。 変更キャプチャ、再埋め込み、再インデックス化は、アプリケーションのグルーコードではなく、データレイヤーの機能になります。
オフラインのインテリジェンスがオンラインに反映される1つの場所。 メモリ圧縮、バックフィル、品質シグナルは同じテーブルに書き戻され、提供機能を直接改善します。
これが実践的なChapter 2です。単なるより良い検索ではなく、ベクトルデータのための統合された運用モデルです。
Vector Lakebaseは、Chapter 2に対するZilliz Cloudの答えです。既存のデータレイク上での統合されたベクトルストレージ、処理、提供。移行は不要です。続報にご期待ください。
読み続けて

We spent 8 years making vector databases faster. Then we stopped.
Rarely queried embeddings still need to stay searchable. See how Vector Lakebase enables on-demand vector search without always-on compute costs.

OpenAI o1: What Developers Need to Know
In this article, we will talk about the o1 series from a developer's perspective, exploring how these models can be implemented for sophisticated use cases.

Vector Databases vs. Hierarchical Databases
Use a vector database for AI-powered similarity search; use a hierarchical database for organizing data in parent-child relationships with efficient top-down access patterns.



