Every developer has an internal debate when they see a free tier: is this a genuine resource or a lead magnet? The announcement says free models, and perhaps even a free server. The words sound like the same thing, yet they are not. A model quota and a server lease answer entirely different questions. The first asks how many tokens you can burn, the second asks whether something stable will still be alive next Tuesday at 3 a.m. This article builds a small, reproducible verification toolkit for both promises, and it applies that toolkit honestly to MonkeyCode, an open-source project whose outreach currently includes free models and a free server option.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
The argument here is deliberately narrow. Public documentation gives you intentions, not behavior. A quota table tells you the upper bound in the best case, while the real contract hides inside response headers, latency spikes, and the quiet moment when a 429 appears without a Retry-After header. Instead of arguing about marketing numbers, we can write a few scripts that convert the free models claim into observations, then a cron job that converts the free server claim into an uptime percentage. Thirty minutes of work buys you a decision you can defend with data.
The first tool is a model and usage probe. Most modern LLM gateways follow an OpenAI-compatible surface, which means you can inspect the available models and then send a minimal completion. The script below assumes you have a MonkeyCode API key or any other OpenAI-compatible endpoint. It prints three things: whether the server answers, what rate limit headers exist, and what the usage object says in the response body.
import requests
import time
def probe(base_url, api_key, model="default"):
headers = {"Authorization": f"Bearer {api_key}"}
# 1. Can we even list models?
models_r = requests.get(f"{base_url}/models", headers=headers, timeout=10)
print(f"GET /models -> {models_r.status_code}")
rate_headers = {k: v for k, v in models_r.headers.items() if "ratelimit" in k.lower()}
print(f"rate-limit headers: {rate_headers or 'none'}")
# 2. One tiny completion
payload = {
"model": model,
"messages": [{"role": "user", "content": "ping"}],
"max_tokens": 1
}
t0 = time.time()
r = requests.post(f"{base_url}/chat/completions", json=payload, headers=headers, timeout=15)
dt = time.time() - t0
print(f"POST /chat/completions -> {r.status_code} in {dt:.2f}s")
if r.ok:
data = r.json()
print(f"usage field: {data.get('usage')}")
print(f"model echoed: {data.get('model')}")
else:
print(f"error body: {r.text[:200]}")
return r.status_code, dict(rate_headers)
if __name__ == "__main__":
probe("https://api.monkeycode.example.com/v1", "your-key")
This tiny probe separates the free models claim from the free server claim. A working /models call proves the server is reachable. A usage object that shows prompt_tokens and total_tokens proves the model quota is being tracked. Rate limit headers prove that the provider wants you to know when you are close to the edge. When a free models offer returns none of these signals, the offer is still valid technically, but it becomes impossible to monitor, and therefore impossible to rely on.
The second tool is a burst test. Token counts are easy to advertise, but the painful constraint is almost always requests per minute. A free models tier can grant you a million tokens while silently limiting you to one request every ten seconds. The following script fires one request per second for a minute and records the moment the API starts pushing back.
import requests
import time
from collections import Counter
def burst(base_url, api_key, model="default", iterations=60):
headers = {"Authorization": f"Bearer {api_key}"}
statuses = Counter()
first_429 = None
for i in range(iterations):
payload = {
"model": model,
"messages": [{"role": "user", "content": f"probe number {i}"}],
"max_tokens": 1
}
try:
r = requests.post(f"{base_url}/chat/completions", json=payload, headers=headers, timeout=10)
except requests.RequestException as exc:
print(f"iteration {i}: network error {exc}")
statuses["network_error"] += 1
continue
statuses[r.status_code] += 1
if r.status_code == 429 and first_429 is None:
first_429 = i
retry = r.headers.get("Retry-After")
print(f"first 429 at iteration {i}; Retry-After: {retry}")
if i % 10 == 0:
print(f"iteration {i}: {r.status_code}")
print(f"status distribution: {dict(statuses)}")
print(f"first 429 at: {first_429}")
return statuses, first_429
if __name__ == "__main__":
burst("https://api.monkeycode.example.com/v1", "your-key")
The practical takeaway from this burst test is the request budget, not the token budget. If the free models tier supports 60 rapid requests without a single 429, you have room for a small automation bot. If the 429 arrives at iteration 12, you know that real-world latency or heavier prompts will make the free tier unusable for a periodic job. In the case of MonkeyCode, the advertised 10 million tokens describe the volume, but only the burst test describes the rhythm.
The third tool is the one that targets the free server claim specifically: an uptime poller. A server is a relationship, not a static entity. It has a heartbeat, a response time, and a tendency to break during your vacation. The free server option means someone else is paying for the hardware, but it does not guarantee a five-nines SLA. A simple cron job running every five minutes gives you the evidence.
#!/bin/bash
# health-poller.sh
URL="https://api.monkeycode.example.com/v1/models"
AUTH="Authorization: Bearer $API_KEY"
code=$(curl -s -o /dev/null -w "%{http_code}" -H "$AUTH" "$URL")
time=$(curl -s -o /dev/null -w "%{time_total}" -H "$AUTH" "$URL")
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) $code $time" >> uptime.log
Run this every five minutes for a week, then compute the percentage of non-2xx responses. That percentage is the free server's real availability. There is no universal pass mark, but a simple decision table makes the evaluation boring and repeatable.
| Weekly non-2xx rate | Interpretation | Recommended action |
|---|---|---|
| 0% – 1% | Excellent for a free tier | Keep using for dev and cron |
| 1% – 2% | Acceptable for prototypes | Add retries and backoff |
| 2% – 5% | Borderline for any automation | Restrict to development only |
| > 5% | Broken promise | Switch to paid or self-host |
The table is deliberately conservative. A free server that fails 5% of the time will fail a nightly job roughly twice a week, which is enough to erode trust even if the job is non-critical. The percentage also reveals whether the free server should be treated as infrastructure or as a sandbox.
The fourth tool is a latency histogram. Quota and uptime are necessary but insufficient; a server can answer every request while taking thirty seconds per token. The earlier probe already collects latency samples. A slightly extended version records the time for a fixed three-token response, repeated ten times, and sorts the results.
import requests, time, statistics
def latency_histogram(base_url, api_key, model="default", samples=10):
headers = {"Authorization": f"Bearer {api_key}"}
times = []
for _ in range(samples):
payload = {
"model": model,
"messages": [{"role": "user", "content": "Say hi"}],
"max_tokens": 3
}
t0 = time.time()
r = requests.post(f"{base_url}/chat/completions", json=payload, headers=headers, timeout=30)
times.append(time.time() - t0)
time.sleep(1)
print(f"min: {min(times):.2f}s, median: {statistics.median(times):.2f}s, max: {max(times):.2f}s")
return times
A consistent median below two seconds means the free server feels like a local model. A median above ten seconds means the server exists monetarily, but the free models behind it are too slow for any interactive tool. This metric matters most for the free server option, since a distant box that responds slowly is effectively worse than a local small model.
All of these checks lead to a clean mental model. The free models claim says something about a quota; the free server claim says something about infrastructure. Neither claim is proof of reliability. Verification turns each claim into a number. The numbers then combine into a verdict. If MonkeyCode passes the burst test with no 429 below 60 requests and the uptime log stays above 98%, the free tier becomes a reasonable budget option for development, evaluation, and small internal tools. If either check fails, the same evidence tells you to cap your usage or pay for the guaranteed tier.
Who should not use this approach? First, teams that need contractual availability. A free server has no SLA, so building a customer-facing product on it is a business risk, not an engineering choice. Second, teams that process sensitive data. A free server may reside in a region you cannot control, and the response logs are outside your governance boundary. Third, teams that cannot tolerate rate limit spikes. If your automation is time-critical and a 429 breaks the whole pipeline, the free models tier needs a paid-level buffer. In those cases, the verification scripts are still valuable; they simply tell you to walk away.
The same discipline extends beyond MonkeyCode to every free model provider you encounter. Quotas are hypotheses. Servers are living systems. Rate limits hide in headers. A developer who internalizes this pattern avoids the most expensive free tier in the world: the one that works for the first three days and then burns a weekend in debugging sessions.
If you want to try the verification workflow yourself, MonkeyCode's free models and free server give you a concrete target. Grab a key, run the burst test, leave the poller running for a week, and decide with your own log file instead of someone else's landing page. When the data is in your hands, the marketing words become irrelevant.
Top comments (0)