Build a Token-Budgeted LLM Service on a Free Server: A Step-by-Step Tutorial A developer has published a step-by-step tutorial for building a token-budgeted LLM service that runs on a free server. The service, built with Python and the httpx library, tracks token usage and fails loudly when the budget is exceeded, addressing the common problem of unmeasured API usage. The tutorial uses MonkeyCode's free tier, which currently includes 10 million tokens. Last month, a side project died at the API checkout. The code worked. The credit card did not. The fix is not a bigger budget. The fix is a smaller one. This tutorial builds a working LLM endpoint from zero. Every step ends with a verification command. You need a terminal, Python 3.11+, and about thirty minutes. LLM prices keep dropping. My API bills did not. The reason: I never measured usage before adding features. Everyone is talking about agent memory right now. Token accounting is the boring sibling nobody writes about. This tutorial closes that gap. The service you build summarizes incoming text under a hard token budget. It tracks every token it spends. It fails loudly when the budget is exceeded. POST /summarize TokenBudget class that estimates, truncates, and tracksFree tokens still have limits. The budget class makes those limits visible. MonkeyCode offers free model access and a free server option. Disclosure: This article was prepared as part of MonkeyCode's product outreach. At the time of writing, the free tier includes 10 million tokens. Quotas change. Verify the current numbers in the dashboard before you build on them. You need three values: Export them as environment variables: export MONKEYCODE API KEY="..." export MONKEYCODE BASE URL="..." export MONKEYCODE MODEL="..." Verification: curl -s "$MONKEYCODE BASE URL/models" \ -H "Authorization: Bearer $MONKEYCODE API KEY" The exact path lives in the current docs. If the response lists models, you are ready. mkdir budget-llm && cd budget-llm python3 -m venv .venv source .venv/bin/activate pip install httpx Verification: python python -c "import httpx; print httpx. version " One dependency. That keeps the free server deployment boring. Boring is what you want in production. Create budget.py . The example assumes an OpenAI-compatible chat endpoint. Confirm the request shape in the current docs before running. python budget.py import os import httpx class TokenBudget: def init self, limit: int, base url: str = "", api key: str = "", model: str = "" : self.limit = limit self.spent = 0 self. base url = base url or os.environ "MONKEYCODE BASE URL" self. api key = api key or os.environ "MONKEYCODE API KEY" self. model = model or os.environ "MONKEYCODE MODEL" self. client = None def get client self - httpx.Client: if self. client is None: self. client = httpx.Client base url=self. base url, headers={"Authorization": f"Bearer {self. api key}"}, timeout=30.0, return self. client @staticmethod def estimate text: str - int: Heuristic: about four characters per token. return max 1, len text // 4 def fit self, text: str - str: budget = self.limit - self.spent - 100 reserve room for the reply if budget <= 0: raise RuntimeError "Token budget exhausted" while self.estimate text budget: text = text : len text // 2 return text def summarize self, text: str - str: prompt = self.fit text response = self. get client .post "/chat/completions", json={ "model": self. model, "messages": {"role": "system", "content": "Summarize in three sentences."}, {"role": "user", "content": prompt}, , }, response.raise for status data = response.json usage = data.get "usage", {} self.spent += usage.get "total tokens", self.estimate prompt return data "choices" 0 "message" "content" The fit method is the safety valve. It halves the text until it fits. It never guesses about the reply size. python python - <<'PY' from budget import TokenBudget tb = TokenBudget limit=2000 text = open "README.md" .read 10 print tb.summarize text print "spent:", tb.spent PY Verification: the output is three sentences. The spent value is below 2000. Use a real article for the first real run, not a README. If the script raises "Token budget exhausted", the truncation path is working. That is a pass, not a failure. A budget you cannot hit is not a budget. Create server.py with the standard library only. No FastAPI. No uvicorn. No extra install step. python server.py import json import os from http.server import BaseHTTPRequestHandler, HTTPServer from budget import TokenBudget tb = TokenBudget limit=int os.environ.get "TOKEN LIMIT", "2000" class Handler BaseHTTPRequestHandler : def do POST self : length = int self.headers.get "Content-Length", 0 payload = json.loads self.rfile.read length try: summary = tb.summarize payload "text" self.send response 200 self.end headers self.wfile.write json.dumps {"summary": summary, "spent": tb.spent} .encode except Exception as exc: self.send response 429 self.end headers self.wfile.write json.dumps {"error": str exc } .encode def log message self, args : pass HTTPServer "0.0.0.0", 8000 , Handler .serve forever Push the folder to the free server. The exact deploy command is in the current dashboard. The pattern is always the same: upload the folder, set the environment variables, run python server.py . Verification: curl -s -X POST https://