Scaling from ten users to ten thousand

What actually changes as software grows a thousandfold, what to build in from the start, and what to leave until the numbers demand it.

3 minread 680words last updated

The short answer

Most business software never needs to serve ten thousand users, and building for that on day one is waste dressed as prudence. A few cheap decisions keep the door open: a stateless application that a managed platform can run in many copies, a managed database with proper indexes, background jobs for anything slow, object storage for files, and caching at the edge. Those cost nothing extra and let the platform add instances when traffic arrives. What is premature early is expensive: microservices, multiple databases, custom infrastructure, sharding, building for a load you do not have. Growth, when it comes, is met by measuring. The first bottleneck is nearly always the database, and a trace finds it.

Cheap early, expensive early

Do from the startLeave until measured
Stateless application: sessions and state in the database or cache, not on the instanceSplitting the application into services
Managed database, indexed for the queries the screens actually runRead replicas, sharding, multiple databases
Background jobs for email, imports, reports and integrationsA custom job platform
Object storage for files, never the instance diskA content delivery strategy beyond the platform’s default
Edge caching for public pages and assetsApplication-level distributed caches
Monitoring and tracing in placeCapacity planning spreadsheets
Budgets and limits per user and endpointAuto-scaling policies tuned by hand

What growth looks like in practice

  1. Ten users: everything is fast; the database is tiny; the only concern is building the right thing.
  2. A hundred: still fast; the first slow screen appears as data grows; an index fixes it.
  3. A thousand: reports and exports strain; they move to background jobs; a query per row surfaces and is batched; the database tier goes up one size.
  4. Ten thousand: the platform runs more instances automatically; caching matters; the database is the focus: indexes, query shapes, perhaps a read replica for reporting; external calls are queued and rate-limited.
  5. Beyond: architecture decisions are made from a year of measurements, by people who know exactly where the load is.

Meeting growth by measuring

Real-user timings show which screens slow first. Traces show where the time goes, and under growth it is a query, a synchronous job or an external call. The fix is specific: an index, a batch, a job, a cache, a bigger database tier. Each is done when the measurement demands it and no earlier. Teams that scale this way rarely face a crisis, because each bottleneck arrives one at a time and is small when found.

What this means for you

Build for scaling to be possible, not for scale you do not have: stateless, managed database with indexes, background jobs, object storage, edge caching, monitoring. Then grow by measuring, fixing the database first because it is nearly always first. The system that serves ten thousand users is usually the same simple system that served ten, with a year of small, measured fixes.

Written by the CivSec S.M.A.R.T team

We build and run websites, software and AI systems for businesses. We write about what we see in that work, in plain language, and we update articles when things change.

Last checked . Spotted something outdated? Tell us.

Frequently asked questions

Should we build for scale from the start?

Build so that scaling is possible, not so that it is already done. A stateless application on a managed platform, a properly indexed managed database, background jobs and object storage cost nothing extra and let the platform add instances when traffic arrives. Everything beyond that is decided later, from measurements, when there is load to measure.

What breaks first when users grow?

The database, nearly always: a query that was fine with a thousand rows scans a million, a missing index, a report that locks a table. Then background work that was synchronous, then external calls made per request. Each is found by tracing the slow requests under real load and fixed with an index, a batch, a job or a cache. Very few systems reach the point where the architecture itself is the limit.

When do we need microservices or multiple databases?

Later than almost anyone expects, and usually for organisational reasons, several teams working independently, rather than for load. A well-built single application on managed services handles far more traffic than a business of this size will see. Splitting it early adds operational complexity and network failure modes without adding capacity you can use.