👜

Vercelのコストが急増した原因がGooglebotだった

に公開

背景

  • 検索機能のあるサイトで、検索条件をパスで表現している(例:/search/area-13/category-2/page-1/limit-10
  • 検索条件は7軸あり、各軸は複数選択が可能
  • generateStaticParamsは空配列で、全URLがオンデマンド生成

課題

  • VercelのFunction Invocationsが急増していた。しかし実ユーザー数に大きな変化はなかった
  • ログを確認するとGooglebotが検索結果ページ(/search)を延々と巡回していた
  • robots.txtはuser-agent: *に対して/searchを拒否していたが、Googlebot向けの記述は別にあったため、Googlebotには適用されていなかった

下記は修正前の状態。

src/app/robots.ts
rules: [
  {
    userAgent: "Googlebot",
    allow: ["/"],
    disallow: disallowPaths,
  },
  {
    userAgent: "*",
    disallow: ["/search", ...disallowPaths],
  },
],

原因

  • robots.txtはuser-agentごとにグループが独立していて、クローラーは自分に合う1グループだけを見る。そのためGooglebotは*の記述を無視し、全許可の状態になっていた
  • 条件の各軸が複数選択できるため、組み合わせが実質無限にあり、URLも実質無限にある状態
  • ページを事前生成していないので1URLごとにFunctionが起動する。しかもアクセス頻度が少ないと思われる条件のURLも多く、キャッシュも活きない

解決法

robots.txtを下記のように修正。

src/app/robots.ts
rules: [
  {
    userAgent: "Googlebot",
    allow: ["/"],
    disallow: ["/search/*/*/*/*/*/*", ...disallowPaths],
  },
  {
    userAgent: "*",
    disallow: ["/search", ...disallowPaths],
  },
],

条件3つまでを許可し、4つ以上を拒否する形に設定。

*が6個で条件4つ以上になる理由

  • URLには必ずpage-limit-がつくので、ユーザーが設定する条件が4つのとき/search以降のセグメントは6個になる
  • 指定した/search/*/*/*/*/*/*には/が6個あるので、URL側も/が6個以上ないとマッチしない
  • robots.txtの*はスラッシュを含む0文字以上にマッチする

補足

  • いくつの条件までをクロールさせるかはSEOにも関わるため、関係者に確認の上で設定を行なった

まとめ

  • クローラーが原因でコストが急増することがあるが、設定によって防ぐことができる
  • robots.txtのuser-agentはグループごとに独立していて混ざらない。そのため「Googlebot以外は拒否」=「Googlebotだけフリーパス」という意味になってしまっていた
  • robots.txtの*/を越えてマッチするので、セグメントが7個以上のURLもまとめて対象になる
chot Inc. tech blog

Discussion