sixty

何のためのものか

1ページで、数十回のデータベース呼び出し

以前は速かった一覧ページが、いまは1〜2秒かかる。しかもリストが伸びるほどひどくなる。個々のクエリを確認すると、どれも問題なさそうに見える。10件なら平気で、100件だと駄目。

なぜ見えにくいのか

これは N+1 で、レンダーの内側で生まれます。何かが一覧を取得し、その各要素について関連レコードを取得する。個々のクエリは本当に速いので、リクエスト単位の計測では捕まらず、レビューも通ってしまいます — コードはまったく自然に読めるからです。間違っているのは回数だけ。

機能追加よりリファクタリングと一緒に来ることが多い欠陥です。取得処理を「1行につき1回描画されるコンポーネント」の中へ移すのは1行の変更で、それが1本のクエリを行数と同じ本数に変えます。

Sixty は何をするのか

データベース呼び出しはレンダーごとに数え、リリース間で比較します。だから検出結果は「この操作は1レンダーあたり1本だったクエリが、このデプロイ以降14本になっている」であって、解釈の必要な遅延の数値ではありません。スタックフレームも一緒に届くので、原因のレンダーが名指しされます。

その証拠は MCP 経由でコーディングエージェントに渡ります。クエリ、フレーム、前後の回数、そして変化の内訳となる子呼び出し。

できないこと

レンダーごとの呼び出し回数を数えるにはサーバーエージェントが必要で、Node、Python、Go、Ruby、PHP 用にあります。ただし頼まなくても済むのは Node だけです。Node はビルド時の変換で、エクスポートされた非同期関数ごとに自動でスパンを開きます。それ以外では計測する価値のあるコードに印を付け(Python ならデコレータ、Go なら2行、Ruby ならモジュールの取り込み、PHP なら1回の呼び出し)、その後の帰属は同じです。Java、.NET、Rust、Elixir にはエージェントがありません。ブラウザ側はどんなバックエンドでも動きますが、ページ自身が要求したものしか見えません。

OpenTelemetry

OpenTelemetry をすでに使っていますか?

現在の Collector と exporter はそのまま使えます。Sixty は接続された trace と有用な runtime metric を取り込み、release regression を推論します。対応する native agent があれば、function と DB driver の詳細がさらに得られます。

OpenTelemetry Collector を接続 →

関連

最後の変更が何をしたのか、確かめてください。

ログイン
Next.js の N+1:1ページが数十回のクエリを出す — Sixty