{"slug": "a-budget-guard-for-llm-calls-cap-daily-spend-in-a-small-business-automation", "title": "A Budget Guard for LLM Calls: Cap Daily Spend in a Small-Business Automation (Python)", "summary": "A developer published a Python budget guard that wraps every LLM call, tracks a running daily spend in a JSON state file, and raises a BudgetExceeded exception once a configurable cap is reached, routing the item to a human queue instead. The guard estimates input tokens from prompt length and projects cost using per-1K input and output rates pulled from environment variables, so caps and pricing are never hard-coded. The approach is framed as a way for small businesses to degrade to manual processing rather than drop enquiries when a runaway loop would otherwise burn through spend overnight.", "body_md": "Estimating model spend before launch is useful. Stopping a runaway loop at 2 a.m. is more useful. For small businesses, [keeping small-business automation spend predictable](https://www.nxflowai.com/blog/how-to-audit-business-workflow-before-ai) matters more than squeezing the last fraction out of each call.\n\nThis guard wraps every model call, keeps a running daily total and refuses calls once a cap is reached, routing the item to a person instead.\n\n``` python\nimport json, os, time, datetime\n\nSTATE = \"budget_state.json\"\nDAILY_CAP = float(os.environ.get(\"DAILY_CAP\", \"0\"))       # set in your own currency units\nRATE_IN = float(os.environ.get(\"RATE_PER_1K_IN\", \"0\"))    # from your provider's pricing page\nRATE_OUT = float(os.environ.get(\"RATE_PER_1K_OUT\", \"0\"))\n\nclass BudgetExceeded(Exception):\n    pass\n\ndef _load():\n    today = datetime.date.today().isoformat()\n    if os.path.exists(STATE):\n        s = json.load(open(STATE))\n        if s.get(\"day\") == today:\n            return s\n    return {\"day\": today, \"spent\": 0.0, \"calls\": 0}\n\ndef _save(s):\n    json.dump(s, open(STATE, \"w\"))\n\ndef guarded_call(call_model, prompt, est_out_tokens=300):\n    s = _load()\n    est_in = len(prompt) / 4  # rough token estimate\n    projected = s[\"spent\"] + est_in / 1000 * RATE_IN + est_out_tokens / 1000 * RATE_OUT\n    if DAILY_CAP and projected > DAILY_CAP:\n        raise BudgetExceeded(f\"cap reached: {s['spent']:.2f} spent today\")\n    result, used_in, used_out = call_model(prompt)\n    s[\"spent\"] += used_in / 1000 * RATE_IN + used_out / 1000 * RATE_OUT\n    s[\"calls\"] += 1\n    _save(s)\n    return result\n```\n\nUse it like this:\n\n```\ntry:\n    reply = guarded_call(my_model_fn, prompt)\nexcept BudgetExceeded:\n    send_to_human_queue(item, reason=\"daily model budget reached\")\n```\n\nThe business still needs the work done. A capped day should degrade to the manual process, not drop enquiries.\n\nThe rates and the cap are yours to set from your provider's pricing page; never hard-code them. More build notes are on our engineering blog index.", "url": "https://wpnews.pro/news/a-budget-guard-for-llm-calls-cap-daily-spend-in-a-small-business-automation", "canonical_source": "https://dev.to/ujjwal_dubey_9/a-budget-guard-for-llm-calls-cap-daily-spend-in-a-small-business-automation-python-3m8g", "published_at": "2026-11-13 14:36:19+00:00", "updated_at": "2026-11-13 14:52:14.822592+00:00", "lang": "en", "topics": ["ai-tools", "large-language-models", "ai-agents", "developer-tools"], "entities": ["nxflowai.com"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/a-budget-guard-for-llm-calls-cap-daily-spend-in-a-small-business-automation", "markdown": "https://wpnews.pro/news/a-budget-guard-for-llm-calls-cap-daily-spend-in-a-small-business-automation.md", "text": "https://wpnews.pro/news/a-budget-guard-for-llm-calls-cap-daily-spend-in-a-small-business-automation.txt", "jsonld": "https://wpnews.pro/news/a-budget-guard-for-llm-calls-cap-daily-spend-in-a-small-business-automation.jsonld"}}