Agent Job Quota Admission Control: Free-Tier Quota Ledger in Practice

Free-tier agent jobs lack admission control and fail silently; a forty-line quota ledger plus a four-leaf decision tree fixes it.
Free-tier agent batch jobs commonly ship with routing logic but no admission control, so when a quota window closes mid-run, the job ends with exit code 0 while emitting wrong labels. The author proposes a local quota ledger built only on the Python standard library that appends a JSON line per attempt, bills failures and retries alike, and uses a hard SAFETY multiplier to force plans to absorb a 20% estimation error. On top of it sits a four-leaf decision tree: Leaf A admits as-is, Leaf B shrinks the batch, Leaf C defers to the next window, and Leaf D reroutes the overflow. The article hand-computes all four leaves against a fixed fixture and stresses testing the deterministic decision logic rather than the model.
Why Your Agent Jobs Need "Admission Control"
Picture a nightly batch job: 400 classification calls, one free model endpoint, one free server, one cron schedule. At 3:12 a.m. the job ends with exit code 0 and a wall of green logs. The next morning you discover half the labels are wrong — because after the quota window closed, the run quietly started receiving truncated or fallback responses, and the pipeline never noticed.
This scenario is fictional, but the arithmetic behind it is real. I've seen nearly every free-tier agent job ship with routing logic but no admission logic. It knows where to send work; it doesn't know whether it can afford to send it.
This article builds the missing layer: a local quota ledger plus a four-leaf decision tree that runs before any request leaves the machine. MonkeyCode's free model access and free server option are the deployment target I use for examples, since that combination hits the failure above most easily. Treat availability claims as operator-provided and re-read the project's current terms before relying on them.
Disclosure: This article was prepared as part of a MonkeyCode product promotion.

Five Terms That Carry the Whole Design
If you remember only one, remember replay cost.
- Quota window — the period over which a provider's allowance resets (if it resets). You don't control it, so you have to assume it can close mid-batch.
- Unit cost — the number of tokens each work item consumes (input + output). Measure it; don't guess.
- Replay cost — the extra allowance burned by retries and re-runs. A 15% retry rate is a 15% tax on your budget, and it's completely invisible if you only count successful calls.
- Headroom —
budget - spend, where spend includes failed and retried attempts, not just the ones that returned 200. - Admission — deciding, before the first request goes out, to not start the job, or to start a smaller version of it.
Routing asks where to send. Admission asks whether to send, and how much. Skip the second question and you get exactly "exit code 0 but wrong output."
Idempotency key: In distributed systems, an idempotency key is a unique identifier attached to each request so that the same operation produces a side effect only once, no matter how many times it is replayed. In this article's rerouting scenario (Leaf D), idempotency keys are especially critical — when some items are pushed to the free server or a local model path, if that path fails and falls back to a retry, the system needs the idempotency key to determine "has this item already been processed," thereby avoiding double billing or duplicate label writes for the same item. Without idempotency keys, the overflow portion of a reroute could execute once on each path, wasting quota and polluting output. That's why Leaf D's admission condition explicitly requires every item to carry an idempotency key and the reroute target to produce comparable output; if either fails, fall back to Leaf C.
The Ledger: Forty Lines, Standard Library Only
The script below depends only on the Python standard library and is deliberately plain. It appends one JSON line per attempt, so retries are billed naturally.
# ledger.py - Python 3.11+, stdlib only
import json, os
from dataclasses import dataclass, asdict
LEDGER = os.environ.get("LEDGER_PATH", "usage.jsonl")
BUDGET = int(os.environ.get("QUOTA_BUDGET", "200000"))
SAFETY = 0.80 # never plan past 80% of headroom
REPLAY = 0.15 # measured retry tax, replace with your own
@dataclass
class Entry:
ts: float
job_id: str
tokens_in: int
tokens_out: int
status: str # ok | retry | failed
idem_key: str
def append(entry: Entry) -> None:
with open(LEDGER, "a", encoding="utf-8") as f:
f.write(json.dumps(asdict(entry)) + "\n")
def load() -> list[Entry]:
if not os.path.exists(LEDGER):
return []
with open(LEDGER, encoding="utf-8") as f:
return [Entry(**json.loads(line)) for line in f if line.strip()]
def spent() -> int:
return sum(e.tokens_in + e.tokens_out for e in load())
def headroom() -> int:
return BUDGET - spent()
def plan(items: int, per_item: int, deadline_bound: bool) -> tuple[str, dict]:
unit = per_item * (1 + REPLAY)
want = items * unit
left = headroom()
if want <= left * SAFETY:
return "A", {"items_now": items, "items_later": 0}
if want <= left:
now = int(left * SAFETY // unit)
return "B", {"items_now": now, "items_later": items - now}
if not deadline_bound:
per_window = int(BUDGET * SAFETY // unit)
return "C", {"windows": -(-items // per_window), "per_window": per_window}
now = int(left * SAFETY // unit)
return "D", {"items_now": now, "items_rerouted": items - now}
Run it with an explicit window budget:
QUOTA_BUDGET=200000 LEDGER_PATH=usage.jsonl python -c "import ledger; print(ledger.plan(130, 900, False))"
Two design choices matter more than the code itself. First, status is recorded but never filtered out by spent() — failed attempts consume allowance too. Second, SAFETY is a hard multiplier, not a suggestion: it forces a plan to absorb a 20% estimation error without touching the last fifth of the allowance.
The Four-Leaf Decision Tree, With Hand-Worked Examples
Fixed test fixture: BUDGET = 200,000, spent 60,000, so headroom = 140,000; SAFETY = 0.80 gives a planning ceiling of 112,000; REPLAY = 0.15. All four numbers below are hand arithmetic against that fixture, not measured provider values.
Leaf A — Admit as-is
40 items at 900 units each: want = 40 × 900 × 1.15 = 41,400, under the 112,000 ceiling. Run, record, move on. Leaf A is where you want 90% of batches to land; if they don't, your per_item estimate is wrong.
Leaf B — Admit a reduced batch
130 items at 900 units each: want = 134,550. That overshoots the ceiling but stays within 140,000, and the right move is partial admission: items_now = 112,000 // 1035 = 108, deferring 22. Validate the first chunk's output before committing the second. If chunk one's labels look wrong, you just saved 22 items of allowance and a whole window of failure.
Leaf C — Defer to the next window
300 items at 900 units each: want = 310,500, no deadline. per_window = 160,000 // 1035 = 154, so the job needs two windows. Note that even a fresh window can't absorb it in one go — deferral without re-chunking just relocates the failure.
Leaf D — Reroute the overflow
Same 300 items, but with a deadline. Take 108 locally and push the remaining 192 to the free server or a local model path. Leaf D is the only branch that depends on job properties rather than budget properties: it's valid only when every item carries an idempotency key and the reroute target produces comparable output. If either fails, fall back to C and negotiate the deadline.
Deadline constraint (deadline_bound): The only input distinguishing Leaf C from Leaf D in the four-leaf decision tree is the deadline_bound boolean. It indicates whether the job must complete within the current quota window. When False, the job can be deferred across windows (Leaf C), and the system computes how many windows are needed and how many items to process per window; when True, deferral is unacceptable, and the system can only reroute the overflow to another path (Leaf D). This distinction matters because quota window reset times are typically controlled by the provider, and the job cannot assume it will finish all work before the window closes. Modeling the deadline explicitly as a parameter avoids the hidden assumptions of "always defer by default" or "always reroute by default," making the policy choice testable and auditable.
Test the Decision Tree, Not the Model
The decision logic is deterministic, so pinning it down is cheap:
- Boundary fixtures. Assert that
want == 0.8 × headroomreturns A, whilewant == 0.8 × headroom + 1returns B. Off-by-one errors at the ceiling are the most common regression. - Inject clock and path. Every test points
LEDGER_PATHat a temp file; never read the developer's real ledger. - Conservation property. For every fixture,
items_now + items_later(oritems_rerouted) equals the input count. A leaf that loses work items is a bug, not an optimization. - Retry billing. Append a
status="retry"entry and assertspent()increases. If it doesn't, your replay tax isn't being billed. - Window rollover. Move the ledger file aside, re-run, and confirm the plan returns to Leaf A instead of remembering stale headroom.
Conservation property: In testing, the conservation property means that for any input fixture, the sum of items_now and items_later (or items_rerouted) returned by the decision tree must strictly equal the total number of input items. This is an invariant, not an assertion about a specific value. It catches a class of serious bugs where the decision logic silently drops work items on some branch, causing the batch to "succeed" while actually skipping part of the data. Because each leaf of the four-leaf decision tree returns a plan dictionary, the conservation property can cover all branches with a single generic assertion without writing expected values for each leaf individually. Any leaf that violates conservation should be treated as a bug rather than an optimization, since losing work costs far more than running an extra pass.
Limitations and Who Should Skip This
The ledger only counts what your process records. It can't see another process under the same account, and without file locking two concurrent writers will interleave lines. It has no pricing knowledge either: per_item and REPLAY are yours to measure, and they drift when prompt lengths or retry behavior change. Most importantly, admission control does not override the provider's own rate limiter; if the endpoint returns 429, stop the batch instead of retrying around the limit.
Skip all of this if you run one interactive session at a time, if your work items are genuinely non-repeatable and can't be idempotent, or if you already have a billing dashboard that reports real spend per key. For a free-tier nightly batch whose quota window closes, this ledger is about forty lines, and it turns a silent failure into a printed plan.
If you want to try the tree end to end, MonkeyCode's free model access and free server option give you a real budget constraint to run these leaves against — confirm the current quota and server terms on the project page first, then let the ledger, not the cron entry, decide what runs tonight.
One-line Summary
Free-tier agent jobs lack admission control and fail silently; a forty-line quota ledger plus a four-leaf decision tree fixes it.
Paragraph Summary
The article argues that free-tier agent batch jobs commonly ship with routing logic but no admission control, so when a quota window closes mid-run, the job ends with exit code 0 while emitting wrong labels. The author proposes a local quota ledger built only on the Python standard library that appends a JSON line per attempt, bills failures and retries alike, and uses a hard SAFETY multiplier to force plans to absorb a 20% estimation error. On top of it sits a four-leaf decision tree: Leaf A admits as-is, Leaf B shrinks the batch, Leaf C defers to the next window, and Leaf D reroutes the overflow. The article hand-computes all four leaves against a fixed fixture, stresses testing the deterministic decision logic rather than the model — covering boundary fixtures, the conservation property, retry billing, and window rollover — and notes the ledger's limits: it can't see concurrent processes, has no pricing knowledge, and doesn't replace provider rate limiting.
Related articles

2026 AI Coding Tools Comparison: Claude, ChatGPT, Gemini — Which Is the Best?
A 2026 comparison of five mainstream AI coding tools — Claude Code, ChatGPT Codex, Gemini, DeepSeek, and GitHub Copilot — on real projects, pricing, and code quality, to help you decide where that $20/month should go.

ChatGPT Codex Can Clone Any Software? Testing the Risks and the Truth
YouTube shorts claim ChatGPT Codex or Claude Code can clone Adobe, Excel, and Figma for lifelong free use. We break down the feasibility, legal risks, and DM-funnel tactics—and explain what AI coding tools are truly good for.

Kilo Code Is Free to Install but Charges for API: Cost Estimation and Configuration Guide
Kilo Code is free to install, but connected AI models are billed per token. This guide covers VS Code extension and CLI setup and shows how to estimate API costs.