▸ Scalability Guide · 2025

SaaS Scalability Guide

TL;DR

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.

Read time:17 min
Level:Technical
Focus:Scalability & Performance
By:4Byte Agency

▸ 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.

📊01

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.

🔍02

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.

⬆️03

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.

04

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.

🗄️05

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.

🌐06

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.

From day one
Indexes on all foreign keys and WHERE-clause columns. Connection pooling via PgBouncer. Query scoping by organisation_id.
At 10K users
Add EXPLAIN ANALYZE monitoring. Add composite indexes on frequently combined filter columns. Review and eliminate N+1 queries.
At 50K users
Add a read replica for analytics queries. Separate heavy report queries from OLTP traffic. Increase Supabase compute tier.
At 250K+ users
Evaluate database sharding by organisation_id for extreme tenant isolation and query parallelisation.
⚙️

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.

From day one
Stateless API handlers. No server-local session state. All state in DB or Redis. Vercel serverless auto-scales.
At 10K requests/min
Add Redis caching for expensive repeated reads (permissions, subscription status, dashboard aggregates).
At 100K requests/min
Add rate limiting per token and per IP. Review API response payload sizes. Add response compression.
At 1M+ requests/min
Evaluate Edge middleware for auth validation. Move high-frequency reads to Edge-cached responses.

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.

At ~1K users
Cache subscription status per organisation (5-minute TTL, invalidated on webhook). Cache user permission role per session.
At ~5K users
Cache dashboard aggregate queries (MRR, user counts, activity metrics) with short TTL (1–5 min).
At ~25K users
Cache full-text search results. Cache API responses for public/shared data endpoints. Add cache warming on deploy.
At 100K+ users
Implement tiered caching: Edge cache (CDN) → Application cache (Redis) → Database. Add cache hit rate monitoring.
🔄

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.

From first feature needing async
Implement background job queue (Inngest or Trigger.dev). Move email sends, report generation, AI calls to jobs.
At steady job volume
Add job retry logic with exponential backoff. Add dead letter queue for failed jobs. Monitor queue depth and latency.
At high job volume
Separate job queues by priority (critical vs batch). Add concurrency limits per queue. Add job execution time monitoring.
At scale
Add worker autoscaling based on queue depth. Implement job deduplication to prevent duplicate processing.
🌍

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.

From day one
Vercel CDN handles all Next.js static assets automatically. Supabase Storage serves user uploads via CDN. Never serve binaries from API routes.
Growing user base
Add image optimisation via Next.js Image component. Enable Vercel's ISR (Incremental Static Regeneration) for data-driven public pages.
Global users
Verify CDN edge node coverage for your primary geographic markets. Consider regional database replicas if read latency across continents is measurable.
High traffic assets
Add aggressive cache-control headers for immutable assets. Use content hashing in filenames for safe long-term caching.

▸ 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

Foundation

Get 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

Optimisation

Measure 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

Infrastructure

Scale 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

Architecture

Consider 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 minutes

Invalidate 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 minutes

Invalidate 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}:stats

TTL

2 minutes

Invalidate 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 minutes

Invalidate 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.

▸ 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.

Available now
Built to scale from day one
Response in ≤ 4 hours
45+ products shipped