It was fast when you had ten customers
The app felt quick at launch. Now pages take a few seconds, reports time out at month end, and your biggest customer complains that their dashboard spins. Support tickets mention slowness more often. Someone has suggested a bigger server, and you have maybe already paid for one, which helped for a while.
The worrying part is that it gets worse with every new customer, which is exactly what you are trying to have more of.
What actually makes it slow
A bigger server treats the symptom. The causes are usually more specific.
| Cause | Why it gets worse with growth |
|---|---|
| Missing database indexes | Queries scan whole tables, and tables grow with every customer |
| Queries in loops | A page makes one query per row, so bigger accounts mean hundreds |
| Reports run live | Heavy calculations run while the user waits |
| Everything in the request | Emails, exports and imports run before the page returns |
| One large customer | Their data volume affects everyone sharing the database |
| No caching | The same expensive result is calculated repeatedly |
The pattern tends to be uneven, which is a clue. If a few pages are slow and the rest are fine, or if slowness hits at the same time each day, the cause is specific and findable. Uniform slowness across everything points more towards capacity, and that is the less common case.
These are normal in an early product. They were reasonable shortcuts when the data was small. They just need dealing with now.
What the slowdown costs
- Customers churn quietly, often citing "performance" or not saying at all.
- Sales demos feel sluggish, which undermines trust.
- Hosting bills rise as you add capacity that does not fix the cause.
- Developers spend time firefighting instead of building features.
- Larger customers, the ones you most want, have the worst experience.
How we fix a SaaS app that does not scale
- Measure before changing anything. We add application performance monitoring and query logging, so we know which endpoints and queries take the time, for which customers.
- Fix the database first. Missing indexes, queries inside loops and unbounded result sets are usually the biggest and cheapest wins.
- Move heavy work to the background. Exports, imports, emails and report generation go onto a job queue, and the user is notified when the result is ready.
- Precompute what reports need. Summary tables or materialised views updated in the background, so dashboards read a prepared answer.
- Cache deliberately. Results that are expensive and change rarely are cached, with clear rules for when the cache is cleared.
- Isolate the heavy tenants. Where one customer's volume affects others, we look at limits, separate queues or, if justified, separate databases.
- Load test the next stage. We simulate the customer numbers you are aiming for, to find the next bottleneck before real users do.
- Alert on slowness. Response time and error alerts, so slowdowns are seen by you first, not reported by customers.
We work through these in order of impact, measuring after each change, so you can see what each fix did.
After the fixes
The conversation with your developers changes as well. Instead of "the app feels slow", there is a dashboard showing which requests are slow, for which customers, and since when. Performance work becomes a normal, planned part of each release rather than an emergency that stops everything else.
Pages respond quickly again, including for your largest accounts. Reports stop timing out. Hosting is sized for the real load rather than padded to hide a problem. And the team has monitoring that shows where the next limit is, so growth becomes something to plan for rather than something to fear.
Could this be your app?
- Performance has got worse as customer numbers grew.
- You have upgraded the server and the problem came back.
- Reports or exports time out, especially at busy times.
- Your largest customers complain the most.
- You do not have monitoring that shows which queries are slow.