YouBaseをCloudflare Workersで構築した理由
ホーム / ブログ / プロダクトアップデート / YouBaseをCloudflare Workers上に構築した理由 YouBaseをCloudflare Workers上に構築した理由 私たちはYouBaseを構築しました。これはAIコーディングエージェントがフルスタックWebアプリケーションをデプロイ・管理できるPlatform-as-a-Serviceです。単にAPIを呼び出すだけでなく、実際にコードを書き、リリースし、テストし、反復し、再デプロイできます。VercelやHerokuのようなものですが、「開発者」はClaudeやGPTです。
技術的な課題は最初から明らかでした。AIエージェントの反復は速い。コードをデプロイし、エンドポイントにアクセスし、エラーを受け取り、修正し、再デプロイする——1時間に数十回行うこともあります。従来のプラットフォームはそのような密なフィードバックループには設計されていません。秒単位で完了するデプロイ、デフォルトでのグローバル配信、そして強固なマルチテナント分離が必要でした。デプロイされるコードは信頼されておらず、オンザフライで生成されるためです。
また、オーケストレーションシステム、レプリケーションレイヤー、マルチテナント分離フレームワークをゼロから構築したくありませんでした。
私たちはCloudflare Workers を選択し、約2ヶ月で本番環境にリリースしました。
リリースから2週間後、すべてのアクティブなテナントWorkerのバリデーションロジックを更新する必要が生じました。従来のプラットフォームでは、協調したローリングデプロイ、段階的なロールアウト、そして長い尾を引く残留タスクが必要だったでしょう。私たちの構成では、単一のService Bindings Workerを再デプロイしました。約30秒後、すべてのテナントがダウンタイムなし・テナント再デプロイなしで新しいロジックを実行していました。これがアーキテクチャが理論から現実になった瞬間でした。
アーキテクチャ概要
YouBaseはハイブリッドアーキテクチャで動作します。コントロールプレーン(Go、PostgreSQL、Redis、Lambdaなど)はプロジェクト作成、デプロイ、課金、管理を担います。データプレーンはCloudflare Workers上で完全に動作します。
各プロジェクトは専用のD1データベースと専用のR2バケットを持つ独自のWorkerを取得します。共有データベースも共有ストレージもありません。バインディングはテナントごとなので、あるWorkerが誤動作しても、別のテナントの状態にアクセスすることはできません。
ディスパッチャーWorkerは、KVに保存されたドメインマッピングを使用して受信リクエストを正しいテナントWorkerにルーティングします。また、バリデーション、課金ルール、フレームワークユーティリティ、フィーチャーフラグを含む共通ロジックをService Bindingsを通じて提供する共有Workerも実行しています。
リージョン、レプリカ、ノードプールは管理しません。すべてが300以上のCloudflareロケーションで自動的に実行されます。
Cloudflareの肩の上に立つ
真のマルチテナンシーが必要でした。Kubernetesを使用した場合、ネットワークポリシー、テナントごとのポッド、リソースクォータ、シークレット管理、テナントごとのデータベース、そして多くの運用オーバーヘッドが必要になっていたでしょう。
Workers for Platformsは、ネイティブランタイム機能としてマルチテナント分離を提供します。各ワークスペースは独自のWorkersとバインディングを持つディスパッチネームスペースを取得します。ディスパッチャーはKVからドメインマッピングを読み取り、正しいWorkerにリクエストを転送します:
© 2026 YOUWARE
YouWareにメッセージを送信することで、 YouWareにメッセージを送信することで、利用規約とポリシーに同意したことになります。 利用規約 and ポリシー .
const workerName = getWorkerNameFromHostname(url.hostname);
const dispatcher = getDispatcher(url.hostname, env);
const backendWorker = dispatcher.get(workerName);
return await backendWorker.fetch(request);
各WorkerはV8アイソレート内で実行されます。テナントはお互いのバインディングやメモリにアクセスできません。共有ファイルシステムも共有環境もありません。
驚いたのは分離そのものではなく、設定する必要のあるインフラがいかに少なかったかという点でした。クラスターをプロビジョニングしませんでした。ネットワークを設定しませんでした。リージョンを選びませんでした。ネームスペースを作成し、Workersをデプロイしただけです。
ここでの主な摩擦はネームスペースルーティングのデバッグでした。ディスパッチパスの失敗は、スタックコンテキストが限られた汎用フェッチエラーとして表れることが多くありました。ディスパッチャーからテナントWorker、共有Workerまでリクエストをトレースできるように、相関ヘッダーを追加することにしました。
その粗い点があったとしても、このアプローチは信頼されていない生成コードのためにKubernetesを実行するよりも劇的にシンプルでした。
D1 + Session API:エッジでの一貫性 エッジデータベースは一貫性をレイテンシーと引き換えにすることが多く、そのトレードオフは私たちのユースケースでは許容できませんでした。
D1のSession APIはブックマークでこれを解決します。各書き込みの後、データベースはブックマーク(トランザクションログ位置)を返します。次のリクエストでそのブックマークを送信すると、D1は自分の書き込みを読めることを保証します:
const BOOKMARK_HEADER = "x-es-sticky-session-db-bookmark";
const bookmark = request.headers.get(BOOKMARK_HEADER) || "first-primary";
const session = env.D1.withSession(bookmark);
response.headers.set(BOOKMARK_HEADER, session.getBookmark());
リクエストヘッダーを通じてブックマークを渡します。フレームワークはそれらを抽出し、D1セッションを作成し、クエリを実行し、新しいブックマークを返します。
これにより、コーディネーションサーバーなしで強力なread-after-write保証が得られます。一貫性のためにすべての書き込みはプライマリに送られます。速度のために読み取りは最寄りのレプリカに送られます。レプリカがまだあなたのブックマークに追いついていない場合は待機します。
運用面では、PostgreSQLレプリカを管理し、リージョン間でのレプリケーションラグをデバッグするよりもはるかにシンプルでした。
Service Bindings:即時更新を伴う共有ロジック Workerの数が増えるにつれて、共有ロジックの更新が最も心配な運用上の問題でした。
セキュリティルール。バリデーション。課金。レートリミット。フィーチャーフラグ。
従来の答えはすべてのテナントWorkerへのローリングアップグレードです。
Service Bindingsにより、テナントWorkerがネイティブRPCを通じて呼び出す単一の共有Workerを実行できます。HTTPレイヤーなし、トークン認証なし、オーバーヘッドはサブミリ秒です。
この共有Workerを以下のために使用しています:
SQLバリデーション
課金計算
レートリミット
フィーチャーフラグ
フレームワークユーティリティ
コアビジネスルール
その他の共有インフラに関する懸念
このWorkerを更新すると、すべてのテナントが即座に新しい動作を確認します。
これが運用上の負担のほとんどを除去した部分です。今日、テナントリクエストの大部分がService Bindingsを通じて流れています。
オブザーバビリティ:Tail WorkersとAnalytics Engine ユーザーにログを計装するよう依頼することはできませんでした。AIエージェントはクラッシュしたり、ループしたり、奇妙な動作をするコードを生成します。「すぐに使える」ログとメトリクスが必要でした。
Tail Workersはコンソール出力、例外、リクエストメタデータ、タイミング情報をキャプチャします。これらのイベントをバッファリングし、SSEを通じてクライアントにストリーミングするインジェストサービスを構築しました。ユーザーはedgespark log tailを実行し、サブ秒のレイテンシーでライブ出力を確認できます。
Analytics Engineはメトリクス側をカバーします。プロジェクトごと、ドメインごと、エンドポイントごとのディメンションを追跡します。従来のシステムはそのレベルのカーディナリティでは機能しなくなります。
env.ANALYTICS_ENGINE.writeDataPoint({
blobs: [projectId, environment, customDomain, method, status],
doubles: [cpuTimeMs, wallTimeMs],
indexes: [endpoint]
});
書き込みはノンブロッキングで、カーディナリティの爆発なしにSQLを通じて結果をクエリできます。
これをダッシュボード、課金、使用レポート、レートリミットに使用しています。
サポートインフラ:R2とKV R2はS3互換のオブジェクトストレージを提供します。各プロジェクトは専用のバケットを取得します。署名付きURL、マルチパートアップロード、ストリーミングはすべて期待通りに動作します。
KVはドメインからWorkerへのルーティングマッピングを保存します。ディスパッチャーはすべてのリクエストでKVをクエリし、更新は数秒以内にグローバルに伝播します。
統合プラットフォームが重要な理由 この統合が実際に重要だったのは、Lambda、RDS、S3、API Gatewayを繋ぎ合わせるのに何週間も費やさなかったからです。接続プーリングロジックを書いたり、VPCエンドポイントを設定したりしませんでした。サービス間のIAMポリシーを設定したり、メトリクス用の独自の時系列データベースを実行したりしませんでした。
Workersはバインディングを通じてD1とR2を呼び出します。Service BindingsはネイティブRPCでWorkersを接続します。KVはルーティングを処理します。Tail Workersはログをキャプチャします。Analytics Engineはメトリクスを取り込みます。各部品がきれいに組み合わさります。
実際には、その2ヶ月のほとんどをインフラではなくプロダクトの構築に費やすことができました。
技術的な学び エッジでのSQLiteには懐疑的でしたが、Session APIを持つD1は私たちの考えを覆しました。PostgreSQLレプリカよりも少ない運用複雑性でグローバルで一貫したデータを提供してくれました。
マルチテナンシーはアーキテクチャの問題ではなく、設定の問題になりました。ランタイムがV8アイソレートとディスパッチネームスペースを通じて分離をサポートする場合、自分で分離を構築する必要はありません。
Service Bindingsは共有ロジックの更新という運用上の問題を解決しました。1回のデプロイで、すべてのテナントのセキュリティルール、ユーティリティ、コア機能が更新されます。
プラットフォームの制約が実際に私たちの設計を改善しました。長時間実行プロセスなし。ファイルシステムなし。PostgresではなくSQLite。これらの制約により、よりシンプルで信頼性の高いパターンへと向かいました。
難しかったのはCloudflare自体ではなく、それにコミットすることでした。 本番環境の問題をデバッグするよりも、代替手段の評価に多くの時間を費やしました。
オブザーバビリティには何週間もかかると予想していました。Tail WorkersとAnalytics Engineのおかげで数日で稼働できました。
分散Workersのデバッグは予想以上に困難でした。ツールは従来のサーバー環境ほど成熟していません。しかし、運用のシンプルさというトレードオフは価値があります。
現在の制限 D1にはデータベースあたり10GBの制限があります。ほとんどの本番アプリケーションではうまく機能しますが、データ量の多いワークロードには適しません。
WorkersにはHTTPリクエストごとに300秒のCPU時間制限があります。長時間実行タスクには非同期パターンまたはバックグラウンド処理が必要です。
WebSocketsは永続的な状態のためにDurable Objectsが必要です。現在のアーキテクチャはリクエスト-レスポンスのみなので、プレゼンスやライブカーソルなどのリアルタイム機能には追加インフラが必要です。
ライブテールは現在ステージング環境のみをサポートしています。本番ログの保持とクエリには別のストレージとインデックスシステムが必要です。
これらは現在私たちが対応しているプラットフォームの制約です。
今後のロードマップ データベースクリーンアップ、レポート生成、通知バッチングなどのスケジュールされたバックグラウンドジョブのためにCron Triggersを統合しています。
リアルタイムコラボレーションのために、WebSocket処理、プレゼンスシステム、状態同期のためのDurable Objectsを評価しています。
データ量の多いアプリケーションをサポートするために、PostgreSQLとMySQLのサポートを追加しており、テナントWorkerがセキュアなプーリングを通じて外部データベースにアクセスできるようにしています。
APIエンドポイントの人気度、機能の使用状況、エラーパターンなど、より高レベルのビジネスメトリクスのためのAnalytics Engine使用も拡大しています。
エッジデータプレーンはすでにグローバルにスケールしています。これらの取り組みは、基礎となるプリミティブが進化し続ける中で、コントロールプレーンの機能と残りのプラットフォームのギャップに焦点を当てています。
まとめ プロダクトをリリースする前にインフラに6ヶ月を費やしたくなかったため、YouBaseをCloudflare Workers上に構築しました。2ヶ月後、ミリ秒のコールドスタート、エッジでの一貫した読み取り、自動的なオブザーバビリティを持つ本番環境にいました。
まだ粗い部分はあります。分散Workersのデバッグはモノリスのデバッグよりも難しく、いくつかのプラットフォーム制限には回避策が必要です。Workersがまだ完全に適合していない領域ではハイブリッドソリューションを構築しています。
しかし、リリース以来コアインフラを再構築する必要はありませんでした。今のところ、設計したワークロードに対応できています。すべてのテナントにわたる更新が必要だったとき、約30秒かかりました。そのトレードオフこそが重要なものでした。
技術的付録:使用したCloudflareテクノロジー
Cloudflare Workers – V8アイソレートベースのエッジでのサーバーレスコンピューティング
Workers for Platforms – ディスパッチネームスペースを持つマルチテナントWorkerデプロイ
Cloudflare D1 – 一貫性のためのSession APIを持つSQLiteベースのエッジデータベース
Cloudflare R2 – グローバルエッジアクセスを持つS3互換オブジェクトストレージ
Cloudflare Service Bindings – 低レイテンシーRPCスタイルのWorker間通信
Cloudflare KV – ドメインルーティング用のキーバリューストレージ
Tail Workers – リアルタイムログストリーミングとオブザーバビリティ
Analytics Engine – SQLクエリによる無制限カーディナリティメトリクス
ランタイム: HertzフレームワークのGo
データベース: コントロールプレーン状態のためのPostgreSQL
キャッシュ: セッションとレートリミットのためのRedis
サーバーレス: 非同期タスクのためのAWS Lambda
HTTPフレームワーク: Hono(軽量、エッジ最適化)
ORM: Drizzle ORM(D1アダプターを持つタイプセーフSQL)
認証: ネイティブD1サポートを持つBetter Auth