Skip to content

Scaling a SaaS Application: From 10 to 10,000 Users

Scaling a SaaS application from 10 to 10,000 users: measure, fix indexes, add queues and caching, then add servers. The right order and what to skip early.

By

Freelance full-stack developer

Published
Reading time
13 min
In this post8

Scaling a SaaS application from 10 to 10,000 users is mostly about removing one bottleneck at a time, in a fixed order: measure, fix the database, move slow work into a queue, cache what's expensive, and only then add servers. In my view, most B2B products can get there on one codebase, one database and a queue, with no microservices or Kubernetes involved.

The most expensive scaling mistake isn't running out of capacity. It's building for 10,000 users before you have 10.

The short answer

Typical bottlenecks and next moves as a SaaS grows
Usual bottleneckWhat to do nowWhat can wait
10-100 usersNothing technical. Finding customers is the problemOne server, a managed database, backups and error trackingQueue servers, caching, extra servers
100-1,000 usersSlow queries and missing indexesMeasure response times, add indexes, fix N+1 queries, queue emails and exportsLoad balancer and read replicas
1,000-10,000 usersHeavy background jobs and the databaseCache expensive results, upsize the database, give the queue its own server, make the app statelessSharding and microservices
10,000+ usersDepends on the product and your largest customersSeveral app servers behind a load balancer, read replicas, dedicated databases for big customersMicroservices, unless your team size rather than your traffic calls for them

The user counts are rough guides. A SaaS where every customer imports large files overnight hits its limits far sooner than a simple booking tool with the same number of accounts, so read the table as an order of operations, not a timeline.

If you're earlier in the process, my complete guide to building a SaaS covers the full path from idea to paying customers.

What 10,000 users means in actual load

Ten thousand registered users is not ten thousand people clicking at the same moment. In a typical B2B product, some users log in daily, some weekly and many rarely. What decides if your system holds up is load per second during the busiest hours, not the row count in your users table.

A back-of-the-envelope calculation shows why. Assume 20% of 10,000 users are active on a given day, and each sends 100 requests to your server across an 8-hour working day. That's 200,000 requests spread over 28,800 seconds, or roughly 7 per second on average. If your peak is five times the average, you're at around 35 requests per second.

Those inputs are assumptions, not measurements, but the order of magnitude is the point: for many B2B products, one well-configured server can carry that if the queries behind each page are efficient. For a European B2B tool, also expect traffic to bunch up in office hours across a few neighboring time zones, so plan for Monday morning CET rather than the daily average.

What usually breaks a system is the heavy stuff. One customer exporting two years of data. A 50,000-row spreadsheet import. A report that crunches everything, or a nightly job that emails every user at once. One large customer can generate more load than a hundred small ones, which is why your multi-tenant SaaS architecture matters for performance as well as data isolation.

Why you shouldn't build for 10,000 users on day one

Microservices (an app split into many small services), Kubernetes (a system for running lots of containers across servers) and multiple databases feel responsible when you're hoping for success. In practice they cost more to build and run, and, worst of all, they make every change slower.

In its first year, a SaaS needs to change quickly while you learn what customers will actually pay for. My view is that a new product is far more likely to have too few users than too many. A scaling problem is one you can solve with time and money once revenue exists.

None of this means ignoring scale. It means picking a well-understood foundation and not solving problems you don't have yet. What belongs in a first release is covered in my guide to scoping a SaaS MVP, and the foundation I usually recommend is in my post on choosing a SaaS tech stack.

Three decisions that are cheap now and expensive later

  • A tenant ID and indexes from the start: every table holding customer data gets a tenant ID (the customer account each row belongs to), and the indexes you query on should lead with it. That keeps both isolation and speed manageable as data grows.
  • Heavy work written as background jobs: emails, PDFs and imports live in their own job classes. In Laravel the queue can start on the "database" driver, which uses the database you already have, so you don't need Redis or a separate queue server yet. Moving to Redis later is a configuration change, not a rewrite.
  • An app that keeps nothing on its own disk: sessions, cache and uploaded files belong in the database, Redis or object storage such as Amazon S3, never in a folder on the server. That way you can add a second server later without logging everyone out or losing files.

Signs you've outgrown your current setup

Scale when your measurements show strain, not when your user count hits a round number. These are the signals I watch for:

  • Response times for the slowest 5% of requests creep up week after week, even though the code hasn't changed.
  • The queue backs up, so emails and exports arrive minutes or hours late at busy times.
  • The database server runs hot on CPU or runs out of connections at peak.
  • Timeouts and errors spike at predictable moments, like Monday morning or month end.
  • Customers start mentioning that the app "has gotten slow".

That last one is the expensive one. Slow pages and errors are among the reasons customers quietly start looking elsewhere, as I cover in technical causes of SaaS churn.

The scaling playbook, step by step

Each step below is cheaper than the one after it, and in my view the first three resolve most scaling problems well before 10,000 users.

1. Measure before you change anything

Collect response times per page, the slowest database queries, slow background jobs and errors in one place. In a Laravel app, Laravel Pulse is a good first step: it surfaces slow queries, slow jobs and queue throughput among other things, without extra infrastructure. You'll also want external uptime monitoring, so you hear about outages before your customers do.

Don't stop at the average. A 200 ms average can hide one page in twenty taking two seconds.

2. Fix the database: indexes and N+1 queries

The database is usually where the first real bottleneck shows up, and two mistakes cause most of it. The first is missing indexes. Without one, the database has to read the whole table to find the rows it needs, which is fine at 1,000 rows and painful at 10 million. EXPLAIN shows you how the database actually runs a query, and the PostgreSQL guide to using EXPLAIN explains how to read the output.

The second is N+1 queries: a list of 50 rows that runs one query for the list and then one more for every row. Laravel can prevent lazy loading during development (lazy loading is when related data gets fetched one row at a time), so the problem gets caught before it reaches production.

Fix both before you buy a bigger server. More hardware makes a bad query a bit faster, but it's still a bad query. For more of the usual suspects, see my breakdown of why a web app gets slow.

3. Move slow work into a queue

Anything that doesn't need to finish before the user sees the next page belongs in a queue: emails, PDFs, imports, exports, webhooks to other systems and calls to AI APIs. The user gets an instant response while separate worker processes do the work. Laravel's own queue documentation uses parsing an uploaded CSV file as its example of a task too slow for a normal web request.

Three things need to be in place. Jobs must be safe to rerun if they fail halfway: a duplicate invoice email is embarrassing, a duplicate card charge is worse. Failed jobs must be visible, not silently lost. And one heavy customer shouldn't block everyone else, so split work across queues by priority. On Redis, Laravel Horizon gives you a dashboard for throughput and failures.

4. Cache what's expensive and rarely changes

Caching means storing the result of expensive work so the next user gets it instantly. Good candidates are dashboard figures, lookups used on every page and third-party API responses that don't change by the minute. Use a shared cache such as Redis so every server sees the same data.

There are two traps. One is using a cache to hide a missing index, which leaves you with two problems instead of one. The other is stale data: the hard part is knowing when to throw cached values away. In a multi-tenant SaaS, every cache key also needs the tenant ID, so customer A never sees customer B's numbers.

5. Scale up before you scale out

Scaling up means a bigger server or a bigger database. Scaling out means more servers side by side. Up is almost always the simpler next move: no code changes, no new failure modes, just a larger machine. A managed database also gives you backups, updates and room to grow without running the database server yourself. Pick an EU region if your customers expect their data to stay in Europe.

Give queue workers their own server once they compete with web requests for CPU, so a heavy import can't slow the app down. That requires files to live in shared storage.

6. Add servers behind a load balancer

When one server is no longer enough, or a single machine failure shouldn't take everything down, put two or more app servers behind a load balancer that spreads traffic between them. This is where the day-one decisions pay off: sessions, cache and files already live somewhere shared, so it doesn't matter which server a user hits.

Watch out for scheduled tasks. Run the scheduler on three servers and the weekly report gets generated three times. Laravel handles this with onOneServer, which requires every server to talk to the same central cache.

7. Split the database last

The database is the hardest part to scale out, because the data has to stay correct. The first move is usually read replicas: copies of the database used only for reads, such as reports and search. The next is moving a handful of very large customers into their own databases, which is far easier if the tenant ID has been on every table from the start. If you've promised customers that their data stays in the EU, that promise covers replicas and backups too.

True sharding, where data is split across many databases by a key, is something I'd expect very few SaaS products to need at 10,000 users. By then, you can usually afford full-time infrastructure people.

When one developer isn't enough

Everything above can be done by one experienced developer with a solid hosting provider behind them. There are situations where that isn't enough:

  • You need round-the-clock uptime with an on-call rota, because your customers are hospitals or critical infrastructure. Someone has to be reachable at 3 a.m., and one freelancer can't promise that.
  • You expect thousands of concurrent users from day one, for example because a large partner is rolling your product out to its entire customer base at once.
  • Customers require certifications and audited operations, which assume a team with documented processes.

In those cases you need a team with dedicated operations, or a DevOps specialist alongside the developer. I'd rather say that up front than six months into a project.

With a few hundred or a few thousand users and an app that has started to slow down, it's a different story: one developer who knows the whole codebase can often move faster than a team that first has to learn it.

Next steps

Start by measuring. If you don't have numbers for response times, slow queries and queue health, getting them is step one, whatever your user count. Use this checklist to see where you stand.

Is your SaaS ready to grow?

  • You track response times, slow queries and errors, including the slowest 5% of requests.
  • Every table with customer data has a tenant ID, and your most important queries use an index.
  • Lazy loading is blocked in development, so N+1 queries get caught early.
  • Emails, exports, imports and third-party calls run on a queue, and failed jobs are visible.
  • Sessions, cache and uploaded files live outside the app server's own disk.
  • Scheduled tasks run on only one server at a time.
  • The database has automated backups, and you've tested a restore.
  • You know which customers and actions put the most load on the system.

If several of these are missing, I'd start with a review of the codebase and the metrics, followed by a prioritized plan that tackles the cheapest wins first. To see how I run SaaS projects, from a fixed-price discovery phase through ongoing development, take a look at my SaaS development service.

Frequently asked questions

Can Laravel handle 10,000 users?

Yes. The framework is rarely what limits a SaaS at 10,000 users. The bottleneck is almost always the database, heavy background work or the way the code loads data. Laravel ships with queues, caching, single-server scheduling and monitoring tools, either built in or as official packages, so the steps in this guide don't require switching technology.

Do I need Kubernetes or serverless to scale?

Rarely at 10,000 users. Kubernetes shines for many services and large teams, but it takes specialist knowledge to operate, and that time comes out of product work. Serverless can suit very spiky traffic, but it makes debugging harder and can get expensive under steady load. I'd recommend a managed hosting platform or plain servers until you have a concrete reason to change.

How do I load test a SaaS before launch?

Set up a copy of your production environment with realistic data volumes, then send traffic at the heavy pages using a tool like k6. Test the actions that actually create load, such as login, search, reports and imports, not just the landing page. Ramp up gradually. Don't point load tests at production unless you're certain they won't affect real customers.

How much does it cost to scale a SaaS to 10,000 users?

It depends far more on how much code needs fixing than on servers. For many B2B products, hosting at 10,000 users is a modest line item compared with developer time. The big costs appear when scalability has to be retrofitted: missing tenant IDs, files stored on the server's disk and heavy work running inside user requests. A short review with real metrics gives the most accurate estimate.