You got free model access and a free server. Why is everything still slow?
I kept hearing the same excuses. "It's free, so it's bad." Or worse: "It's free, so it's fine."
Both are wrong. Let me bust five myths I've verified in real projects.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
Myth 1: "Free means unlimited invocations"
Free tiers have limits. They also have burst windows and quiet periods.
Treat every free endpoint as a shared resource. Your neighbor's batch job can starve your calls.
Evidence: Run a 10-minute probe. Log status codes and response times. You'll see patterns that look like traffic shaping, not random noise.
Correct mental model: Free capacity is a noisy shared bus. Design for contention, not isolation.
Myth 2: "The server is always awake"
A free server spins down. Cold starts eat 2-5 seconds before your first byte.
Your test suite hides this. Local calls look instant. Remote calls don't.
Evidence: Send a request, wait 30 seconds, send again. Compare the first p50 to the second.
Correct mental model: Treat your server like a parking brake. You pay for re-engagement, not just parking.
Myth 3: "Latency is the model's fault"
Most pipeline latency lives between your code and the model.
Serial round trips, retry storms, and oversized payloads dwarf model inference.
Evidence: Add timestamps at every hop: client send, gateway arrival, provider receive. Count where the milliseconds actually go.
Correct mental model: The model is one hop. The network and your own code are five more.
Myth 4: "Caching is overkill for free stuff"
Caching is more important when resources are scarce.
A 70% cache hit rate turns ten slow calls into three slow calls. That's real.
Evidence: Log request hashes. Check how many identical prompts repeat hourly. You'll find duplicates.
Correct mental model: A free cache TTL is a cheap way to buy back free-tier headroom.
Myth 5: "One model fits every task"
Small tasks deserve small models. Big tasks deserve bigger ones.
Using one model for everything wastes tokens and time. Classification, extraction, and chat have different sweet spots.
Evidence: Run a pairwise comparison. Same input, three model sizes, one output contract. Measure accuracy and latency.
Correct mental model: Route by complexity. Save the heavy model for the hard 20%.
Artifact: The Latency Budget Probe
Here's a minimal script that measures each hop. Save it as probe.mjs.
const endpoint = process.env.ENDPOINT;
const iterations = Number(process.env.ITERATIONS || 20);
const timings = [];
async function request() {
const t0 = performance.now();
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 10000);
try {
const res = await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt: 'Hello' }),
signal: controller.signal
});
const t1 = performance.now();
timings.push(t1 - t0);
return res.status;
} finally {
clearTimeout(timer);
}
}
// Run a warm-up call, then measure.
await request();
timings.length = 0;
for (let i = 0; i < iterations; i += 1) {
const delay = i % 3 === 0 ? 250 : 50; // simulate traffic
await new Promise(resolve => setTimeout(resolve, delay));
await request();
}
timings.sort((a, b) => a - b);
const p50 = timings[Math.floor(timings.length * 0.5)];
const p95 = timings[Math.floor(timings.length * 0.95)];
console.log(JSON.stringify({ p50, p95, samples: timings.length }, null, 2));
Run it against your free server and your model gateway separately. Compare the numbers.
If p50 jumps when you add a delay, your idle behavior is the problem. If p95 explodes during quiet periods, you are seeing cold starts.
A small decision table
| Symptom | Likely cause | First fix |
|---|---|---|
| First call slow, rest fast | Cold server | Keep-alive ping |
| Random 429s | Shared quota | Retry with backoff + jitter |
| All calls slow | Network / auth overhead | Reuse connections, trim JSON |
| Consistent p95 spike | No cache | Add TTL cache keyed by prompt hash |
Limitations
This probe won't tell you the provider's internal queue. It only measures end-to-end latency, plus your local process time.
I didn't test every free tier. Some have hard concurrency limits that require queuing on your side.
Don't use this approach for production monitoring. Use a proper APM with alerting instead.
Who should not use free infrastructure this way
If your feature must answer in under 500ms every single time, free model + free server is the wrong bet.
If you have strict data residency rules, verify where the endpoint sits before sending anything.
And if you can pay a few dollars a month, do. Free is a learning sandbox, not a reliability contract.
The corrected mental model
Free model access plus a free server is a great prototyping combo. Treat it like a borrowed bike, not a company car.
Measure first. Optimize the hops that matter. Then decide if you need to pay.
You'll save your free quota for real work. You'll also stop blaming the model for your own cold starts.
Top comments (0)