Upgrade to Pro — share decks privately, control downloads, hide ads and more …

1MBの壁にぶつかった話

Avatar for 赤神青空 赤神青空
September 03, 2026

 1MBの壁にぶつかった話

Avatar for 赤神青空

赤神青空

September 03, 2026

More Decks by 赤神青空

Other Decks in Programming

Transcript

  1. ▪アンケートの集計ツール/NestJS 前提:本番だけ Data API を挟んでいる + TypeORM + Aurora ローカル開発環境

    Docker の PostgreSQL に通常のドライバで直結 結果セットのサイズ上限がない だから、このバグは一度も再現しない 本番環境 Lambda から Data API 経由で Aurora へ VPC 内に Lambda を置かずに済む構成 1クエリの結果セットは 1MB まで この一点の差だけが、今日の話の全てです。 今ココ 前提 2/10
  2. ▪コードから立てた仮説は、どれも「形は合っている」 外れた仮説 500 が返る経路として、まず2つを疑った。 どちらも、症状の形とは矛盾していなかった。 01 02 判定が failure だと例外

    → そのまま 500。「403 ではなく 500」と 形が合う 前日に修正を2件入れていた。調べたら dev 止まりで本番未反映だ った 認可ライブラリ 今ココ 調査 デプロイ不整合 4/10
  3. ▪本番の ログ1行で確定した Lambda ロググループに、同じ例外が繰り返し出ていた The result exceeds the size limit

    1 MB. Data API の仕様 1クエリの結果セットは 1MB まで。超えると API が 400 を 返す。 設定では変えられない Data API 側の固定値。結果サイズを減らして下回らせるし かない。 フレームワークがこの例外を拾えず、そのまま 500 になって画面に出ていた。 今ココ 真因 5/10
  4. ▪552 行 既定では、1本の LEFT JOIN になる = 46 回答 ×

    12 設問。各行に回答データが丸ごと乗る 意図している姿 実際に返ってきたもの 46 件 552 行(46 回答 × 12 設問) 回答 ︙ 回答A 回答データ 4.8KB 設問1 回答データ 4.8KB 回答B 回答データ 4.8KB 設問2 回答データ 4.8KB 設問3 回答データ 4.8KB 設問4 回答データ 4.8KB 合計 220KB 設問への回答 LEFT JOIN 552 行 値だけの軽い行 ︙ 同じ回答データが 552 回コピーされる 結果セットのサイズ(概算) 上限 1MB ︙ 概算 2.5MB 回答データは 46 個ぶんだけ 1MB を超えた瞬間に Data API が 400 1MB に対して十分に軽い アプリ側は拾えず、そのまま 500 1行に付いている重い荷物が、552回コピーされている(2.5MB は概算) 今ココ 真因 7/10
  5. ▪まだ答えていない設問には、行がそもそも存在しない 伏線回収:このバグは時間とともに発症する 行が増える → 回答が集まる 行が増える → 回答データの複製も 閾値へ 設問が埋まっていく

    昼は開けたのに夜は落ちた その日のうちに回答が集まり、閾値を越 えた。 今ココ 真因 その分だけ増える 壊れ方が特殊 リリースを疑っても、原因はそこにな い。 突然 500 デプロイなしで 壊れる 静かに近づく 動いているうちは、誰も気づけない。 8/10
  6. ▪上限は変えられないので、結果サイズを減らす 直し方 01 直積をやめる(relationLoadStrategy) テーブルごとに別クエリで取らせる。552行 → 46行 + 軽い552行に分かれ、掛け算の構造が消える。 02

    重いカラムを読まない(射影) 一覧が使うのは受付番号と回答者名だけ。必要な列だけ取ると1件 数KB → 百数十バイト。余裕が2桁変わる。 03 それでも上限との距離は残る 設問への回答は 回答件数 × 設問数 で育つ。12設問なら回答800件規模で再び当たる(概算)。 今ココ 対処 9/10