← All thoughts

July 29, 2026

Your AI-built app works on your laptop. Here's what breaks in production.

A practical list of what actually goes wrong when a vibe-coded prototype meets real users — and why none of it means you did something wrong.

Every prototype I've been handed in the last year has followed the same arc: someone used Cursor or Claude or Replit, got something working in a weekend, showed it to a few people, and got genuinely excited. Then they tried to put real users on it, or raise money, or hire their first engineer — and hit a wall they didn't know was there. None of this means they did anything wrong. It means "it works on my laptop" and "it works in production" are different problems, and nobody tells you that up front.

Here's what actually breaks, in the order I usually find it.

Auth was never really finished

Test users hardcoded in, sessions that never expire, no rate limiting on login attempts. It's not that auth is hard to build wrong — it's that auth is easy to build just enough to demo, and the gap between "demo enough" and "production enough" is invisible until someone tries to abuse it.

Secrets are sitting in the code

API keys, database passwords, and email credentials committed straight into the repo, sometimes because it was faster, sometimes because nobody explained where they should actually live. I just went through this exact cleanup on my own site's repo — even careful people end up with something in git history that shouldn't be there. It happens to almost everyone; the fix is just to actually check.

The database schema was designed for the demo, not for scale

No indexes, no foreign key constraints, sometimes no real migration strategy at all — just editing the schema by hand and hoping. Fine for 50 test rows. Falls over in a specific, unpleasant way somewhere between 10,000 and 100,000 rows, usually right when you can least afford the distraction.

Error handling only covers the happy path

One unexpected input, one failed API call, one edge case nobody tested, and the whole thing crashes instead of degrading. Worse: often there's no logging, so the first sign of trouble is a user telling you something's broken, not a system telling you.

Third-party calls have no retry or timeout logic

Your app is only as reliable as the flakiest external service it depends on, and most AI-assisted code doesn't defend against that at all — one slow API call away from the whole request hanging.

Deployment is a manual, unrepeatable process

Uploading files by hand, no CI/CD, no rollback plan. It works until the one time you need to undo a bad change fast, and you can't.

Nobody's watching it

No monitoring, no alerting, no real visibility into what's actually happening in production. You find out about outages from users instead of from your own systems.

None of this is exotic

These are the same handful of things that have always separated a demo from a product — AI-assisted development didn't invent them, it just made it possible to get further before you hit them. That's actually the useful way to think about it: the prototype did its job. It proved the idea. The work now is the same work it's always been.

Have a prototype that needs to become a real product?

Fractional CTO, AI workflows, and agent teams — let's talk about what you're building.

Let's Talk