ANTIGRAVITY LABJP
Articles/Antigravity Basics
Antigravity Basics/2026-09-17Intermediate

Wait or Pay When the Baseline Runs Out: Deciding Credit Overages Per Task

When your baseline quota is exhausted, one setting decides whether you wait for the refresh or spend purchased credits. Here is how I split attended work from unattended runs, and the small gate I put in front of the jobs nobody is watching.

credits3quota10cost control2Antigravity CLI34indie dev19

Late one afternoon a request I had just sent stopped coming back. The usage indicator on the right of the status line had changed color, and I was standing right at the edge where the baseline quota runs out. My hands were idle for maybe two minutes, and all I could think about was whether I should keep going.

Whether I could keep going was not up to my mood that afternoon. It had already been decided by a single setting — one I only learned about after the indicator changed color.

One setting decides whether you wait or you pay

The official Plans page describes a baseline quota on every plan. On Google AI Pro and Ultra it refreshes every five hours until the weekly rate limit is reached; below those plans, the refresh is weekly. The same page notes that the limits correlate with how much work the agent actually did, which differs from prompt to prompt. So counting "how many requests do I have left" is not a thing you can do.

What happens past the baseline is a separate question: whether you keep going on purchased AI credits. That is governed by the "AI Credit Overages" setting, which has exactly two values — Never and Always. Never waits for the refresh. Always spends credits automatically and switches back to the baseline on its own once the refresh lands. In the CLI, the same lever is useG1Credits in ~/.gemini/antigravity-cli/settings.json, or the Use G1 Credits field in the /config and /settings panel.

There are three places to read your remaining allowance: the indicator at the right of the status line, the balance and consumption breakdown behind /credits, and the per-model view behind /usage (aliased as /quota). If you would rather start from the money side, I wrote about where each plan breaks even in Antigravity Pricing and Usage Limits — Free Tier, Pro, or AI Ultra?.

What Always cost me during one particular week

As an indie developer I keep a handful of apps running, and I batch the unglamorous work — store copy drafts, maintenance on the Lab sites — into the hours when nobody is awake. My setting sat on Always. Not stopping felt safer.

That week, a nightly run crossed the baseline. The balance in the morning was visibly lower. What stung was not the amount. It was that I could not remember what it had been spent on. Nothing in that batch was urgent; I had paid money for drafts that would have gone through for free if I had simply let them wait.

One line came out of it. Money for the work someone is waiting on; time for the work nobody is waiting on. Once the direction was settled, I stopped touching the setting so often.

Three boxes first, then the setting

I tried finer categories at one point and only made the decision harder. These days I drop work into three boxes and stop there.

BoxWhat you spendDirection at the limitHow a wrong call shows up
Someone is waiting (client deadline, live defect)MoneyAlways — keep goingThe balance drops faster than expected
Nobody is waiting (nightly batches, draft generation)TimeNever — wait for the refreshYou find it unfinished in the morning
Exploration and learning loopsNeitherNever, on a lighter modelYou drift toward the weekly ceiling unnoticed

The third box was the one I kept overlooking. Each exploratory round trip is cheap, so the count climbs, and the count is what pushes you into the weekly ceiling. With Never in place, your hands stop when the ceiling is near. Whether that stop reads as friction or as a signal is exactly what determines how you feel about this setting.

A pause in front of the runs nobody watches

I am not there for the nightly jobs. Nobody is around to notice the indicator changing color, so setting Never is not enough by itself — something has to check the remaining allowance before the job starts.

The status line script turns out to be the place where that number is machine-readable. Every time the agent state changes, the CLI runs your script and pipes a state JSON payload to its stdin. Inside that payload, quota carries remaining_fraction, reset_time, and reset_in_seconds per bucket. I keep exactly one snapshot of it on disk.

#!/usr/bin/env bash
# ~/.gemini/antigravity-cli/quota-snapshot.sh
# Print one line for the status line, and keep a single snapshot on disk (no history)
set -u
SNAP="${HOME}/.gemini/antigravity-cli/quota_snapshot.json"
PAYLOAD="$(cat)"   # the state JSON arrives on stdin whenever the agent state changes
 
printf '%s' "${PAYLOAD}" \
  | jq -c --arg at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
      '{captured_at: $at, tier: (.plan_tier // "unknown"), quota: (.quota // {})}' \
      > "${SNAP}.tmp" 2>/dev/null \
  && mv "${SNAP}.tmp" "${SNAP}"
 
printf '%s' "${PAYLOAD}" | jq -r '
  (.quota // {}) | to_entries
  | if length == 0 then "quota -"
    else map("\(.key) \(((.value.remaining_fraction // 0) * 100) | floor)%") | join("  ")
    end'

Wire it up through the statusLine block, and set stack_with_default so the built-in line survives. Replacing the default display with your snapshot logger makes your everyday work harder to see.

{
    "statusLine": {
        "type": "command",
        "command": "~/.gemini/antigravity-cli/quota-snapshot.sh",
        "stack_with_default": true
    },
    "useG1Credits": false
}

The write goes to a temporary file and then through mv because this script runs again and again as the state changes. Write in place and the reader eventually picks up a half-written JSON file. Accumulating consumption into a ledger is a different job, and I kept it in its own piece — Three things I had to fix before my status line could tell me what a session cost. Here there is no ledger; there is one snapshot.

The pause itself is a small gate that reads that snapshot and answers one question: run now, or wait for the refresh.

#!/usr/bin/env python3
"""A pause in front of unattended runs.
exit 0  ... fine to run right now
exit 75 ... defer (the caller skips this round)
When the remaining allowance cannot be read, it falls to "defer".
"""
import json
import os
import sys
import time
 
SNAP = os.path.expanduser("~/.gemini/antigravity-cli/quota_snapshot.json")
MIN_REMAINING = 0.25    # below this share of the baseline, unattended runs are skipped
MAX_AGE_SEC = 6 * 3600  # the snapshot goes stale; it only updates while the CLI is open
DEFER = 75
 
 
def load_snapshot(path):
    try:
        age = time.time() - os.path.getmtime(path)
        with open(path, encoding="utf-8") as fp:
            return json.load(fp), age
    except (OSError, ValueError):
        return None, None
 
 
def main():
    snap, age = load_snapshot(SNAP)
    if snap is None:
        print("defer: could not read the snapshot")
        return DEFER
    if age > MAX_AGE_SEC:
        print(f"defer: snapshot is too old ({age / 3600:.1f} hours)")
        return DEFER
 
    buckets = snap.get("quota") or {}
    if not buckets:
        print("defer: quota was empty (possibly before the first call)")
        return DEFER
 
    name, worst = min(buckets.items(), key=lambda kv: kv[1].get("remaining_fraction", 0.0))
    remaining = worst.get("remaining_fraction", 0.0)
    wait_min = int(worst.get("reset_in_seconds", 0) // 60)
 
    if remaining < MIN_REMAINING:
        print(f"defer: {name} is at {remaining:.0%} (refresh in about {wait_min} min)")
        return DEFER
 
    print(f"go: {name} is at {remaining:.0%}")
    return 0
 
 
if __name__ == "__main__":
    sys.exit(main())

On my machine it prints one of these:

$ python3 ~/bin/quota_preflight.py
go: gemini-weekly is at 93%
 
$ python3 ~/bin/quota_preflight.py
defer: gemini-weekly is at 11% (refresh in about 74 min)

The caller stays quiet if you treat a deferral as a normal outcome rather than a failure.

# called from the nightly job
python3 ~/bin/quota_preflight.py || exit 0
agy -p "$(cat ~/prompts/nightly_draft.md)"

The decision runs on the thinnest bucket rather than an average, because each model carries its own allowance and one empty bucket is enough to stop the job. Average the buckets and the one that will actually stop you disappears into the mean.

When the number cannot be read, choose not to run

There is one plain weakness here. The snapshot only updates while the CLI is open. If you have not opened it since the previous evening, the gate answers "go" from a stale number.

A gate that decides on stale data is worse than no gate at all. That is why the snapshot has an expiry and why anything unclear falls to defer. An empty quota gets the same treatment: the field can be absent before the first call, and reading empty as "zero left" rather than "unknown" quietly changes the behavior.

One more thing worth keeping separate. Choosing Never does not move the weekly ceiling. The setting only decides whether you cross the limit with money. If you want to hit the ceiling less often, that is a conversation about how you ask and how much context you hand over.

What to do next

Open /usage and look at the per-model remaining allowance and the time to refresh. Then set Overages to Never and live with it for one week. Counting the moments where you were stopped tells you, without much analysis, which box your work belongs in.

My own threshold for unattended runs moved up again last week, so I am still adjusting. If any of this saves you the morning I had, I am glad.

Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $15 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Antigravity2026-08-20
Count What Writes Outside Your Workspace Before You Upgrade to CLI 1.1.14
Antigravity CLI 1.1.14 makes paths outside the workspace read-only by default. If your source assets and delivery targets live outside the repository, it is worth knowing what breaks before you upgrade. Here is a script that inventories your write targets, and the two ways it quietly undercounts them.
Antigravity2026-08-18
How Much Slower Search Gets When /codesearch Cannot Run ripgrep
Antigravity CLI 1.1.13 moved the bundled ripgrep binary, and /codesearch quietly falls back to local search when it cannot run. I measured the cost of that fallback on a real repository and wrote down how to tell which path your machine is on.
Antigravity2026-08-17
Deleting Duplicate Rows Will Not Shrink Your Antigravity CLI Conversation Database
A schema-agnostic way to audit conversation database growth, plus measurements showing why deletion reclaims nothing and why freelist_count is the wrong number to trust when you estimate how much you can get back.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links