Astroでブログ作成してみた話 -技術編-
Next.jsばっかりやってたけどAstroでブログ作ってみたら爆速すぎた!1.5秒でビルド完了、設定不要でMarkdown対応、画像最適化も自動。個人ブログ作るならNext.jsよりAstroの方が圧倒的に楽だったので、実際の開発体験と選んだ理由を話します。
「ついさっきまでは普通にビルドが通っていたのに、なぜかPV数が取得できなくなってしまった…」
GA4 Data APIを使ってブログにPV数を表示している方には唐突なホラーかもしれませんが、
実は先日、まさにこの状況に遭遇しました。
原因を調べていくと、どうやら「サーバーエラークォータ」という制限に引っかかっていたことが分かりました。
この記事では、実際に体験したトラブルの経緯と、GA4 Data API 無料枠のクォータ制限の全体像、そして対策を備忘録としてまとめます。
同じエラーに遭遇して困っている方の参考になれば嬉しいです〜。
本記事は上記の環境で検証しています。
いつも通り npm run build を実行したら、こんなエラーが出ました。
❌ GA4 Data API エラー: データ取得に失敗しました
詳細: 8 RESOURCE_EXHAUSTED: Exhausted server errors quota.
This quota tokens will return in under an hour.
ビルド自体は完走するのですが、GA4からのデータ取得が全滅。
PV数が全て0になってしまう状態です。
なんだこれは???最近ブログをサボっていた天罰か???
サボりすぎてPV数すら没収されるほどの状態になってしまったのか…。
悲しい気持ちになりつつとりあえずはざっと構成を振り返りました。
このブログでは、ビルド時にGA4 Data API v1を使ってPVデータを取得しています。
具体的には、astro.config.mjs にViteプラグインとして仮想モジュールを定義して、ビルド開始時に @google-analytics/data の BetaAnalyticsDataClient で3つのAPIリクエストを Promise.all で並列実行しています。
取得したデータは仮想モジュール(virtual:ga4-data)にキャッシュされて、各Astroコンポーネントから import して使い回す仕組みです。
つまり、1回のビルドでAPIリクエストは3回だけ。何度もAPIを叩くような構成ではないので相当分のビルドをぶん回してもリクエスト上限には引っかからないはずなのに…。
「何か壊した?」と思って、まず確認したのはこのあたりです。
.env を確認したが問題なしどれも該当しませんでした。
そこで、改めてエラーメッセージをよく読んでみました。
RESOURCE_EXHAUSTED: Exhausted server errors quota.
「server errors quota」…?
自分のリクエスト回数が多すぎるのではなく、サーバーエラーのクォータが枯渇しているということのようです。
これは調べてみる必要がありそうだと思い、公式ドキュメントを確認してみました。
Google公式のクォータドキュメントを読んでみたら、思っていたよりも多くの制限があることが分かりました。
| クォータ種別 | 無料(Standard) | 有料(Analytics 360) | リセット |
|---|---|---|---|
| トークン / プロパティ / 日 | 200,000 | 2,000,000 | 毎日 午前0時(PST) |
| トークン / プロパティ / 時 | 40,000 | 400,000 | 1時間以内 |
| トークン / プロジェクト / プロパティ / 時 | 14,000 | 140,000 | 1時間以内 |
| 同時リクエスト数 / プロパティ | 10 | 10 | — |
| サーバーエラー / プロジェクト / プロパティ / 時 | 10 | 10 | 1時間以内 |
有料版(Analytics 360)はトークン系が10倍ですが、注目すべきはサーバーエラークォータは有料でも同じ10回という点です。
「トークン」と聞くとAI系のトークンを想像してしまいますが、GA4 APIではリクエストの複雑さに応じて消費されるポイントのようなものです。
公式ドキュメントによると、ほとんどのリクエストは10トークン以下で済みます。
私のブログの場合だと、こんな計算になります。
トークン数だけ見れば、個人ブログで枯渇することはまずありません。
じゃあなんでエラーになったの?
トークンの問題じゃなくて、「サーバーエラークォータ」が原因でした。
ここが今回のエラー原因です。
GA4 Data APIには、Google側でサーバーエラー(500/503)が発生した回数をカウントするクォータがあります。
これが「サーバーエラークォータ」です。
仕組みはこうです。
サーバーエラークォータは、自分のリクエスト回数とは関係ありません。Google側が一時的に不安定だった時に、たまたまリクエストが重なるとカウントが溜まります。
そして厄介なのが、クォータが枯渇した後の挙動です。
正常なリクエストも含めて全てブロックされます。Google側のサーバーが回復していても、クォータが回復するまではリクエストが通りません。
振り返ってみると、原因はClaude Codeで色々な開発を半自動的に回していたことでした。
私は普段、Claude Code(AIコーディングツール)を使って機能追加やリファクタリングなどの開発作業を進めています。
その過程で、動作確認のために npm run build を何も考えずにぽちぽち承認してました。
手動で何回もリトライしたわけではなく、開発フローの中で自然とビルドが積み重なっていたのがポイントです。
1ビルド3リクエストなので、ビルドが3〜4回走るだけでサーバーエラークォータの上限に届いてしまいます。
ビルドのたびにAPIを叩くと、開発のテンポが上がるほどクォータを消費しやすくなり良くないですね
(⬆️そもそもbuildしなくて良いとこしてたのもありちゃんと整備しろという話)
RESOURCE_EXHAUSTED エラーには実はいくつかの種類があります。
エラーメッセージを見れば、どのクォータに引っかかっているのか判断できます。
| エラーメッセージ | 原因 | 対処法 |
|---|---|---|
| Exhausted tokens quota | トークン消費量の上限に到達 | リクエストの最適化 or 時間をおいて待機 |
| Exhausted server errors quota | Google側のサーバーエラーが累積 | 1時間待つ(リトライ厳禁) |
| Exhausted concurrent requests quota | 同時リクエスト数の超過 | 並列リクエスト数を減らす |
今回引っかかったのは2番目の「server errors quota」です。
「tokens」なのか「server errors」なのかで対処法がまったく違うので、エラーメッセージはしっかり読みましょう(自戒を込めて)。
一番大切なのは、焦ってリトライしないことです。
エラーメッセージに This quota tokens will return in under an hour. と書いてある通り、1時間待てば自動的に回復します。
❌ ビルド失敗 → すぐ再ビルド → また失敗 → また再ビルド → 完全にブロック
✅ ビルド失敗 → エラーログ確認 → RESOURCE_EXHAUSTED → 1時間待つ → 回復
「待つだけ」というのはもどかしいですが、これが最善の対処法です。
「1時間も待てない」「ビルドを止めたくない」という場合は、前回取得したデータをローカルにキャッシュしておいて、API失敗時にフォールバックする仕組みが有効です。
考え方としてはこんなイメージです。
// API成功時 → データをJSONファイルに保存
// API失敗時 → 保存済みのJSONファイルから読み込み
async function fetchGA4DataWithFallback() {
try {
const data = await fetchFromGA4API();
// 成功したらキャッシュに保存
await saveCache(data);
return data;
} catch (error) {
console.warn('GA4 API失敗、キャッシュからフォールバックします');
return await loadCache();
}
}
PV数は数時間で劇的に変わるものでもないので、前回のデータで代用しても実用上はほぼ問題ありません。
CI/CDで自動ビルドをしている場合は、ビルド頻度にも注意が必要です。
私のブログの場合、1ビルドで3リクエストなので、トークン数は余裕があります。
ただし、Google側が不安定な時間帯にCIが何度もビルドを走らせると、サーバーエラーが累積するリスクがあります。
こうした工夫をしておくと、安心してCI/CDを回せます。
今回の体験で学んだことをまとめます。
RESOURCE_EXHAUSTED エラーが出たら、まずエラーメッセージを読んで種類を見分ける個人ブログでGA4 Data APIを使う分には、無料枠で全く問題ありません。
ただ、今回のようにGoogle側の一時的な不調 × リトライの繰り返しで引っかかることがあるので、「サーバーエラークォータ10回/時」という数字だけは覚えておくと良いですよ。
同じエラーで困っている方の参考になれば嬉しいです。
参考リンク:
読んでくれてありがとう。よかったらシェアやフォロー押してってください。Xで雑に絡んでくれるのも普通に嬉しい。