Part 4 — Beyond the MVP · 18 min read
MVP thinking vs scale thinking
Every shortcut you took was a loan. Here's what each one costs and when it comes due.
Every shortcut in Parts 2 and 3 was deliberate. Skipping caching, indexes, background jobs and tests was the right call — those things cost time you didn't have, to solve problems you didn't have either.
But a shortcut isn't a mistake you got away with. It's a loan with a trigger condition. This page is the list of what you borrowed, what each one costs when it's called in, and roughly when that happens — so that the day your app gets slow, you recognise it instead of panicking.
What you borrowed
| The shortcut | What it looks like when it comes due | Roughly when |
|---|---|---|
| No database indexes | A page that was instant now takes several seconds, and gets worse every week | Around 10,000+ rows in a table you filter or sort on |
| Fetching everything, then filtering in code | Sudden slowness and memory errors, often all at once | A few thousand rows |
| A query inside a loop (the "N+1") | A list page that's fine with 5 items and unusable with 200 | Your first power user |
| No pagination | A page that tries to render 2,000 rows and freezes the browser | Your first power user |
| Sending email during the request | Forms that hang or time out whenever the email provider is slow | Immediately, intermittently — the worst kind of bug |
| No rate limiting | One bot, one script, or one bad actor runs up your bill or floods your database | Within days of being publicly reachable |
| No background jobs | Anything slow — imports, reports, image processing — blocks the user | The first feature that isn't instant |
| No monitoring | You find out things are broken when a customer emails you, if they bother | User one |
| No tests | Every change risks silently breaking something that used to work | Around 5+ features, or the moment a second person touches it |
| No staging environment | You test in production, in front of customers | The first time a deploy goes wrong |
| Everything in one region | Sluggish for users far from your database | Day one if you picked the wrong region — see the stack page |
Don't fix these yet
The instinct on reading that table is to go and pre-emptively fix all of it. Resist. Most of these never come due, because most MVPs never reach the scale that triggers them — and time spent on a problem you don't have is time not spent finding out whether anyone wants the product.
So: measure before you optimise. Almost every "the app is slow" problem turns out to be one specific query, one page, or one missing index — not a stack that needs replacing. Find the actual slow thing before changing anything.
What actually breaks first
In practice, and roughly in order:
- One database query. Almost always. A missing index or a query inside a loop. Usually a one-line fix once found.
- Something slow blocking a request. An email send, a file upload, an external API call that's having a bad day.
- Cost. Not the app breaking — your bill breaking. Usage-based services, or an AI feature that costs more per user than you charge.
- You. Long before the technology strains, the bottleneck is a solo founder who can't ship fast enough and is afraid to change anything.
Notice that the fourth is the most common, and it's the one this whole guide has been quietly addressing.
Rewrite or refactor?
At some point something will feel bad enough that "we should just rebuild it properly" becomes tempting — possibly suggested by a developer you've brought in.
It is almost always the wrong answer. A rewrite throws away every bug you've already found and fixed, every edge case you've handled, and every piece of knowledge embedded in the code — and it takes far longer than anyone estimates. Meanwhile your product stops improving for the duration.
| Refactor (nearly always) | Rewrite (rarely) |
|---|---|
| The app works; parts of it are messy or slow | The fundamental data model is wrong in a way that makes correct behaviour impossible |
| Change one area at a time, keeping it working throughout | You're on something genuinely unmaintainable or unsupported |
| You keep shipping while you improve | What you validated is materially different from what you'd build now |
If a contractor's first instinct is "this is all rubbish, let's start again" — get a second opinion. Sometimes they're right. More often it's the reflex of someone who'd rather write new code than read yours. There's more on evaluating that reaction in When to get tech advice.
Signals you've genuinely outgrown MVP mode
Not "I have more users" — these:
- Downtime now costs money or trust. You need monitoring, backups you've actually tested, and a staging environment.
- You're afraid to change things. That fear is the precise symptom that tests are now cheaper than not having them.
- Someone else is editing the code. Branches, pull requests and reviews stop being ceremony and start being necessary.
- You hold data you genuinely cannot lose. Backups, restore drills, and the privacy program in Personal data, properly.
- A customer is doing diligence on you. Business customers will ask about backups, access control, and where data is stored, and your answers need to be true.
Audit this project for scaling problems — but be realistic about my stage rather than listing every best practice.
For each issue found, tell me:
1. Where it is (file and line) and what it does
2. At roughly what scale it becomes a real problem — be specific: how many rows, users, or requests
3. What the symptom would look like to me, in plain English, when it happens
4. How hard the fix is, honestly: minutes, hours, or a project
5. Whether I should fix it now, at my next milestone, or leave it
Look specifically for: missing database indexes, queries inside loops, unbounded queries with no limit or pagination, slow work happening during a request, missing rate limits, and anything that would hold too much in memory.
Rank by "most likely to hurt me first", not by severity in the abstract. I'd rather fix three real things than read about thirty theoretical ones.
My app feels slow on [describe the page or action]. I don't want to guess at the cause.
Teach me to diagnose it properly:
1. How do I measure what's actually slow, using tools I already have — the browser's network and performance tabs, and my hosting dashboard?
2. Walk me through interpreting what I find: what numbers are normal, what numbers are bad, and where the time is actually going.
3. Based on the code, what's your hypothesis for the cause?
4. What's the cheapest way to confirm or disprove that hypothesis before changing anything?
5. Only then: what's the smallest change that would fix it, and what improvement should I expect?
Afterwards, tell me how to re-measure so I know whether the fix actually worked, rather than assuming.
I want to know whether this app will survive growth, without over-engineering for scale I don't have.
My realistic expectations: [X users in 6 months, each with roughly Y records, mostly active at Z times].
Tell me:
1. Which parts of the app would struggle first under that load, and why
2. What would break at 10x that, and at 100x
3. Which of those problems are cheap to prevent now versus expensive to fix later — this is the only list I actually care about
4. Which are fine to leave entirely until they happen
5. How I could generate realistic test data and see the slowdown for myself before real users do
Be honest if the answer is "this will be completely fine and you should go and talk to customers instead".
Someone has suggested that [describe the area, or the whole app] should be rebuilt rather than improved.
Argue both sides properly:
1. The strongest honest case for rebuilding, including what specifically is wrong that can't be fixed incrementally
2. The strongest honest case for improving it in place, including what we'd lose in a rebuild
3. What a staged, incremental version of the change would look like — could we get 80% of the benefit without stopping?
4. A realistic time estimate for each path, for a non-technical founder working with AI tools
5. What the product would cost me in lost progress during a rebuild
Then give me your actual recommendation and the one fact that would change it. Bias toward incremental unless the case for rebuilding is genuinely overwhelming.
Run the debt-audit prompt. From what comes back, write the five most relevant into docs/debts.md — one line each, with the trigger condition: "no index on bookings.start_time — becomes a problem past ~10k bookings".
You'll know it worked when you have a short list you could hand to a developer that says "I know about these, and here's when each matters". That document is worth more than fixing any of them today.
Ask the AI to generate 5,000 realistic records for your main table and load them into a development database — never production. Then use the app: load the list page, search, sort, open a detail page.
You'll know it worked when you've found at least one thing that's noticeably slower than with ten records. That's your first real debt coming due, discovered by you in private rather than by a customer.
Open your deployed app, press F12, go to the Network tab, and reload your heaviest page. Find the request that takes longest. Write the number down.
You'll know it worked when you can say "my dashboard takes 1.8 seconds and most of that is one database call". You've just moved from "it feels slow" to a measurement — which is the entire difference between fixing a problem and guessing at one.