What running an LLM in production actually costs you
Every "build an AI app" tutorial stops at the demo. Prompt goes in, response comes out, ship it. Nobody covers the part where that demo has real users and you're staring at a Gemini or OpenAI invoice trying to figure out which feature did that. I've spent the last several months building the AI layer for a consumer app that fires vision and language calls on almost every user action. Not a chatbot getting occasional traffic. A product where the model call basically is the product. Here's what I actually had to build, in the order I had to build it. Four problems, not one Cost first, obviously. Tokens are metered, and past a certain volume, calling the model on every request means paying for answers you already gave someone five minutes ago. Latency next. A cache hit lands in milliseconds. A cold model call takes seconds. Users feel that, especially anything camera-driven where they're staring at a loading spinner over their own kitchen counter. Reliability too. Your provider will have an outage or a degraded day at some point. Not if, when. And blast radius. One bug, one bot, one traffic spike, and a $50/day bill becomes a $5,000/day one while everyone's asleep. You don't see any of this in a demo. It shows up with real traffic, and by then it's a lot more expensive to fix than it would've been to build right the first time. Cache on what the query means, not its exact string Key your cache off the literal request text and you've built something close to useless. "What can I make with chicken and rice" and "chicken and rice, what should I cook" mean the same thing and share almost no characters. So embed the query, run a vector similarity search against everything already answered, and if something clears a high threshold, serve that instead of paying for another call. I use 0.95 cosine similarity as the bar. async function checkSemanticCache(embedding: number[], taskType: string, threshold = 0.95) { const { data } = await db.rpc("find_similar_response", { query_emb