この記事では、パフォーマンスの数値を公開する前に、Aurabase で適用するプロトコルを文書化することで、特定の質問 (再現可能な方法でバックエンド API のベンチマークを行う方法) に答えます。結果ではなく、方法です。このサイトの他の場所 (特に パフォーマンスページ) ですでに公開されており、このプロトコルにまだ依存していない測定値は、追って通知があるまで未検証として扱う必要があります。
必需品
現在のところ、公開されている再現可能なプロトコルに従った Aurabase のパフォーマンス結果は存在しません。この記事では、すでに得られた結果ではなく、結果を生成するために適用する方法論について説明します。リポジトリには、すでに 3 レベルのテスト スイートが含まれています。3 つのクレートでの Criterion.rs マイクロベンチマーク、8 つの HTTP/WebSocket シナリオでの k6 負荷テスト、およびパーセンタイル計算による Postgres と API の直接比較のための Python スクリプトです。完全なプロトコル (測定期間、平均ではなくパーセンタイル、環境の分離、バージョンと日付の開示) は、検証済みの外部ソース (PostgreSQL、Criterion.rs、k6 (Grafana)、HdrHistogram、PlanetScale、Convex) に基づいています。このプロトコルを追跡せずにこのサイトの他の場所ですでに公開されているパフォーマンスに関する主張は、未検証であると見なされます。
なぜ裸の数字を公表しないのか
競合するレスポンシブ バックエンドのパブリッシャーである Convex は、同社の技術チームがデータベース プロバイダー間の「棒グラフ戦争」と呼ぶものから公に距離を置いています。彼の公式は直接的です。「スケーリング シアターであって、スケーリングではない」 — スケーリング シアターであって、実際のスケーリングではありません (stack.convex.dev/on-competitive-benchmarks、スタック技術ブログ、2026 年 8 月 23 日にアクセス)。
その中心的な議論は、整合性、トポロジ、または価格モデルの保証が異なる 2 つのシステムを比較するベンチマークは、同じことをテストしていると主張していても、多くの場合、同じことをテストしていないということです。つまり、「ベンチマークは実際には同じことをテストしていない」ということです。この反射は業界ではベンチマーケティングと呼ばれており、手法の厳密さではなく、マーケティング効果に基づいて選ばれた数字を公表します。
私たちの対応は、測定を拒否することではありません。数値の公表を無期限に拒否することは、根拠のない数値を公表するのと同じくらい不誠実です。それは、何かを測定したと主張する前に、どのように、どのツールを使用して、どのような条件で測定するかをまず文書化することです。これは、有用な比較 (検証可能なアーキテクチャの違いを文書化する Aurabase と Appwrite の比較など) を、共通のプロトコルを使用しないパフォーマンス数値の比較と区別するものでもあります。
これは、技術委員会でバックエンドの選択を擁護しなければならない技術責任者や CTO にとって特に重要です。メソッドに遡ることができない数字は、最初のややしつこい質問には耐えられません。文書化されたプロトコルは自己防衛的です。必要に応じて、スクリプトやテストされたバージョンを見せ、誰かの前でテストを再実行できます。
ほとんどのバックエンド ベンチマークが誤解を招く原因
体系的に 2 つの落とし穴が生じます。それは、報告せずに異なるトポロジーを比較すること、もう 1 つは、ユーザーにとって最も重要な一時停止を正確に隠す方法で遅延を測定することです。
最初の点では、PlanetScale はハードウェア パリティ制約を明示的に文書化しています。比較される各環境は、同じクラウド リージョン内の参照インスタンスと同等以上のコンピューティング リソース (vCPU、RAM) で実行する必要があります (Planetscale.com/benchmarks、「Telescope」方法論、2026 年 8 月 23 日にアクセス)。この規律がなければ、レイテンシのギャップは、より高速なアーキテクチャではなく、単にマシンの大型化を反映するだけになる可能性があります。
同じ原則がキャッシュ状態とネットワーク トポロジにも当てはまります。起動したばかりのインスタンス (コールド Postgres キャッシュ、空の接続プール、クエリ プランがまだキャッシュされていない) は、安定した負荷の下で 1 時間実行されているインスタンスよりも構造的に応答が遅くなります。データベースと同じリージョンからのクエリは、リージョンをまたがるクエリよりも構造的に高速に応答します。どちらも指定していない 2 つのベンチマークは、たとえ同じ単位が表示されていたとしても単純に比較できません。
2 番目の点では、この罠は調整された省略と呼ばれます。 Gil Tene によって作成されたレイテンシー測定のリファレンス プロジェクトである HdrHistogram は、このことを次のように説明しています。ロード ジェネレーターが次のリクエストを送信する前にリクエストの応答を待機するとき (閉ループ)、サービスの一時停止により、一時停止中に送信されるリクエストの数が自動的に削除されるため、記録される高レイテンシ測定の数が減少します (github.com/HdrHistogram/HdrHistogram、 2026 年 8 月 23 日にアクセス)。このプロジェクトでは、具体的かつ定量化された例を示しています。200 秒間 10 ミリ秒ごとにレイテンシをサンプリングする仮想システムでは、テストの途中で 100 秒の一時停止を 1 回行うだけで、この 1 回の一時停止で実時間の半分が経過したにもかかわらず、応答の約 99.99% が 1 ミリ秒未満に収まるように見えるヒストグラムを修正なしで生成できます。
前の応答を受信した後にのみ要求を送信する閉ループ負荷テストでは、体系的に長い一時停止が過小評価されます。表示される p99 は、実際のユーザーが経験する現実よりも優れている可能性があります。これは、システムが高速だからではなく、測定プロトコルが一時停止中にクエリの送信を「忘れた」ためです。
平均が嘘をつく理由: p50、p95、p99
20 リクエストに 1 件のリクエストに 5 倍の時間がかかる場合、平均レイテンシは優れているように見えます。これはまさにパーセンタイルが明らかにするものであり、平均が構造的に隠しているものです。
機械的には、パーセンタイルについて不思議なことは何もありません。測定されたすべてのレイテンシを昇順に並べ替えて、対応する位置の値を取得します。 1000 個の並べ替えられたクエリのうち、p50 は 500 番目の値、p95 は 950 番目、p99 は 990 番目の値です。 1000 件のリクエストのうち 1 件の異常に遅いリクエストがあれば、p99 を動かすのに十分です。この同じ孤立したリクエストが平均にほとんど影響を及ぼさない場合、p99 が役立つのはまさにまれなケースに対する感度です。
明らかな兆候: pgbench (PostgreSQL の公式ベンチマーク ツール) がデフォルトで表示するテキスト レポートでは、パーセンタイルではなく平均と標準偏差が示されます (postgresql.org/docs/current/pgbench.html、2026 年 8 月 23 日にアクセス)。公式ドキュメントでは、「数秒間だけ実行されるテストは絶対に信じないでください」と警告しています。数秒間だけ実行されるテストは決して信じないでください。これは、選択したメトリックだけでなく期間にも当てはまります。
スイートのレベル 2 に使用するロード ツールである k6 は、パーセンタイルで表されるしきい値を使用してこれを解決します。p(95)<500 構文は、合否基準を定義します。つまり、リクエストの 95% が 500 ミリ秒以内に応答する必要があります。テスト構成 (grafana.com/docs/k6、8 月 23 日に参照) 2026年)。
| p50 (中央値) | クエリの半分はこの値より高速です | 分布の尾部を完全に非表示にします |
|---|---|---|
| p95 | クエリ 20 件に 1 件が遅い | 不満を持ったユーザーが最初に現れる領域 |
| p99 | 100 件のクエリに 1 件が遅くなります | プロトコルの設計が適切でない場合、調整された省略の影響を最も受けやすくなります。 |
リポジトリにすでに存在する 3 つのベンチマーク レベル
実際のツールを使わずに方法論を発表することは、単なる演劇の形式の一つにすぎません。 Aurabase リポジトリの benchmarks/ フォルダには、公開されている Supabase 方法論に基づいた構造の 3 レベルのスイートがすでに含まれています。ツールは存在しますが、測定および日付の付いた結果はまだ存在していません。
レベル 1 — マイクロベンチマーク Criterion.rs
Cargo ワークスペース の 3 つのクレートには、専用の CPU バウンド ベンチマークがあります: aura-crypto (Argon2 ハッシュ、JWT HS256 — PostgREST、AES-GCM 暗号化の生成、検証および署名)、aura-db-adapters (PostgREST 形式のフィルターおよび select の解析 — eq.、 gte.、 in.()、リレーションシップの埋め込み)、および aura-core (JSON シリアル化、schema_name解決、UUID 検証)。
aura-db-adapters は、特に PostgREST 形式のクエリの解析コストを測定します。フィルターの場合は 4 つのケース (simple_4、 complex_10、 or_group、 in_large_50 、値が 50 個)、select の場合は 4 つ (単一列、 *、リレーション埋め込み 1 つ、埋め込み 5 つ) です。これは、グローバル負荷テストでは目に見えない種類のコストです。複雑な or.(...) フィルターの分析の回帰は、あまり使用されていないエンドポイントの p95 ではほとんど何も変化しませんが、トラフィックの多いエンドポイントでは測定可能になります。そのため、レベル 2 だけに依存するのではなく、マイクロベンチマークで分離することに関心が集まっています。
aura-core は異なるアプローチを採用しています。生の時間を測定するのではなく、ゲートウェイとサービス間で交換される内部 NatsRequest/NatsResponse メッセージの JSON シリアル化および逆シリアル化の スループット (Throughput::Bytes) を、現実的な 3 つのペイロード サイズ (最小限のリクエスト、ネストされた JSON 本体を含むリクエスト、50 行のリスト応答) で測定します。
Criterion.rs はループの時間を計測するだけではありません。まず、CPU/OS キャッシュを埋めるためのウォームアップ フェーズを実行し、(データセットから除外せずに) Tukey の方法の修正バージョンで異常値を検出し、多数のリサンプリングされたサンプルでブートストラップすることによって信頼区間を計算し、構成可能なノイズしきい値 (通常は ±1%) を使用して Student の統計検定によって 2 つの実行間のパフォーマンスの回帰を検出して、統計的に有意ではない変動を無視します (bheisler.github.io/criterion.rs/book/analysis.html、2026 年 8 月 23 日にアクセス)。
Criterion を実行するたびに、分布、回帰グラフ、前回の実行との比較などの詳細な HTML レポートが target/criterion/ で生成されます。単なる終着線ではなく、この関係こそが再生を可能にする真剣な方法論でなければなりません。
レベル 2 — k6 負荷テスト
8 つの k6 スクリプトは、データ プレーン側の ゲートウェイをカバーします: health (レイテンシ ベースライン)、auth-flow (登録 → ログイン → 更新 → ログアウト)、crud-read および crud-write、storage (アップロード/ダウンロード)、realtime-ws、breakpoint (障害が発生するまで負荷が増加) および supabase-compare。 7 つは専用の Makefile ターゲットに接続されています。supabase-compare.js はリポジトリ内に存在しますが、まだターゲットを持っていません。この記事では、その状況を偽装するのではなく、そのまま記載します。
共有構成では、操作タイプごとにしきい値を定義します。これらは、テストが実行されるたびにチェックされる合否基準であり、既に測定された結果ではありません。
| 読み取り(GET) | p95 < 500 ミリ秒 · p99 < 1000 ミリ秒 | 構成 k6 (benchmarks/k6/lib/config.js) |
|---|---|---|
| 書き込み(POST/PATCH) | p95 < 300 ms · p99 < 1000 ms | 構成 k6 |
| 認証(ログイン/更新) | p95 < 300 ms · p99 < 1000 ms | 構成 k6 |
| ストレージ(アップロード/ダウンロード) | p95 < 500 ms · p99 < 2000 ms | 構成 k6 |
| エラー率、すべてのシナリオ | < 1 % | 構成 k6 |
benchmarks/ フォルダー内の README.md には、 < 200ms (「Supabase SLO」) での読み取りしきい値 p95 が文書化されていますが、テストが実行される benchmarks/k6/lib/config.js で実際に適用されるしきい値は p(95)<500です。 2 つのファイルは相互に派生したものです。これは、この記事のソース コードを読んでいるときに見つけた、プロトコルが 2 つの場所で文書化されるのではなく、バージョン管理された信頼できる単一のソースを持つ必要がある理由を示す具体的な例です。これがないと、厳密に努めようとするチームであっても、矛盾するしきい値を公開することになります。
レベル 3 — PostgreSQL と API の直接比較
Python スクリプト (direct_vs_api.py) は、直接 psycopg2 リクエストを同じ操作 (リスト、ID による 1 回読み取り、フィルター処理および並べ替え読み取り) での HTTP 呼び出しと比較することにより、ゲートウェイ + サービス層の実際のオーバーヘッドを測定します。各測定は、タイミングループの前に 10 回の反復のウォームアップを経て、平均、p50、p95、p99、および 1 秒あたりの操作のスループットを計算します。
2 番目のスクリプト (aurabase_vs_supabase.py) は、同じウォームアップおよびパーセンタイル計算ロジックを、ローカルの Supabase インスタンス (Supabase CLI、デフォルトでは localhost:54321) との直接比較に適用します。これは、どちらも同じマシン、同じローカル ネットワークであり、PlanetScale が独自の比較のために文書化している環境パリティ規則とまったく同じです。
オーケストレーション スクリプト (collect_baseline.sh、 Makefileのターゲット bench-baseline ) は、3 つのレベル (3 つのクレートの Criterion、k6 シナリオのサブセット (今日のhealth と crud-read、まだ 8 つすべてではありません)、次に Python の比較) を接続し、ログ、JSON、および Criterion HTML レポートを一意のタイムスタンプが付いているフォルダーに書き込みます。 benchmarks/results/AAAAMMJJ_HHMMSS/。これはまさに、次のセクションで完全なプロトコルとして形式化した、単一の再現可能な実行における日付の開示の反映です。
Figure を公開する前に適用するプロトコル
8 つの取り組み。それぞれは、認知されたサードパーティのツールまたはプロジェクトによってすでに文書化されている実践に基づいていますが、この機会のために考案されたものではありません。
- 測定とは別に予熱を行います。 Criterion.rs はタイミングを計る前に CPU/OS キャッシュを埋めます。
pgbenchは、ほんの数秒続く実行を決して信じないことを明示的に推奨しています。 - 反復回数は固定ではなく、期間は固定です。 負荷が収束するまでには時間が必要です。これは、
stagesk6 とpgbenchの-Tフラグの役割です。 - パーセンタイル。単なる平均 ではありません。ロード ジェネレーターが閉ループで動作する場合は、調整された省略に対して積極的に警戒します。
- 環境の詳細が文書化されています: テストされたサービスの git コミット、PostgreSQL のバージョン、ハードウェア仕様、ロード ツールのバージョン。 PlanetScale は、まさにこの理由から、正確な TPCC パラメーター (
TABLES=20、SCALE=250、~500 GB) を文書化しています。これらの詳細がなければ、誰も実行を再現できません。 - タイムスタンプとバージョン管理された結果。日付のない単一の数字がマーケティング ページに刻まれることはありません。現在のツールはすでに日付の付いたファイルに書き込まれています。他の環境変数と同様にホスティング地域を文書化して、この反射を公的に公開された測定値に拡張する必要があります (数値が特定の地域に依存するとすぐに関連する EU ホスティング主権に関するガイドを参照してください)。
- 最終的な平均値だけでなく、集計結果とともにスクリプトと生データが公開されます。 PlanetScale は、方法論上の誤りを専用のアドレスで報告するよう読者に勧めています。これは私たちが健全であると考えており、再開したいと考えている姿勢です。
- どちらか一方だけではなく、遅延と併せて宣伝されるスループット。 システムは、低負荷では優れたレイテンシを持ち、同時実行性が増加するとスループットが低下する可能性があります。これはまさに、k6 スイートの
breakpointシナリオ (スケールからクラッシュまで) が明らかにするように設計されていること、および Criterion のThroughput::Bytesマイクロベンチマーク測定が機能レベルで捉えていることです。 - 改善を発表するまでに大きなギャップ。 2 つの実行間の数パーセントの変動は、実際のゲインではなく測定ノイズである可能性があります。Criterion.rs は、観察された差が回帰または改善であると認定する前に、偶然によるものである確率を計算します。この検証がなければ、孤立した数字は単なる統計上の逸話にすぎません。
私たちがやらないこと
このリストは、上記の陽性プロトコルと同じくらい重要です。
- 明示的に報告せずに、さまざまなトポロジ (セルフホスト型インスタンスとマネージド型インスタンス、コールド インスタンスとプレヒート インスタンス) を比較します。
- 他の 9 には言及せずに、10 のうち最良のランを保持します。
- 日付なし、サービス バージョンなし、複製スクリプトなしの図を公開します。
- このプロトコルに遡らない限り、既存のマーケティング数値を再発行します。
- 競合他社が同等の方法で独自の方法論を公開していない場合、生のパフォーマンス数値で競合他社と自社を比較することは、数値と沈黙は比較ではなく、スローガンです。
「コールド スタートは 1 ミリ秒未満」などの数値が、再現可能なベンチマークの裏付けなしに流布されました。現在、これは内部的に サポートされていない として扱われており、公開された方法論による日付の測定によって確認されるまで、製品の測定された特性として読み取られるべきではありません。これはまさに、このプロトコルが繰り返されるのを防ぐために存在するという類の主張です。
あらゆるバックエンドをベンチマークするための最小限のプロトコル
このプロトコルは特定の Aurabase ツールに依存しません。今すぐ独自の API に適用できます。
- ツールの前に負荷を設定します。読み取り専用、書き込み、アプリケーションの現実的な組み合わせ — 別のプロジェクトからコピーした一般的な比率ではありません。
- 予熱フェーズを測定フェーズから明示的に分離します。
- テストは十分な時間 (秒ではなく分) 実行してください。
- 決して平均だけではなく、パーセンタイル (p50/p95/p99) で測定します。
- ロード ジェネレーターが閉ループになっていないことを確認するか、解析での調整漏れを修正してください。
- テスト対象の環境を隔離します。騒々しい隣人や競合するバックグラウンド タスクは存在しません。
- 最終結果だけでなく、テストしたバージョン、日付、ハードウェア仕様、スクリプトも公開します。
ベア Postgres ベースでは、このプロトコルは 1 つのコマンド pgbench を実行します。20 の同時クライアントが 4 つのスレッドに分散され、5 分間、10 秒ごとに進行状況レポートが表示されます。
レベル別のリファレンス ツール
スタックの異なるレベルにそれぞれ適した 5 つのツール。他のツールに代わるものはありません。
| マイク(機能) | Criterion.rs | 純粋な CPU、ブートストラップ統計 |
|---|---|---|
| SQLクエリ | pgベンチ | TPC-B のようなトランザクション、tps、レイテンシ |
| HTTP/WS負荷 | k6 (グラファナ) | パーセンタイル、合格/不合格のしきい値 |
| 大規模な OLTP | sysbench + TPCC (望遠鏡手法) | QPS、パフォーマンスあたりのコスト |
| 測定値補正 | Hdrヒストグラム | 調整された省略を補う |