Column

コラム

  • 【テックコラム】Gemini の 429 エラー対策まとめ...

【テックコラム】Gemini の 429 エラー対策まとめ

はじめに

こんにちは!DataCurrent の奥村です。 Gemini を本番運用していると、避けて通れないのが 429(Resource Exceeded)エラーです。本記事では、429 エラーの意味と、それを回避するためのベストプラクティスをご紹介します。 なお、本記事の内容は 2026 年 6 月執筆時点の情報です。料金や仕様は変更される可能性があるため、最新の情報は公式ドキュメントをご確認ください。

429 エラーとは

Gemini の 429 エラーは、固定の上限(Hard Limit)に達したという意味ではなく、共有プール内で一時的に需要が供給を上回った「リソース競合状態」を示します。つまり恒久的なエラーではないため、適切に対処すれば成功させられる可能性が高いリクエストです。主な対策は以下の 3 つです。

  • リトライ処理:切り捨て型指数バックオフによるリトライを実装する
  • グローバルエンドポイント:リージョナルエンドポイントよりも高いレートを利用する
  • 消費オプションの使い分け:Priority PayGo やバッチ予測 API などを用途に合わせて活用する

順番に見ていきます。

対策 1:指数バックオフによるリトライ処理

429 は一時的な競合状態のため、少し待ってからリトライするだけで成功することが多いです。このとき推奨されるのが、リトライのたびに待機時間を指数的に伸ばしていく指数バックオフ(Exponential Backoff)です。具体的な実装は後述のサンプルコードでご紹介します。

対策 2:グローバルエンドポイント

Gemini Enterprise Agent Platform では、リクエスト先のロケーションに global を指定できます。グローバルエンドポイントはリージョンをまたいでキャパシティを考慮したルーティングを行うため、リージョンエンドポイントと比べて高い可用性・低いエラー率を実現でき、429 の発生自体を減らせます。

client = genai.Client(vertexai=True, project="YOUR_PROJECT_ID", location="global")

注意点として、グローバルエンドポイントでは特定の(マルチ)リージョン内での ML 処理は保証されません。データ所在地の要件がある場合はリージョンエンドポイントを使用してください。また、グローバルエンドポイントに対応していないモデルもあるため、使用するモデルが対応しているかを事前にご確認ください。

対策 3:消費オプションの使い分け

Gemini Enterprise Agent Platform には、トラフィックパターンに合わせた複数の消費オプションが用意されています。

オプション料金(標準比)特徴
Standard PayGo1 倍既定の従量課金。混雑時は大規模送信者からスロットリング
Flex約 0.5 倍応答時間非保証(タイムアウト最大 30 分)。コスト重視の処理向け
Batch約 0.5 倍非同期・約 24 時間のターンアラウンド。大量データの一括処理向け
Priority PayGo1.8 倍標準よりも優先的に処理。バースト的かつ重要な処理向け
Provisioned Throughput期間固定料金容量を予約し、唯一の可用性 SLA を提供。安定かつクリティカルなワークロード向け

リアルタイム性が不要な大量処理は Batch に逃がし、重要なリクエストは Priority PayGo で優先処理する、という使い分けで 429 の影響を小さくできます。Priority PayGo はヘッダーを付与するだけで利用でき、申し込みやコミットメントは不要です。(Priority PayGo の詳細はこちらのコラムもご参考ください)

さらに、クリティカルなワークロードを安定稼働させたい場合は、Provisioned Throughput が選択肢になります。従量課金型とは異なりキャパシティを事前に確保する利用方式のため、スループットが保証され、唯一の可用性 SLA が提供されます。期間固定料金のため、毎月のコストを予測・コントロールしやすい点もメリットです。

実装例:429 を検知したら Priority PayGo に切り替えてリトライ

ここまでの対策を組み合わせた実装例をご紹介します。ポイントは以下の 3 つです。

  • グローバルエンドポイントlocation="global")を使用
  • リトライライブラリ tenacity で 429 のときだけ指数バックオフでリトライ
  • リトライ時は Priority PayGo のクライアントに切り替えて優先処理してもらう
from google import genai
from google.genai.errors import APIError
from google.genai.types import HttpOptions
from tenacity import retry, retry_if_exception, stop_after_attempt, wait_exponential

PROJECT_ID = "YOUR_PROJECT_ID"
LOCATION = "global"
MODEL = "gemini-3.1-flash-lite"

# 1. Standard クライアント(グローバルエンドポイントを使用)
client_standard = genai.Client(
    vertexai=True,
    project=PROJECT_ID,
    location=LOCATION,
    http_options=HttpOptions(api_version="v1"),
)

# 2. Priority クライアント(2 つのヘッダー指定で「Priority PayGo のみ」を使用)
client_priority = genai.Client(
    vertexai=True,
    project=PROJECT_ID,
    location=LOCATION,
    http_options=HttpOptions(
        api_version="v1",
        headers={
            "X-Vertex-AI-LLM-Request-Type": "shared",
            "X-Vertex-AI-LLM-Shared-Request-Type": "priority",
        },
    ),
)

# 429 でリトライするときに True になり、以降の試行で Priority を使う
use_priority = False


def is_429_error(exception: BaseException) -> bool:
    """429(リソース競合)のときだけリトライ対象にする。"""
    return isinstance(exception, APIError) and exception.code == 429


def switch_to_priority(retry_state) -> None:
    """リトライ待機の直前に呼ばれ、次の試行から Priority に切り替える。"""
    global use_priority
    use_priority = True
    print(f"429 エラーを検知。{retry_state.next_action.sleep} 秒待機して Priority でリトライします")


@retry(
    retry=retry_if_exception(is_429_error),
    stop=stop_after_attempt(4),  # 初回 1 回 + リトライ 3 回
    wait=wait_exponential(multiplier=2, min=2, max=10),  # 2秒 → 4秒 → 8秒
    before_sleep=switch_to_priority,
    reraise=True,  # リトライ上限到達時は最後のエラーをそのまま送出
)
def generate_content_with_retry(contents: str):
    # 初回は Standard、429 でリトライする場合は Priority を使用
    client = client_priority if use_priority else client_standard
    return client.models.generate_content(model=MODEL, contents=contents)


def main() -> None:
    try:
        response = generate_content_with_retry("こんにちは")
    except APIError as e:
        print(f"リトライ上限に達したか、回復不能なエラーです: {e}")
        return

    print(response.text)
    # どのレーンで処理されたかは usage_metadata.traffic_type で確認できる
    print(f"traffic_type: {response.usage_metadata.traffic_type}")
    # → "ON_DEMAND"(Standard)or "ON_DEMAND_PRIORITY"(Priority PayGo)


if __name__ == "__main__":
    main()

通常時は標準料金のまま、429 が発生したときだけ 1.8 倍の Priority PayGo に切り替えるため、コストを抑えつつ重要なリクエストの成功率を上げることができます。実際にどちらのレーンで処理されたかは usage_metadata.traffic_type で確認できます。

まとめ

Gemini の 429 エラーは一時的なリソース競合のため、「指数バックオフでリトライ」「グローバルエンドポイントの利用」「消費オプションの使い分け」で多くの場合は対処できます。今回の実装例のように組み合わせるとより効果的です。ぜひ試してみてください!

最後に

自社に専門人材がいない、リソースが足りない等の課題をお持ちの方に、エンジニア領域の支援サービス(Data Engineer Hub)をご提供しています。 お困りごとございましたら是非お気軽にご相談ください。

本件に関するお問い合わせは下記にて承ります。
株式会社DataCurrent
info@datacurrent.co.jp

人気のコラムランキング

PICK UP

企業のDX推進におけるダッシュボード内製化について

DXmarketingPICK UP コラムダッシュボード内製化

企業のDX推進に向けた人材教育支援について

GA4marketingPICK UP コラム内製化

【データプライバシーコラム】電気通信事業法改正の解説(2022年7月時点)

CMPPICK UP コラムデータプライバシーデータプライバシーコラム個人情報保護

CMP導入時の注意点

CMPPICK UP コラムデータプライバシーデータプライバシーコラム個人情報保護

TOPへ
戻る