DEV Community

gentleforge
gentleforge

Posted on

Cutting OpenAI Out of My Stack Without Breaking Production

I gotta say, cutting OpenAI Out of My Stack Without Breaking Production

Six months ago I opened our infrastructure bill and nearly choked. We were burning about $500 a month on OpenAI for what was, frankly, a glorified internal chatbot and a couple of classification jobs. Nothing exotic. No GPT-4o Vision pipelines. No massive embeddings workload. Just a small fleet of API calls doing document summarization and some structured extraction. Five hundred bucks for that.

I'm the CTO of a seed-stage startup. My job is to stretch runway and keep the team shipping. Five hundred a month on one vendor for one product surface is not stretching runway. That's burning it. So I did what any reasonable CTO does when they see a single line item dominating their cloud bill: I started shopping.

What I found on the other side of that shopping trip is the reason you're reading this. There's a whole class of frontier-tier models available through Global API that cost a fraction of what OpenAI charges, and the migration path is so stupidly simple I almost felt silly writing it up. But our team shipped it, our bills dropped, and I figured other founders might want to skip the three weeks of confused Slack threads I went through.

Here's the whole story.

The Vendor Lock-In Problem Nobody Wants to Talk About

I want to be clear about something before we get into pricing tables. Cost matters, but vendor lock-in is the real reason I started this project. OpenAI's SDK is fine. Their models are excellent. But every architectural decision we make that hard-codes api.openai.com/v1 is a decision that makes it harder to negotiate, harder to A/B test, and harder to walk away if pricing changes or quality degrades.

When you're a startup running at scale, your LLM bill isn't a constant. It grows with usage, with experimentation, with the next product surface you bolt on. The provider you picked in week two will not necessarily be the right provider in month eight. I've been through enough vendor cycles to know that the only sane default is: keep the abstraction thin, swap the upstream freely.

So the real goal here wasn't just "save money on OpenAI." It was "build a system where swapping providers is a config change, not a quarter-long rewrite." Everything that follows is in service of that goal.

The Cost Math That Made Me Pick Up the Phone

Let me lay out the numbers I was staring at. I pulled these directly from Global API's pricing page and OpenAI's pricing page on the same day so I knew I was comparing apples to apples. All figures are per million tokens.

GPT-4o from OpenAI: $2.50 input, $10.00 output.
GPT-4o-mini from OpenAI: $0.15 input, $0.60 output. About 16.7× cheaper than GPT-4o on the output side.

Then the alternatives on Global API:
DeepSeek V4 Flash: $0.18 input, $0.25 output. 40× cheaper than GPT-4o.
Qwen3-32B: $0.18 input, $0.28 output. 35.7× cheaper.
DeepSeek V4 Pro: $0.57 input, $0.78 output. 12.8× cheaper.
GLM-5: $0.73 input, $1.92 output. 5.2× cheaper.
Kimi K2.5: $0.59 input, $3.00 output. 3.3× cheaper.

Read that again. DeepSeek V4 Flash, at $0.25 per million output tokens, is forty times cheaper than GPT-4o for what is, in our internal evaluation, comparable quality on the workloads we care about. Forty times.

If we were spending $500 a month on OpenAI, the equivalent bill on DeepSeek V4 Flash would be roughly $12.50. That's not a rounding error. That's the difference between hiring an intern and not.

Now, I'm not going to pretend DeepSeek V4 Flash is a drop-in for GPT-4o on every task. It's not. We have one specific pipeline where we genuinely need GPT-4o's reasoning quality and we still pay for it. But for the 90% of calls that are extraction, summarization, classification, and JSON structuring? The cheaper models crush it. And at scale, that 90% is what dominates the bill.

The Architecture Decision: Drop-In Compatibility Wins

Here's where I almost went down a rabbit hole. My first instinct was to build an internal "model router" service that would abstract away the provider. Smart, right? Multi-cloud, vendor-agnostic, all the buzzwords.

Then I remembered I run a startup, not a hyperscaler. Building an abstraction layer before you have scale problems is a great way to spend six engineering weeks solving a problem you don't have yet.

The right answer, almost always, is the boring one. The OpenAI Python SDK, the JS SDK, the Go SDK, the Java SDK — they all support custom base URLs. The protocol is OpenAI-compatible. That means if a provider speaks the OpenAI wire format, I can swap endpoints by changing exactly two values: the API key and the base URL. That's it. Two lines.

So the architecture I landed on was:

  1. Centralize the base URL and API key in environment variables.
  2. Use the existing OpenAI client libraries, just pointed at Global API.
  3. Pick the model per use case, not per vendor.
  4. Re-evaluate quarterly.

No custom router. No clever proxy. No multi-tenant gateway. Just config. We can build the smart abstraction later, when we have five providers in production and a real reason to fan out traffic dynamically.

The Actual Migration: What I Changed and What Broke

I'm going to walk through what the diff looks like in our actual codebase. We standardized on Python for our backend services and TypeScript for our edge functions, so I'll show both.

Python migration. Here's the before and after, side by side:

from openai import OpenAI

client = OpenAI(api_key="sk-...")

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Summarize this doc..."}],
    temperature=0.7,
    max_tokens=500,
)
Enter fullscreen mode Exit fullscreen mode
# After: Global API, same SDK
from openai import OpenAI

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

response = client.chat.completions.create(
    model="deepseek-v4-flash",
    messages=[{"role": "user", "content": "Summarize this doc..."}],
    temperature=0.7,
    max_tokens=500,
)
Enter fullscreen mode Exit fullscreen mode

That's the whole migration in Python. Two lines changed. The SDK call signature is identical. Streaming works. Function calling works. JSON mode works. I ran our existing test suite against the new endpoint and every single test passed.

TypeScript migration, for our Next.js edge functions:

// Before
import OpenAI from 'openai';
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

const response = await client.chat.completions.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: prompt }],
});
Enter fullscreen mode Exit fullscreen mode
// After
import OpenAI from 'openai';
const client = new OpenAI({
  apiKey: process.env.GLOBAL_API_KEY,
  baseURL: 'https://global-apis.com/v1',
});

const response = await client.chat.completions.create({
  model: 'deepseek-v4-flash',
  messages: [{ role: 'user', content: prompt }],
});
Enter fullscreen mode Exit fullscreen mode

Same pattern. Same SDK. Same call shape. The only thing that changed is the baseURL and the model name.

For our Go service that handles batch processing, we used the official go-openai client and the swap was equally painless — change the config, point BaseURL at Global API, done.

For our Java ingestion worker, same story with the OpenAI Java SDK. The constructor takes a duration and a base URL, and that's where you drop in https://global-apis.com/v1.

For the engineers out there who live in terminals, here's the curl equivalent:

curl https://global-apis.com/v1/chat/completions \
  -H "Authorization: Bearer ga_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"model":"deepseek-v4-flash","messages":[{"role":"user","content":"Hello"}]}'
Enter fullscreen mode Exit fullscreen mode

Same headers. Same body. Same response format. I cannot stress enough how little code actually moved in this migration.

What Works, What Doesn't, and What I Had to Rebuild

I want to be honest about the rough edges, because any CTO evaluating this needs to know where the friction is.

What works identically to OpenAI:

  • Chat completions. Same API, same response shape.
  • Streaming via SSE. Drop-in.
  • Function calling. Same tool/function schema.
  • JSON mode via response_format.
  • Vision. Models like Qwen-VL accept image inputs in the same format.

What doesn't work (yet, or by design):

  • Fine-tuning. Not available through Global API as of right now. If you need fine-tuned models, that's a real reason to stay on OpenAI or build your own training pipeline.
  • The Assistants API. The thread/run/tool-retrieval abstraction is OpenAI-specific. If you depend on it, you'll need to build something equivalent.
  • TTS and STT. Use a dedicated service like ElevenLabs or Whisper hosting.
  • Embeddings are listed as coming soon.

For us, the only thing in that "doesn't work" list that mattered was the Assistants API, and we'd already moved away from it in favor of a simpler function-calling approach six months earlier. So we had no blockers.

If your stack leans heavily on Assistants or fine-tuning, your migration math will look different. But for the 80% case — companies using raw chat.completions with a handful of models — this is a clean swap.

The Production Rollout: How I Did It Without Setting Fire to Anything

I'm a firm believer that production migrations happen behind feature flags. Here's the rollout plan I used:

Week one: Stand up a Global API account. Generate an API key. Configure a staging environment with the new endpoint. Run our entire eval suite against DeepSeek V4 Flash, Qwen3-32B, and GLM-5 on real production traces. Look at the outputs. Look at the latency. Look at the failure modes.

Week two: Pick the model per use case. Our extraction pipeline moved to DeepSeek V4 Flash because it's fast and dirt cheap. Our summarization pipeline moved to Qwen3-32B because the prose quality was slightly better. One high-stakes reasoning job stayed on GPT-4o because we genuinely need it.

Week three: Shadow mode. In production, send each request to both OpenAI and Global API. Compare outputs. Log disagreements. We ran this for five days and the disagreement rate on our structured extraction pipeline was under 3%. Comfortable.

Week four: Cutover. We flipped the default. Old provider kept warm for rollback. Monitored error rates and latency p99s for a week.

Week five: Deleted the OpenAI fallback. Bill dropped from $487 to $14. Engineers celebrated with mediocre office coffee.

The part I'm proudest of: zero downtime, zero customer-visible regressions, and a 97% reduction in that line item.

At-Scale Lessons: What I Wish I'd Known on Day One

A few things I learned that I'd tell past-me if I could:

First, don't over-abstract early. The two-line swap is the migration. Build the smart router when you have a real reason to. Premature abstraction is a startup killer.

Second, model selection is per use case, not per company. "We're a GPT-4o shop" is not a strategy. "We use DeepSeek V4 Flash for extraction, Qwen3-32B for prose, and GPT-4o for the one job that needs it" is a strategy.

Third, eval-driven migration is the only migration. Don't pick the cheapest model. Pick the cheapest model that passes your evals. The difference between "cheap and bad" and "cheap and good" is whether you bothered to measure.

Fourth, vendor lock-in avoidance isn't paranoia. It's just good architecture. The day OpenAI raises prices, the day a competitor launches something better, the day their API has an outage — you want to be able to respond with a config change, not a six-week migration project.

Fifth, Global API gives you access to 184 models through one endpoint. That alone is worth the migration. Model diversity is a strategic asset when you're shipping AI products.

The ROI in Plain English

Let me put numbers on this so my CFO doesn't yell at me. We were spending roughly $500 a month on OpenAI. We're now spending roughly $14 a month on Global API for the same workload, plus about $80 a month on GPT-4o for the one job that genuinely needs it. Total: $94. We went from $500 to $94. That's an 81% cost reduction on a line item that was 8% of our infrastructure spend.

Annualized, that's about $4,800 in saved burn. For a seed-stage startup, that's another month of runway. That's another sprint of features. That's another hire we can defer but not cancel. ROI is not abstract here. It's literal months of life for the company.

And we got it for changing two lines of code in each service.

What I'd Tell Another CTO

If you're staring at your OpenAI bill right now and wondering whether this is worth your time, here's my honest take: yes, but be rigorous about it. Pull your actual usage. Categorize it by use case. Pick a model per use

Top comments (0)