Arketo
All posts

How to review the architecture of a vibe-coded app

· Arketo team

Vibe coding is the fastest way anyone has ever built software. You describe what you want, the assistant writes it, and an hour later there's a working app. The catch hides inside the word "working": it works the way a demo works. One machine, one user, a hundred rows in the database.

The code itself is usually fine. What nobody reviewed is the architecture: how the pieces connect, where data crosses a trust boundary, and what happens to everything else when one piece gets slow. That shape exists from the moment you ship, whether or not anyone has looked at it.

Here's the review we run on every prompt-built app, in the order the problems tend to bite.

1. Walk the hot path

Take the single most common user action, loading the dashboard, submitting the form, opening the feed, whatever it is for your app, and trace every hop it makes: browser, server, database, external APIs, back.

Three questions at each hop:

  • Is this call synchronous? A slow third-party API on the hot path makes your app exactly as slow as their worst day.
  • Does it run per item? An N+1 query is invisible with a hundred rows and fatal with a hundred thousand.
  • What happens if this hop fails? "The whole page errors" can be an acceptable answer. It just shouldn't be a surprising one.

Assistants love inlining external calls, because inline makes the demo work in one shot. It's the same pattern that times out under real traffic.

2. Draw the auth boundary, then look for paths around it

Vibe-coded apps almost always have an auth check. The failure mode is traffic reaching an endpoint along a path nobody drew: an API route that missed the middleware, a webhook handler that trusts its payload, an admin page whose only protection is that nothing links to it.

List every route that can be reached from outside. For each one, name the check that guards it. Any route where the honest answer is "the frontend doesn't link there" fails the review.

3. Find the single point of failure

Somewhere in the system there's one component everything quietly leans on. One database, one cache, one queue, one cron job. That's normal for a small app. What matters is knowing which one it is and what its blast radius looks like:

ComponentIf it blinks for 30 seconds
DatabaseEverything is down. Known, acceptable.
Redis cacheShould degrade to "slow". Often crashes instead.
Background workerEmails silently stop. Nobody notices for days.

The middle row is the classic trap: a cache added for speed that turned into a hard dependency, because nothing was ever written to handle its absence.

4. Look for the cliff, not the curve

Prompt-built systems rarely degrade gracefully. They hold up fine until some shared resource saturates, a connection pool, a rate limit, a queue depth, and then everything slows down at once while every individual component still looks healthy.

Find your shared resources and learn their actual limits. A default Postgres pool of 10 under a serverless platform that spawns 50 concurrent functions isn't a hypothetical. It's the most common outage we see.

If you'd rather work from a runnable list than a walkthrough, the production-readiness checklist is its own post.

You have to see it first

Every step above starts the same way: you need to see the system. Which service calls which, where the boundaries sit, what leans on what. Reading the code file by file won't get you there, because a system isn't its files.

That gap is why Arketo exists. You connect the assistant that built the app, it draws the real architecture on a canvas, and the bottleneck, the missing boundary and the single point of failure become things you find on a diagram instead of in an incident. Try it on a live diagram, no signup needed.