DEV Community

purecast
purecast

Posted on

Quick Tip: How I Cut AI API API Costs by 95% as a Freelancer

Quick Tip: How I Cut AI API API Costs by 95% as a Freelancer

Last March I opened my first real API invoice and nearly spit coffee on my laptop. $1,847. For one client project. One month.

I'd been happily slamming the "default" button on every request — GPT-4o for everything, because hey, if it's good enough for the demos it's good enough for production, right? Wrong. That single month cost me more than my rent, and I was the one writing the check. So I went down a rabbit hole. I read every pricing page I could find. I ran benchmarks at 2am. I built spreadsheets mapping tokens to dollars like a maniac. And what I found turned into the system that now powers every AI project I ship.

Here's the thing nobody tells you when you start freelancing with LLMs: the gap between "convenient model" and "right model" is not 10%. It's not 50%. It's often north of 95%. And once you internalize that, every API call becomes a decision. Every prompt becomes a budget line. Every client deliverable gets a cost column.

I'm going to walk you through exactly what I do. Five moves. All of them boring. All of them stupidly effective. If you're billing clients by the hour, these compound fast.


Move 1: Stop Worshipping GPT-4o (This One Hurt)

I had to admit it out loud: GPT-4o is not always the answer. At $10/M output tokens, it's the "nice restaurant" of LLMs. Sometimes you need it. Most of the time you really, really don't.

The single biggest lever in your entire stack is which model you point your request at. Here's the rough price map I've been working from, which I now reference before every single client call:

What the client actually needs What I used to bill them What I bill them now Savings
Casual chatbot back-and-forth GPT-4o ($10/M) DeepSeek V4 Flash ($0.25/M) 97.5%
Sorting tickets into categories GPT-4o-mini ($0.60/M) Qwen3-8B ($0.01/M) 98.3%
Writing or refactoring code GPT-4o ($10/M) DeepSeek Coder ($0.25/M) 97.5%
TL;DR-ing long docs GPT-4o ($10/M) Qwen3-32B ($0.28/M) 97.2%
Translating between languages GPT-4o ($10/M) Qwen-MT-Turbo ($0.30/M) 97%

Read that table again. Sorting support tickets into "billing" vs "bug" vs "feature request" was costing me 60 cents per million output tokens. It now costs me a penny. One single penny. That's not a discount. That's a different universe.

The key shift for me was admitting that not every task needs the smartest model in the room. A classification job doesn't need a reasoning engine. A translation job doesn't need a code-aware brain. Match the model to the task, not the task to the model.

Here's the kind of routing logic I now run in basically every project:

from openai import OpenAI

# Pointing at Global API's unified endpoint
client = OpenAI(
    base_url="https://global-apis.com/v1",
    api_key="YOUR_KEY",
)

MODEL_MAP = {
    "chat":       "deepseek-v4-flash",   # $0.25/M
    "code":       "deepseek-coder",      # $0.25/M
    "classify":   "Qwen/Qwen3-8B",       # $0.01/M
    "summarize":  "Qwen/Qwen3-32B",      # $0.28/M
    "translate":  "qwen-mt-turbo",       # $0.30/M
    "reasoning":  "deepseek-reasoner",   # $2.50/M
}

def route_and_call(user_input: str) -> str:
    task = classify_complexity(user_input)   # my own little heuristic
    model = MODEL_MAP[task]

    resp = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": user_input}],
    )
    return resp.choices[0].message.content
Enter fullscreen mode Exit fullscreen mode

That tiny block is doing real work. It's deciding, on every single call, whether I'm paying ten bucks per million tokens or one cent. When you're processing a few hundred thousand requests for a client, that decision is the difference between a profitable month and a panic attack.


Move 2: Cache Like You're Broke (Because Right Now, You Are)

The second thing I learned — and this is embarrassing that it took me this long — is that a lot of API calls are duplicates.

Clients ask the same FAQ over and over. Documentation lookups repeat. "What does the refund policy say?" hits my backend maybe 800 times a day. Every single one of those used to be a billable API call. Now? Cache. Hit. Return. Done.

For my side-hustle projects, a simple in-memory dict is fine. For client production stuff, I usually back it with Redis. Same idea either way: hash the inputs, store the response, return it for free if it's still warm.

Here's the cheap-and-cheerful version I use for quick prototypes:

import hashlib, json, time
from openai import OpenAI

client = OpenAI(
    base_url="https://global-apis.com/v1",
    api_key="YOUR_KEY",
)

_cache = {}
DEFAULT_TTL = 3600  # one hour

def cached_chat(model: str, messages: list, ttl: int = DEFAULT_TTL):
    key = hashlib.md5(
        json.dumps({"model": model, "messages": messages}, sort_keys=True).encode()
    ).hexdigest()

    hit = _cache.get(key)
    if hit and time.time() - hit["time"] < ttl:
        return hit["response"]  # free reuse, $0 marginal cost

    response = client.chat.completions.create(model=model, messages=messages)
    _cache[key] = {"response": response, "time": time.time()}
    return response
Enter fullscreen mode Exit fullscreen mode

That's it. Twenty lines. And in practice, on a real client chatbot, my cache hit rate sits somewhere between 50% and 80% for the common stuff. That means roughly half my traffic now costs me literally nothing. Combined with Move 1, my effective cost per request drops like a stone.


Move 3: Shrink Your Prompts Like a Suspicious Landlord

Here's a fun game I play now: I open every system prompt and ask, "does the model actually need this word?"

Long prompts are sneaky cost drains. You're not just paying for output tokens — input tokens count too, and they count on every single request. A 4,000-token system prompt repeated 50,000 times a day is 200 million input tokens you didn't need.

I now do prompt compression for anything over a few hundred tokens. The trick is: I use a cheap model to summarize the expensive model's context. Dogfooding at its finest.

def compress_prompt(text: str, target_ratio: float = 0.5) -> str:
    if len(text) < 500:
        return text  # already short, leave it alone

    target_chars = int(len(text) * target_ratio)
    summary = call_model(
        "Qwen/Qwen3-8B",  # the $0.01/M workhorse
        f"Summarize this in about {target_chars} characters: {text}",
    )
    return summary
Enter fullscreen mode Exit fullscreen mode

The math on this is what made me a believer. I had a client with a 2,000-token system prompt. Compressed it down to 400 tokens. Saved $0.024 per request on DeepSeek V4 Flash. They were doing 10,000 requests a day. That's $240/day. That's $87,600 a year. From a prompt that was just being polite.

I now run compression as a one-time preprocessing step before deployment. The client sees the same quality. My invoice sees something very different.


Move 4: Batch Everything That Breathes

When I started, I was making one API call per question. Three questions? Three calls. Five tickets? Five calls. Each one paying full price for the input prompt.

Then I had my "oh, duh" moment. You can stuff a lot of small jobs into a single request. The prompt is shared across all of them. You're billed for one round-trip instead of ten.

The pattern looks like this:

# Bad: 3 separate calls, 3x input token cost
for question in questions:
    response = client.chat.completions.create(
        model="deepseek-v4-flash",
        messages=[{"role": "user", "content": question}],
    )

# Good: 1 batch call, input prompt amortized across all
batch_prompt = "\n".join(f"{i+1}. {q}" for i, q in enumerate(questions))
response = client.chat.completions.create(
    model="deepseek-v4-flash",
    messages=[{"role": "user", "content": f"Answer each:\n{batch_prompt}"}],
)
Enter fullscreen mode Exit fullscreen mode

That's a 10–20% saving right there, depending on how repetitive your prompts are. For back-office tasks where the client wants 50 emails classified, the difference is meaningful.


Move 5: Tiered Routing — The Big One

This is the move that took my support chatbot client from $420/month down to $28/month.

The idea is simple: try the cheapest model first. If its answer is good enough, ship it. If not, escalate. Most requests never need the premium model.

def smart_generate(prompt: str, max_budget: float = 0.50):
    # Tier 1: ultra-budget — handles the easy stuff
    resp = call_model("Qwen/Qwen3-8B", prompt)        # $0.01/M
    if quality_check(resp) >= 0.8:
        return resp  # ~80% of requests stop here

    # Tier 2: standard — for things the cheap one stumbled on
    resp = call_model("deepseek-v4-flash", prompt)    # $0.25/M
    if quality_check(resp) >= 0.9:
        return resp  # ~15% of requests

    # Tier 3: premium — only the hard stuff
    return call_model("deepseek-reasoner", prompt)    # $2.50/M  (~5%)
Enter fullscreen mode Exit fullscreen mode

That function is worth more than most of my SaaS subscriptions. For that particular client, 85% of incoming tickets got answered by Qwen3-8B. The smart router kicked the remaining 15% up the ladder. End result: 93% cost reduction. Same quality on the front end.

When you combine all five moves — right model, caching, compressed prompts, batching, tiered routing — the cumulative savings land somewhere around 95%. On a client that's running serious volume, that's the difference between a six-figure API bill and a few hundred bucks a month.


The Part Where I Do the Math on My Own Projects

I want to put real numbers on this, because "90% savings" is the kind of stat freelancers scroll past.

A typical mid-sized client integration I run today:

  • ~300,000 requests/month
  • Average 800 input tokens, 400 output tokens per request
  • All on GPT-4o originally: roughly $3,600/month
  • After Move 1 alone (right model): roughly $360/month
  • After caching + compression + batching: roughly $180/month
  • After tiered routing on top: roughly $72–90/month

That's the difference between a project that's a loss leader and a project that funds my coffee habit for the year. Billable hours don't matter if your COGS eats them.


A Few Hard-Earned Lessons

A couple

Top comments (0)