Gemini APIを使い始めて最初にぶつかる壁の1つが、This model is overloaded right now. Please try again later. というエラーです。公式ドキュメントには「後でもう一度試してください」としか書かれておらず、「具体的にどうすれば止まるのか」が分からないまま、とりあえず time.sleep(5) を挟んで誤魔化している方も多いのではないでしょうか。
このエラーが起きる仕組みと、実用的に使えるリトライ戦略をまとめます。
なぜ overloaded エラーが起きるのか
Gemini APIのoverloadedエラーは、大きく2種類の状況で発生します。
1. モデルの需要過多(一時的な混雑)
gemini-2.0-flashやgemini-2.5-proといった人気モデルは、特定の時間帯にリクエストが集中することがあります。無料枠・低コストモデルほど混雑しやすい傾向があります。
2. レート制限への到達
各APIキーには RPM(1分あたりリクエスト数) と TPM(1分あたりトークン数) の制限があります。これに到達すると、429 Resource Exhausted(レート制限)または overloaded に似たエラーが返ってきます。
どちらの場合も、HTTPステータスコードで区別できます。
# HTTPステータスコードによる分類
# 503 Service Unavailable → モデル過負荷(混雑)
# 429 Too Many Requests → レート制限到達
# 408 / timeout → ネットワーク・処理タイムアウト基本対処:指数バックオフ付きリトライ
time.sleep(5) の固定待機は、同じ時間帯に多数のクライアントが同時リトライすると、混雑がさらに悪化する「サンダーリングハード」問題を引き起こします。実務では指数バックオフ(リトライごとに待機時間を増やす)とジッター(ランダムな揺らぎ)を組み合わせるのが標準です。
import google.generativeai as genai
import time
import random
def call_gemini_with_retry(
model_name: str,
prompt: str,
max_retries: int = 5,
base_delay: float = 1.0,
) -> str:
"""
指数バックオフ + ジッター付きのGemini API呼び出し。
overloaded (503) と rate limit (429) を自動リトライする。
"""
model = genai.GenerativeModel(model_name)
for attempt in range(max_retries):
try:
response = model.generate_content(prompt)
return response.text
except Exception as e:
error_str = str(e).lower()
# リトライすべきエラーか判断
is_retryable = any(keyword in error_str for keyword in [
"overloaded", "503", "429", "resource exhausted",
"timeout", "unavailable"
])
if not is_retryable or attempt == max_retries - 1:
raise # リトライ不可または上限到達 → 例外を再送出
# 指数バックオフ: 1s, 2s, 4s, 8s, 16s + ランダムジッター
wait_time = base_delay * (2 ** attempt) + random.uniform(0, 1)
print(f"Attempt {attempt + 1} failed: {e}. Retrying in {wait_time:.1f}s...")
time.sleep(wait_time)
raise RuntimeError("Max retries exceeded") # 念のため(実際はループ内でraiseされる)
# 使用例
genai.configure(api_key="YOUR_API_KEY")
result = call_gemini_with_retry(
model_name="gemini-2.0-flash",
prompt="Summarize this document...",
max_retries=5
)このパターンで、最大16秒+ジッターまで待機しながら5回リトライします。実務では max_retries=5、base_delay=1.0 がバランスの良い設定です。
タイムアウトの設定
Gemini APIはデフォルトでリクエストのタイムアウトが設定されていないため、応答が長い場合に接続がハングすることがあります。明示的にタイムアウトを設定する習慣をつけましょう。
import httpx
from google.generativeai.types import GenerationConfig
# タイムアウト付きモデル設定
model = genai.GenerativeModel(
"gemini-2.5-pro",
generation_config=GenerationConfig(
max_output_tokens=2048,
)
)
# httpx を直接使う場合(REST API)
def call_with_timeout(prompt: str, timeout_seconds: int = 30) -> str:
client = httpx.Client(timeout=timeout_seconds)
# ... REST API呼び出し
# Python SDK の request_options でタイムアウト設定
response = model.generate_content(
prompt,
request_options={"timeout": 60} # 秒
)長文生成(4,000トークン超)では60〜120秒のタイムアウトが現実的です。短いリクエストなら30秒で十分です。
モデル切り替え戦略
overloadedが頻発する場合、そのモデルが混雑ピーク中の可能性があります。フォールバックモデルを用意する設計が実用的です。
FALLBACK_MODELS = [
"gemini-2.5-pro", # 第1希望
"gemini-2.0-flash", # 第2希望(速い・安い)
"gemini-1.5-flash", # 第3希望(旧モデルだが安定)
]
def call_with_model_fallback(prompt: str) -> tuple[str, str]:
"""
上位モデルから順に試し、失敗したら次のモデルへ。
(response_text, used_model) を返す。
"""
last_error = None
for model_name in FALLBACK_MODELS:
try:
result = call_gemini_with_retry(model_name, prompt, max_retries=3)
return result, model_name
except Exception as e:
last_error = e
print(f"{model_name} failed, trying next model: {e}")
continue
raise RuntimeError(f"All models failed. Last error: {last_error}")
# 使用例
text, model_used = call_with_model_fallback("Analyze this data...")
print(f"Response from {model_used}: {text[:100]}...")コスト・品質のトレードオフを考えて、フォールバックの順番は用途に合わせて調整してください。
よくある原因と見落とされがちな対処
無料枠のRPM制限
Google AI Studioの無料枠は、モデルによっては1分あたり2〜15リクエストと非常に低い制限があります。これはAPIキーの問題ではなく枠の問題なので、有料プランへの切り替えが根本解決になります。
# 自前のRPMスロットリング(無料枠対策)
import asyncio
from asyncio import Semaphore
class RateLimitedGeminiClient:
def __init__(self, rpm_limit: int = 10):
# 1分間に rpm_limit リクエストまで
self._semaphore = Semaphore(rpm_limit)
self._request_times: list[float] = []
async def generate(self, prompt: str) -> str:
async with self._semaphore:
# 1分以内のリクエスト数をチェック
now = time.time()
self._request_times = [t for t in self._request_times if now - t < 60]
if len(self._request_times) >= self._semaphore._value:
wait = 60 - (now - self._request_times[0])
await asyncio.sleep(max(0, wait))
self._request_times.append(time.time())
# 実際のAPI呼び出し(省略)バッチ処理での並列リクエスト過多
一度に100件のAPIリクエストを並列実行すると、全て overloaded で失敗するケースがあります。同時実行数を10〜20に制限し、各リクエストに適切なレート制限をかけるのが安定します。
APIの詳しい使い方については、Gemini API ストリーミングとチャット実装ガイドも参考になります。
全体を振り返って
time.sleep(5) で誤魔化すのをやめて、指数バックオフ付きのリトライ関数を一度作れば、ほとんどのoverloadedエラーは自動で解決するようになります。まず上記のコードをコピーして、自分のプロジェクトのGemini呼び出し部分に差し込んでみてください。それだけで安定性が大きく変わるはずです。