SaaS Scalability Guide
Scale SaaS in order: optimise queries first, add caching second, move slow work to background jobs third, then scale infrastructure vertically before considering horizontal scaling or microservices. Most SaaS performance problems are missing database indexes, not hardware limits.
4Byte Agency builds every SaaS product with the correct scaling foundations from day one — so growth doesn't require architecture rewrites.
▸ Scaling Principles
Six principles that govern every SaaS scaling decision
These six principles prevent the two most common and expensive scaling mistakes — premature complexity and reactive fire-fighting.
Measure before you optimise
Never guess at performance bottlenecks. Use EXPLAIN ANALYZE, Sentry performance tracing, and Posthog usage data to identify the actual slow paths before spending engineering time optimising them.
Fix queries before adding hardware
A missing index on a 10-million-row table can be the difference between a 5ms query and a 12-second query. Most SaaS 'scaling problems' are actually query optimisation problems disguised as infrastructure problems.
Scale vertically before horizontally
Horizontal scaling (more instances) adds coordination complexity — distributed state, load balancing, cache invalidation, session sharing. Vertical scaling (bigger hardware) is simpler and far cheaper than the engineering cost of horizontal architecture.
Move slow work out of the request path
Any operation taking more than 500ms should not block the HTTP response. Background job queues decouple slow work from user-facing latency — the user gets an immediate response, work completes asynchronously.
Cache aggressively, invalidate carefully
Cache expensive, frequently-read, infrequently-changing data — subscription status, user permissions, dashboard aggregates. Cache invalidation on write, not on expiry, prevents stale data while maintaining performance gains.
Design for statelessness from day one
Stateless application servers (no local session state, no in-memory caches tied to a single instance) can be scaled horizontally trivially. Store all state in the database or Redis — never in application memory that's tied to a specific server.
▸ Scaling by Layer
Five scaling layers — what to do at each user milestone
Scaling is not a single action — it's a sequence of targeted improvements across five distinct layers. Here's exactly what to do at each user milestone per layer.
Database Layer
The database is the most common scaling bottleneck for SaaS products. PostgreSQL on Supabase scales further than most SaaS products will ever need — if queries are well-written and indexes are correct.
Application / API Layer
Next.js on Vercel scales horizontally by default — serverless functions spin up and down automatically. The application layer rarely becomes the bottleneck if database queries are fast.
Caching Layer
Redis (via Upstash for serverless compatibility) caches expensive query results, session data, and rate limit counters. A correctly implemented cache reduces database load by 60–90% for read-heavy SaaS products.
Background Jobs Layer
Any operation that takes more than 500ms or processes large data volumes should run in a background queue. Background jobs keep API responses fast regardless of what work needs to happen.
CDN & Static Assets
All static content (images, fonts, JS bundles, CSS) should be served from a CDN edge network, not from your application server. Vercel handles this automatically — but user-uploaded files need explicit CDN routing.
▸ User Milestones
What to focus on at each growth stage
Each user milestone requires a different scaling focus. Don't do 100K-scale work at 1K users — and don't ignore 10K-scale signals until you're at 100K.
0 → 1,000 Users
FoundationGet the foundations right. No premature optimisation — just correct defaults.
Priority Actions
- Indexes on all foreign keys and filter columns
- Connection pooling via PgBouncer (Supabase default)
- Edge deployment via Vercel for global asset CDN
- Error monitoring via Sentry from day one
- Stateless API handlers — no server-local state
1,000 → 10,000 Users
OptimisationMeasure and optimise based on real usage data. Add caching where it has meaningful impact.
Priority Actions
- EXPLAIN ANALYZE on all slow queries
- Add composite indexes for common filter combinations
- Cache subscription status and user permissions in Redis
- Move email sends to background job queue
- Add read replica for analytics queries
10,000 → 100,000 Users
InfrastructureScale infrastructure tier. Background jobs for all slow operations. Cache aggressive.
Priority Actions
- Upgrade Supabase compute tier
- Cache dashboard aggregates (1–5 min TTL)
- Background jobs for all operations >500ms
- CDN for all user-uploaded content
- Add queue depth and cache hit rate monitoring
100,000+ Users
ArchitectureConsider architectural changes — only at this scale do they become warranted.
Priority Actions
- Evaluate database sharding by organisation_id
- Tiered caching: Edge → Redis → Database
- Microservice extraction for independent high-load components
- Regional database replicas for global latency
- Dedicated infrastructure for largest enterprise tenants
▸ Caching Patterns
Four Redis caching patterns for production SaaS
These are the four caching patterns with the highest impact per implementation effort across the SaaS products 4Byte Agency has shipped.
Subscription Status Cache
Cache the subscription status (active, trialing, cancelled) and plan tier per organisation
Cache Key
sub:{organisation_id}TTL
5 minutesInvalidate On
Any Stripe webhook updating subscription status
Why Cache This
Checked on every authenticated request for feature gating. Without cache, this is a database query on every API call.
User Permission Cache
Cache the user's role within the current organisation
Cache Key
role:{user_id}:{organisation_id}TTL
15 minutesInvalidate On
Membership role change, membership deletion
Why Cache This
Role checks happen on every API middleware call. Caching eliminates a memberships table lookup per request.
Dashboard Aggregate Cache
Cache expensive COUNT and SUM queries for dashboard metrics
Cache Key
dashboard:{organisation_id}:statsTTL
2 minutesInvalidate On
Write operations that affect the metric (new user added, project created)
Why Cache This
Dashboard metrics queries can scan millions of rows. At scale these queries take seconds — caching serves them in microseconds.
Feature Flag Cache
Cache feature flag values per organisation to avoid repeated evaluations
Cache Key
flags:{organisation_id}TTL
10 minutesInvalidate On
Feature flag update in admin panel
Why Cache This
Feature flags are checked on many routes. Caching prevents repeated Posthog API calls or database flag lookups.
▸ Background Jobs
Six operations that belong in background job queues
These are the six most common operations that block SaaS API performance — and how to move each one out of the request path.
Email Sends
Sending email via Resend/SendGrid API takes 200–800ms and can fail transiently. Blocking the HTTP response on email delivery creates latency and fragile UX.
Implementation Pattern
Queue email job immediately, return 200 to client. Job sends email with retry on failure.
AI / LLM Processing
OpenAI API calls take 2–30 seconds depending on model and prompt. Serverless functions time out at 10–60s. Streaming helps UX but background jobs handle true async AI workloads.
Implementation Pattern
Queue AI job with task parameters. Return job_id. Client polls /jobs/{id}/status until complete.
PDF / Report Generation
Generating a complex PDF report with charts and data tables can take 5–60 seconds. No HTTP client should wait that long for a response.
Implementation Pattern
Queue report job. Return download link or webhook when complete. Store generated file in Supabase Storage.
Bulk Data Operations
CSV imports, bulk updates, and mass notification sends processing thousands of records cannot run in a single synchronous API call.
Implementation Pattern
Stream uploaded file to storage. Queue batch job with file reference. Process in chunks with progress tracking.
Webhook Delivery
Delivering webhooks to customer endpoints involves HTTP calls to external services that may be slow, unreliable, or offline. Blocking on delivery would make the triggering operation unreliable.
Implementation Pattern
Queue webhook delivery job. Retry with exponential backoff on failure. Log delivery attempts and outcomes.
Scheduled Recurring Tasks
Recurring operations (daily usage reports, subscription renewal checks, stale data cleanup) need to run on a schedule independent of user-initiated requests.
Implementation Pattern
Cron-scheduled jobs via Inngest or Trigger.dev. Each job is idempotent and safe to re-run if failed.
Recommended Tools
Inngest — the best background job solution for Next.js/Vercel deployments. Serverless-native, event-driven, with built-in retries and a local development server. Recommended for most 4Byte SaaS builds. Trigger.dev — excellent for complex multi-step workflows with long execution times and rich observability. Both are far superior to raw cron jobs or DIY queue implementations.
▸ Scaling Metrics
Six metrics that tell you if your SaaS is scaling correctly
You cannot manage what you don't measure. These six metrics give you full visibility into every scaling layer — database, API, cache, jobs, and errors.
API p95 Response Time
The response time that 95% of API requests complete within. The most meaningful latency signal.
Target
< 300ms for standard requests. < 100ms for cached responses.
Tool
Vercel Analytics / Sentry Performance
Database Query p95
The execution time that 95% of database queries complete within. Identifies slow queries before they affect users.
Target
< 50ms for OLTP queries. Flag anything over 200ms for index review.
Tool
Supabase Query Performance Dashboard / pg_stat_statements
Cache Hit Rate
Percentage of cache reads that return a cached value rather than triggering a database query.
Target
> 80% for subscription status cache. > 60% for dashboard aggregates.
Tool
Upstash Redis dashboard / custom metrics
Background Job Queue Depth
Number of jobs waiting to be processed. A growing queue means workers can't keep up with job production.
Target
< 100 queued jobs under normal load. Alert at 500+.
Tool
Inngest dashboard / Trigger.dev queue metrics
Database Connection Pool Usage
Percentage of PgBouncer connection pool in use. High utilisation causes connection timeouts.
Target
< 70% average utilisation. Alert at 90%.
Tool
Supabase database metrics / pgBouncer stats
Error Rate
Percentage of requests resulting in 5xx errors. Spikes indicate scaling failures, database exhaustion, or application bugs.
Target
< 0.1% of all requests. Any spike warrants immediate investigation.
Tool
Sentry / Vercel Error monitoring
▸ Scaling Mistakes
Four scaling mistakes that waste months of engineering time
These are the four most common and most expensive scaling mistakes across SaaS products — each one optimising for a problem that didn't exist yet.
Premature microservice extraction
Consequence
Teams split a perfectly functional monolith into microservices before hitting real scaling limits. The coordination overhead, network latency between services, and distributed tracing complexity adds months of engineering work with no user-facing benefit.
4Byte Standard
Stay on a monolith until a specific service has clear, measurable isolation requirements. Most SaaS products that hit $10M ARR never need to leave a well-optimised monolith.
Horizontal scaling before query optimisation
Consequence
Adding more application servers doesn't fix slow database queries — it adds more concurrent sources of slow queries, increasing database load and compounding the problem.
4Byte Standard
Profile every slow query with EXPLAIN ANALYZE before adding compute. A properly indexed database query is 100-1000× faster than the same query without an index.
No background jobs for slow operations
Consequence
Sending email, calling AI APIs, generating reports, and processing uploads synchronously creates API routes that take 5–30 seconds. These routes time out under load and block the thread for other requests.
4Byte Standard
Any operation exceeding 500ms is a background job candidate. Implement Inngest or Trigger.dev early and move slow operations out of the HTTP request path from the moment they're built.
Cache invalidation that's too aggressive (or not aggressive enough)
Consequence
Too-aggressive invalidation defeats the purpose of caching — every write clears the cache, meaning cache hit rates stay low. Not aggressive enough creates stale data — users see outdated subscription status or old permission data.
4Byte Standard
Cache at the right granularity (per-org, per-user) and invalidate on the specific write events that affect that cache key — not on all writes globally.
▸ FAQ
Frequently asked questions about SaaS scalability
How do you scale a SaaS product?+
Scaling a SaaS product follows a sequential approach: first optimise slow database queries and add missing indexes, then add caching for expensive repeated computations, then offload slow operations to background job queues, then scale infrastructure vertically before horizontally. Most SaaS products never need horizontal scaling if query optimisation and caching are applied correctly.
What causes SaaS performance problems at scale?+
The most common SaaS performance problems at scale are: missing database indexes causing full table scans, N+1 query patterns fetching data in loops, no connection pooling exhausting database connections, synchronous execution of slow operations blocking API responses, and no caching of expensive computed results that don't change frequently.
When should a SaaS product start thinking about scalability?+
A SaaS product should address scalability in layers as it grows. From day one: proper indexes, connection pooling, and Edge deployment. At 1,000 users: monitor slow queries and add caching. At 10,000 users: background job queues and read replicas for analytics. At 100,000 users: consider database sharding and microservice extraction for high-load components.
What is the difference between vertical and horizontal scaling for SaaS?+
Vertical scaling means upgrading to more powerful hardware on the same instance. Horizontal scaling means adding more instances and distributing load. For most SaaS products, vertical scaling is simpler and sufficient to very large scale. Horizontal scaling adds significant architectural complexity and should only be adopted when vertical scaling is genuinely exhausted.
How does caching improve SaaS scalability?+
Caching reduces database load by storing the results of expensive or frequently-repeated queries in fast in-memory storage (Redis). Common SaaS caching patterns: subscription status per organisation, user permission role per session, and expensive dashboard aggregate queries.
Does 4Byte Agency build SaaS products that can scale?+
Yes. 4Byte Agency builds every SaaS product with scalability foundations from day one: proper database indexing, connection pooling, Edge deployment, and background job infrastructure. The architecture scales to 100,000+ users without structural changes — only hardware upgrades and targeted optimisations are needed as the product grows.
▸ Related Resources
Go deeper into SaaS infrastructure
▸ Build for scale from day one
Want a SaaS product built with scalability from the start?
We build every SaaS product with correct indexing, connection pooling, Edge deployment, and background job infrastructure from day one — so scaling is a hardware upgrade, not an architecture rewrite.