Scaling from 100 to 10,000 users: what breaks first
What fails first in a small web app as users grow, from database queries and connections to email limits and background work, and how to fix each in order.
Leer en español →
Going from 100 to 10,000 users rarely breaks the hosting itself; static front ends on modern hosts scale almost without effort. What breaks first is usually the database (queries without indexes, then too many connections), followed by limits on third-party services such as email and AI APIs, slow work done inside web requests, and the lack of monitoring to see any of it happening. Fixing those in that order gets most small apps to five figures of users without a rewrite or a new architecture.
This guide walks through what tends to fail at each stage, how each failure shows up, and the specific fix, plus what you shouldn't spend time on yet.
What usually breaks, and in what order?
| Symptom | Likely cause | First fix |
|---|---|---|
| Lists and dashboards get slower every week | Queries scanning whole tables | Add indexes on filtered, joined and sorted columns |
| Random "too many connections" or timeouts at peak | Each serverless function opens its own database connection | Use a connection pooler in transaction mode |
| Sign-up or password emails stop arriving | Hitting your email sender's rate limit | Move to a dedicated email provider with a verified domain |
| Requests time out when users export, import or generate something | Heavy work done inside the request | Move it to a background job |
| AI features fail with 429 errors, or the bill jumps | Provider rate limits and no per-user limits | Queue, cache and cap usage |
| Users report bugs you can't reproduce | No error tracking or logs | Add monitoring before anything else |
Why is the database first?
At 100 users, a query that reads every row of a table is invisible. At 10,000 users, the same tables are 100 times bigger and the query runs 100 times more often, so the cost grows on both sides at once. Our guide to slow database queries and indexes explains how to find these queries and which indexes to add. On Supabase, also check the Performance Advisor; it flags unindexed foreign keys and Row Level Security policies that run once per row.
The second database problem is connections. Postgres handles a limited number of simultaneous connections. A long-running server reuses a few, but serverless and edge functions can each open a new one, and a traffic spike can exhaust the limit.
The fix is a connection pooler. On Supabase, serverless code should use the pooler's transaction mode, on port 6543, rather than the direct connection on 5432. Transaction mode doesn't support prepared statements, so most drivers need a setting: prepare: false for Postgres.js and Drizzle, or pgbouncer=true in the connection string for Prisma. Requests made through the Supabase client libraries go through Supabase's API instead and don't need this.
Why do emails stop arriving?
Many apps start with whatever email sender came with their backend. Supabase's built-in email service, for example, is meant for testing and is heavily rate-limited; production apps are expected to configure their own SMTP provider. Signs you've hit a limit: confirmation emails arrive for some users and not others, or stop entirely during a launch.
Move to a transactional email provider, verify your domain with SPF, DKIM and DMARC records, and keep marketing newsletters on a separate sending stream so a campaign can't block password resets. If emails arrive but go to spam, our guide on app emails going to spam covers the DNS side.
What counts as "slow work inside a request"?
Anything that takes more than a second or two and doesn't need to finish before the user sees a response:
- Sending emails or notifications to many users.
- Generating PDFs, reports or exports.
- Importing a CSV with thousands of rows.
- Calling an AI model for a long document.
- Processing uploaded images or video.
Inside a web request these hit timeouts (serverless platforms cap how long a function may run) and tie up resources while users wait. The pattern that scales is: accept the request, save a job record, return immediately, process the job in the background, and notify the user or update the screen when it's done. Most backends offer some form of queue, scheduled function or worker for this.
What about AI features?
AI APIs have per-minute rate limits on requests and tokens, and they cost money per call. With more users, a feature that worked fine in testing starts returning 429 errors at peak and the monthly bill grows faster than revenue. Limit usage per user, cache repeated answers, and use cheaper models for simple steps. Both topics have their own guides: controlling AI API costs and rate limiting AI features.
Why does monitoring matter more than any of the above?
Every fix in this guide starts with knowing something is wrong. At 100 users, customers email you. At 10,000, most of them leave quietly. Before you scale, have:
- Error tracking on the front end and back end, so exceptions arrive with a stack trace and the page they happened on.
- Uptime checks that hit a real page and look for expected content, not just a 200 status.
- Database metrics: CPU, memory, connections and slow queries.
- Alerts that reach a person, with thresholds you've actually tested.
Our guide to monitoring and error tracking goes through a minimal setup.
What shouldn't I worry about yet?
At this size, the following usually cost more than they return:
- Splitting the app into microservices.
- Running your own Kubernetes cluster.
- Rewriting in a "faster" language or framework.
- Multi-region databases.
A single well-indexed Postgres database on a reasonable compute size, a CDN for the front end, a pooler, a background job runner and good monitoring cover a very large range of apps. Upgrade the database compute when its metrics show it's consistently busy after the indexes are in place, not before.
How can I test before the users arrive?
- Seed a copy of the database with realistic volumes: if you expect 10,000 users, create 10,000 users with typical amounts of data each. Run this in a staging environment, never on production.
- Click through the main screens and look at query times in the database's slow query list.
- Run a simple load test with a tool like k6 against the staging API, starting low and stepping up, while watching errors and database connections.
- Write down the first thing that broke. That's your next fix.
Quick answers
Will my hosting provider scale automatically? The front end and serverless functions usually do. Your database, email sender and third-party APIs don't scale with them, which is why they fail first.
Do I need a bigger database plan at 10,000 users? Possibly, but add indexes and a pooler first. They often make an upgrade unnecessary.
Is Supabase or Firebase able to handle 10,000 users? Yes, both can, when the data model, indexes and security rules are set up properly.
What should I fix first if I'm about to launch? Monitoring, then indexes on your busiest tables, then a real email provider.
Getting ready for growth?
If you're expecting a launch or a jump in users, our maintenance and support plans cover this kind of preparation and the monitoring around it, and custom software development handles bigger changes like background jobs. Start with the free health check, or tell us what you're planning. Supabase documents its pooler options in connecting to Postgres.


