Gemini APIの無料枠は「モデル単位」で別枠だった(実測)
「本日24/250件使用(9%)」の裏で、16件が静かに失敗していた
自宅で副業アイデアを自動生成するパイプライン(AISideHustle)を回しているのですが、ある日ふと出力を眺めていて「あれ、思ったより候補が積み上がってないな……」と気づきました。
自作の自己診断パネルを開くと、そこにはこう書いてあります。
本日 24/250 件使用(9%)余裕たっぷり。緑ランプ。異常なし。
……なのに、ログを掘ったら直近24時間で16件の処理が429エラーで死んでいました。メーターは何食わぬ顔で「正常」と表示し続けていたわけです。これ、静かに壊れているシステムの中でもかなり性質が悪いパターンでした。

この記事では、2026年8月14日に実際に手を動かして確かめた、
- Gemini APIの無料枠は「プロジェクト単位」ではなく「プロジェクト×モデル単位」だったこと
- ネットでよく見る「1日250リクエスト」ではなく、実測は1日20件だったこと
- そして何より、上限値をコードに書いた自分の設計が間違っていたこと
をまとめます。最後に「じゃあローカルLLMは要らないの?」を確かめるため、クラウドのFlash-Liteと自宅GPUのGemmaを同じプロンプトで殴り合わせた実測比較も載せておきます。
なお、無料枠の数値は時期・モデル・アカウントによって変わります。この記事の数字も「2026年8月時点のうちのアカウントではこうだった」という一次情報でしかないので、必ずGemini API公式のレート制限ドキュメントと、ご自身のGoogle AI Studio のレート制限画面で確認してください。この記事の数字をコードに書き写すのは、この記事が伝えたい失敗そのものです。
今回使用した環境・ツール
今回の検証で使ったものは以下のとおりです。特別なものは使っていません。
- Gemini API(Google AI Studio で発行した無料枠のAPIキー) 今回の主役。クレジットカード登録なしで試せる無料枠があり、個人の自動化パイプラインには十分……と思っていたやつです。発行と使用量の確認は Google AI Studio から行えます。
- Lemonade + llama.cpp(ローカルLLM実行環境) 自宅のマシンでGemmaを動かすために使っています。OpenAI互換のAPIを生やしてくれるので、クラウドAPIとの比較がやりやすいのが利点です。
- AMD Ryzen AI MAX+ 395 搭載機(GPUに32GB割り当て) ローカルLLM側のハードウェア。今回は
Gemma-4-26B-A4B(Q4_K_M量子化)を載せて比較に使いました。
同じことは、そこそこのGPUがあるPCとAPIキーさえあれば追試できます。
犯人はレスポンスの中にいた quotaIdは仕様書として読める
429エラーが出ていると分かったあと、まずやったのはエラーレスポンスの中身をちゃんと読むことでした。というか、最初からそこに全部書いてありました。
Quota exceeded for metric:
generativelanguage.googleapis.com/generate_content_free_tier_requests
limit: 20
model: gemini-2.5-flash
quotaId: GenerateRequestsPerDayPerProjectPerModel-FreeTier注目してほしいのは最後の quotaId です。
GenerateRequestsPerDayPerProjectPerModel-FreeTier分解するとこうなります。
| 部分 | 意味 |
|---|---|
GenerateRequests | 生成リクエストの回数に対する制限 |
PerDay | 日次でリセットされる |
PerProject | プロジェクト単位で数える |
PerModel | さらにモデル単位で数える |
-FreeTier | 無料枠の制限である |
つまりこの文字列ひとつで、「日次・プロジェクト・モデル」という粒度が全部わかる。クォータIDは、実質的に仕様書として読む価値があります。 ドキュメントを探しに行く前に、まずエラーの生JSONを開くべきでした。
そして limit: 20。ここが次の話につながります。
無料枠は「プロジェクト×モデル」で独立していた
PerProjectPerModel が本当なら、gemini-2.5-flash が枯渇していても、別のモデルなら通るはずです。同じAPIキー・同じプロジェクトのまま、ほぼ同じ瞬間に同一のリクエストを各モデルへ投げてみました。
| モデル | 結果 |
|---|---|
gemini-2.5-flash | ❌ 429 quotaId=GenerateRequestsPerDayPerProjectPerModel-FreeTier limit=20 |
gemini-2.5-flash-lite | ❌ 404「no longer available to new users」 |
gemini-3.5-flash | ✅ 200 |
gemini-3.5-flash-lite | ✅ 200 |
gemini-3.6-flash | ✅ 200 |
gemini-3.7-flash | ❌ 503「currently experiencing high demand」 |
片方は429、他方は200。枠はモデルごとに完全に独立していることが実測で確認できました。
ここで大事なのは、これを「無料枠を増やす裏技」として使わないことです。モデルを次々渡り歩けば無料での実行回数は確かに増えますが、それは制限の設計意図に逆らう使い方で、アカウントごと止められたら元も子もありません。うちは同じアカウントを日常の作業でも使っているので、そのリスクは割に合いません。あくまで「枠の粒度はモデル単位だった」という事実の確認までにとどめます。
一方で、次の章で見るとおり、404や503への保険としてのフォールバックは別の話です。こちらは可用性の設計であって、枠の回避ではありません。
設計をどう直したか
「250件」を信じてハードコードしたのが最大の失敗
さて、本題の設計ミスです。
私は世間でよく見かける「Gemini 2.5 Flash 無料枠 = 1日250リクエスト」という情報を信じて、設定ファイルにこう書いていました。
RPD_LIMIT = 250 # 1日あたりのリクエスト上限ところが、実際にサーバーが返してきた limit は 20。10分の1以下です。
この一行のせいで何が起きたか。自作のリソース管理は「まだ250件まで使えます」と信じているので、20件を超えても平然とAPIを叩き続けます。当然すべて429で弾かれる。しかも診断パネルは自前のカウンタ(24件)を自前の上限(250件)で割って「9%使用・正常」と表示する。
メーターが参照している上限値が間違っていれば、そのメーターは嘘をつきます。 「使用量が正常だから大丈夫」は、上限値が正しいときにしか成り立たない前提だったわけです。
正しい設計は「429が返ったという事実」を信じること
反省を踏まえて、判定ロジックをこう変えました。
❌ 悪い: 上限値を設定ファイルに書いて、それを信じて事前にゲートする
✅ 良い: 実際に429が返ったことを検知して、そのモデルは当日分もう使わない印を付ける考え方としてはシンプルで、
- 事前カウントは「自分が何回使ったか」しか知らない(しかも上限の推測が要る)
- 429レスポンスは「もう使えない」という事実そのもの(推測が要らない)
サーバーが教えてくれる事実を、こちらの推測より優先する。これだけです。
なお、事前カウントを完全に捨てる必要はありません。明らかに無駄な呼び出しを減らす効果はあります。ただしそれを唯一の判断根拠にしてはいけない、というのが今回の教訓でした。
エラーコードごとに扱いを変える 429と503と404は別物
検証中、429以外のエラーも拾えたので、扱いを整理しておきます。ここを一緒くたにすると、復活できるはずのモデルを永久に捨てたり、逆に死んだモデルを叩き続けたりします。
| コード | 意味 | 扱い |
|---|---|---|
| 429 | 枠の枯渇 | そのモデルは当日いっぱい使わない |
| 503 | 一時的な混雑 | いったん別のモデルへ回すが、次回はまた試す |
| 404 | モデルが利用不可 | 恒久的に候補から外す |
実例として、gemini-2.5-flash-lite は 404 で「no longer available to new users」でした。既存ユーザーは使えるが、新規からは引退済みという状態です。逆に gemini-3.7-flash の 503 はリリース直後の混雑によるもので、時間をおけば普通に通ります。
つまり「このモデルを使う」と決め打ちしたコードは、ある日突然404や503で止まります。可用性の観点からフォールバック先を用意しておくのは、枠の話とは無関係に妥当な設計だと思います。
おまけ Flash-Liteとローカルの26Bを同じプロンプトで殴り合わせた
「無料枠に余裕のある軽量モデル(Flash-Lite)があれば、自宅GPUのローカルLLMは要らないのでは?」という疑問が湧いたので、同一の入力・同一のプロンプトで比較しました。
タスクA 判定(要件定義書がGo/No-Go判断できる状態かのチェック)
| PRD | flash-lite | Gemma-4-26B(ローカル) |
|---|---|---|
| ① | OK(1.2秒) | NG(50.4秒) |
| ② | OK(1.3秒) | NG(31.6秒) |
| ③ | OK(1.3秒) | NG(42.9秒) |
速度差は25〜40倍。ですが、本当に効いたのは中身の方でした。
Gemmaは3件すべてを「リスクと前提条件が明示されていない」という同じ理由でNGにしました。しかしプロンプトには「完璧である必要はない」「4点が読み取れれば合格」と明記してあり、実際の文書にも技術リスクへの言及は本文中にありました。Flash-Liteはそれを読み取って合格にしたのに対し、Gemmaは独立した「リスク」章がないと認めなかったのです。
指示への追従性、つまり「与えられた基準に従うか、自分の理想に置き換えてしまうか」。ここが一番はっきり性能差として出ました。全件不合格が続けば当然候補は積み上がらないので、これは運用の失敗に直結していました。
タスクB 生成(要件定義書そのものを書かせる)
| flash-lite | Gemma-4-26B(ローカル) | |
|---|---|---|
| 所要時間 | 9.4秒 | 70.0秒 |
| 出力文字数 | 3,253 | 2,753 |
| 見出し数 | 15 | 15 |
| 完走 | ✅ | ✅(finish=stop) |
意外にも、生成タスクでは品質差はほとんどありませんでした。どちらも指定した5章立てを守り、内容の解像度も同等。Flash-Liteはリスクを影響度・発生確率つきの表で整理し、Gemmaは末尾に「PMメモ」を添えるといったスタイルの違いはありますが、優劣とは言い難いレベルです。差がついたのは速度(7.5倍)だけでした。
タスクC 同じGemmaを「ローカル」と「AI Studio API」で比べる
ついでに、Google AI Studioが提供しているGemma(gemma-4-26b-a4b-it)も試しました。ローカルで動かしているのと同じモデル(ローカルはQ4_K_M量子化、APIはフル精度)です。「自前GPUをやめてAPIに寄せるべきか」を確かめたかったわけです。
| AI Studio API | ローカル(Lemonade) | |
|---|---|---|
| 所要時間 | 65.4秒 | 101.3秒 |
| 出力文字数 | 2,540 | 2,494 |
| 見出し数 | 18 | 19 |
| 消費トークン | 4,411 | 4,508 |
差は1.5倍。出力の質も量もほぼ同一で、量子化の影響は体感できるレベルでは出ませんでした。
そして重要なのは、同じタスクでFlash-Liteは9.4秒だったこと。つまり「APIに寄せる」こと自体に価値があるのではなく、モデルをFlash-Liteに変えることに価値があった(API版Gemmaより7倍速い)のです。ここは完全に読み違えていました。
なお、AI StudioのGemmaは RPD(1日あたりリクエスト数)が14,400と大きい一方で、TPM(1分あたりトークン数)は16Kでした(Gemini系は250K)。1回に4〜5Kトークン使う用途だと毎分3回程度が実質の上限になり、RPDの大きさほどには回せません。制限は必ず複数の軸で見る必要があります(こちらも数値は変動するので、公式のレート制限ページでご確認ください)。
比較の結論
判定タスクは指示追従性の差が大きく、Flash-Liteが明確に優位。生成タスクは品質同等で速度だけ差がつく。……とはいえ、ローカルLLMを完全に捨てるべきではないというのが私の結論です。APIの枠が尽きても止まらない「最後の砦」としての価値があるので、「まずAPI → ダメならローカル」という順序が合理的だと思っています。
つまずいたポイント・注意点
同じ轍を踏まないために、今回学んだことを3つに絞ります。
「無料枠◯件」という記事の数値をコードに書かない
これが今回の元凶です。エラーレスポンスが返す limit こそが実態であり、しかもその値は時期・モデル・アカウントによって変わります。この記事の「20件」も、あなたの環境では違う可能性があります。 数値をコードに焼き込むのではなく、サーバーの応答から動的に判断する作りにしてください。
使用量メーターが「正常」でも、機能は止まっていることがある
自己診断パネルは正しく動いていました。ただ、参照している上限値が間違っていただけです。監視は「自分が数えた使用量」ではなく「実際に起きた失敗(429の件数)」を見るようにしましょう。 私の場合、429カウントを可視化していれば24時間も放置しませんでした。
エラーの生JSONを、まず自分の目で読む
quotaId を読んでいれば10分で分かった話に、私はだいぶ遠回りしました。「なんか429出てるな、レート制限か」で片付けず、レスポンス全文を開く。それだけで粒度も上限値も対象モデルも書いてあります。
補足 ローカルモデルの出力には目を通す
比較検証の最中、ローカルのGemmaが一度だけ、プラットフォームの規約に触れかねない手順を提案してきました。それが本当に規約違反なのかは判断が分かれるところですが、少なくともそのまま実行してよいかを人が判断すべき類の出力でした。ローカルモデルはこの種のガードが弱い場合があります。自動化パイプラインに組み込むなら、出力をそのまま実行する設計は避けたほうが安全です。
なお今回の比較は、判定3件・生成1件とサンプル数が少なく、正解データもありません。Gemmaの計測時は同一GPUでパイプラインが並行稼働していたため、単独実行ならもう少し速い可能性もあります。あくまで「うちの環境ではこうだった」という一次情報として読んでください。
まとめ
今回の学びを一枚にまとめておきます。
| 内容 | |
|---|---|
| 無料枠の単位 | プロジェクト×モデル。quotaId の PerProjectPerModel が根拠 |
| 上限値 | 記事の数値を信じない。うちの gemini-2.5-flash は実測20件/日 |
| 正しい検知方法 | 事前カウントではなく、429レスポンスそのものを根拠にする |
| エラーの扱い分け | 429=当日除外 / 503=一時的 / 404=恒久除外 |
| ローカルLLMの位置づけ | 速度と指示追従性ではAPIに劣るが、止まらない最後の砦 |
一番刺さったのは「メーターが嘘をついていた」ことです。自動化を組むと、つい「監視を付けたから安心」と思ってしまいますが、その監視が参照している前提が間違っていたら、監視は安心を演出する装置に成り下がります。緑ランプほど疑うべきものはない、と身にしみました。
次にやりたいのは、429の発生件数そのものをダッシュボードの一級市民に昇格させることと、失敗が一定数を超えたら手元に通知が飛ぶようにすることです。黙って壊れるのが一番こわいので。
同じようにGemini APIで自動化を組んでいる方は、ぜひ一度、自分のコードに書いた上限値と、実際に返ってくる limit を突き合わせてみてください。案外ズレているかもしれません。
