Outages have stopped being a technical embarrassment and started being a line item. In its 2026 Annual Outage Analysis, the Uptime Institute found that 57% of organizations put the cost of their most recent major outage above $100,000, and for the second year running, 1 in 5 put it above $1 million. Outage rates per site have declined for 5 consecutive years, though the report is direct about what further improvement will take: "Further resiliency gains are becoming harder to achieve," says Andy Lawrence, founding member and executive director of Uptime Intelligence, the research arm of the Uptime Institute. Among human causes, failures to follow established procedures remain the leading driver.
For a B2B SaaS company, that risk turns concrete in one of two forms. Sales closes an account 10 times larger than the current biggest customer, with a go-live date written into the contract. Or a campaign, a launch, or a season drops a wave of traffic on a platform that has only ever run at 1x. The first is bounded and dated, the second is neither, and engineering teams tend to answer both the same way, by buying capacity.
That answer addresses the layer of the stack that was already elastic. The four layers that actually give out under a step change in load are shared, stateful, or single-purpose, and none of them respond to a larger instance type. What follows sets out each one, what the engineering literature says about it, and how the first two were solved on Adact, an Estonian marketing platform Brocoders has built since 2021 that now sustains more than 2 million requests at peak.
TL;DR: When load jumps 10x, the layer that fails is usually one that was never scaled, because stateless compute was already the most elastic part of the system. Four shapes decide whether a platform holds: how many backend calls one user action costs, whether one database serves two opposing access patterns, whose work lands on shared resources when a single tenant grows large, and what the system has been told in advance to refuse. All four are answerable before the load arrives.
One problem, two entry points
The enterprise onboarding scenario is the more comfortable of the two, because it arrives with numbers attached. Procurement has finished, the customer goes live on a set date, and the engineering team has a rough count of users and records. The discomfort sits in the comparison: the incoming account is frequently an order of magnitude larger than anything the platform has served before, and nothing in production has been exercised at that size.
The traffic scenario removes the date and keeps the multiple. A campaign lands, a post travels, a season opens. Both are the same event from the platform's point of view, which is a sudden multiple applied to a system whose behavior has only ever been observed at one scale. What separates the platforms that hold from the platforms that fall over is rarely the size of the multiple. It is whether anyone looked at the shape of the work before the multiple arrived.
Why autoscaling arrives too late
The default answer to anticipated load is elastic compute, and practitioners who operate at genuine spike scale are increasingly blunt about its limits. Manoj Yerrasani, vice president of global platform engineering for data and personalization at NBCUniversal, where the streaming platform absorbs Super Bowl traffic, put it plainly in InfoWorld: "At the 'Super Bowl standard' of scale, auto-scaling is a lie. It is too reactive."
The clearest way to see why is to picture a restaurant. Traffic is diners walking through the door, and autoscaling is the decision to hire more waiters. Waiters were never the constraint. The kitchen was, and it is still one kitchen. Twelve people now take orders that the same set of ovens cannot cook, and the queue moves from the door to the pass. That is the shape of most outages that happen with autoscaling switched on and configured correctly.
Underneath the analogy, the mechanism is a question of sequence rather than capacity. When demand rises by an order of magnitude, several failures land faster than an autoscaling group can provision replacements. Database connection pools exhaust, and because every new application instance opens its own connections against the same finite pool, adding application servers drains the database faster. Latency climbs while instances are still booting, callers retry, and those retries multiply load the system was already failing to serve. Caches stampede when popular keys expire simultaneously and every request reaches origin at once.
None of those are compute constraints. Stateless application servers were the straightforward part of the problem, which is why cloud providers made them elastic first, and why scaling them feels like progress.
A second category of failure gets far less coverage. Ben Maurer's "Fail at Scale", published in ACM Queue in 2015 and still the clearest treatment of the subject, divides outages at Facebook into three causes: individual machine failures, legitimate workload changes, and human error. Machine failure has largely been automated away in the decade since. The other two have not, and Maurer's observation about the third is worth sitting with, because Facebook's site ran more reliably on weekends, holidays, and during performance reviews, for the plain reason that engineers were not changing anything. The Uptime Institute's 2026 finding that procedural failures lead the human-error category points at the same behavior from a different dataset.
The operational implication is unglamorous and free. No kitchen gets rearranged on the night of the biggest booking of the year, and the week a large customer goes live is the wrong week to ship configuration changes.
The Load Shape Audit
Load is a shape problem. Volume matters less than the path work takes through a system, because a platform survives a 10x event by doing less work per request, by separating work that competes for the same resource, and by refusing work it cannot serve. In restaurant terms, a kitchen survives a full house by cutting trips to the pass, by not prepping tomorrow's catering during dinner service, and by deciding in advance which menu it stops offering.
Four questions cover the surface area, and all four are answerable before the rush.
The Load Shape Audit
- Request shape. How many backend calls does one user action cost?
- Data shape. Is one database serving two opposing access patterns?
- Tenant shape. Whose work lands on shared resources when one customer grows large?
- Failure shape. What has the system been told in advance to refuse?

The first two are best explained through a platform where both had to be solved at once.
Request shape: the cost of one user action
Start with the waiter. If taking one table's order means six separate walks to the kitchen, then ten times more tables means sixty times more traffic through the kitchen door, and the door becomes the problem long before the ovens do. Cutting six walks to one leaves the same kitchen serving ten times the diners comfortably.
That is the arithmetic behind request shape, and it is the cheapest diagnostic available. Open the busiest page in the product and count the backend calls one page view generates. If the answer comes back as 6, a 10x traffic event is a 60x backend event, and the multiplier has been running quietly the whole time.
Adact is an Estonian martech platform that lets marketers build gamified campaigns without writing code, and the economics of the product are what create its load profile. Before the platform existed, a custom marketing game was programmed by hand, which cost upward of $15,000 and took 2 to 5 months. Automating that build is the product, and it means the platform absorbs every client's campaign traffic centrally instead of each game carrying its own infrastructure.
That traffic arrives in waves and finishes quickly. One client campaign generated more than 18,000 leads in 10 days, around 1,800 a day, and the platform handled over 3 million visitors across half a year. Campaigns also hold attention rather than shedding it, with 96% of players finishing a game once they start, so a visitor who arrives during a spike stays in session generating work rather than leaving after one request. These are diners who order three courses, not people who read the menu and walk out.
Brocoders took the project on in 2021 and found an architecture written in PHP and jQuery, which limited both extensibility and the ceiling. Moving the platform to React and Next.js on the front end and Node.js with Nest.js on the back raised that ceiling. It did not by itself change how much work a single page view cost, which was the next problem.
On Adact, campaign pages were the hot path, so the team put server-side rendering behind Amazon CloudFront, which resolves static campaign data to HTML at the edge and collapses a page load from calls against multiple API endpoints down to a single request. With the CDN serving from the nearest edge location, origin sees a fraction of what the internet sends. The kitchen equivalent is plating the most-ordered dish in advance and keeping it by the door.

Cutting that multiplier toward 1 delivers more headroom than a 6x larger instance, and it keeps delivering every month afterward rather than reappearing on the next invoice. Yerrasani describes the same principle one layer down as request collapsing, or the singleflight pattern, where 500 simultaneous requests for the same uncached value produce one database query and 499 waiters. Engineering teams skip this check more often than any other in the audit, largely because trimming request counts reads as housekeeping rather than as capacity work. It is the cheapest capacity a platform will ever buy.
Data shape: one database serving two access patterns
Back to the kitchen. Cooking dinner service and prepping tomorrow's catering order are both reasonable jobs, and each one alone fits comfortably in the day. Doing both at 8pm on a Friday ruins the Friday, and the catering prep is what management notices least and cuts last.
Adact runs the software version of exactly that. Building a campaign is write-heavy, transactional, and relational, since marketers configure games, rules, prizes, and branding, and each of those writes has to be consistent. The analytics dashboard reads far more than it writes, asks for aggregates, and tolerates data that is a few seconds stale. Marketers watch that dashboard while the campaign runs, which means both workloads peak on the same trigger.
Run them against a single store and the dashboard degrades the campaign it is reporting on, at the exact moment the campaign matters most. The split Brocoders implemented gives campaign creation and configuration to PostgreSQL and the analytics dashboard to MongoDB, with both sitting behind one backend API so the separation stays invisible to the product and to the people building campaigns. Two kitchens, one pass, and the diners never see the difference.
Underneath, AWS Lambda paired with MongoDB autoscaling means capacity follows the number of people actually playing rather than the peak the team provisioned for, which matters on a platform where a campaign can be over in 10 days. Renting the ovens by the hour beats owning a hall you use twice a year.

The platform has since sustained more than 2 million requests at peak. Kalev Kärpuk, Adact's chief executive, described the outcome of that testing period as "a bug-free… platform, conquering initial product testing with more than two million interactions."
The split is a diagnostic rather than a rule. Plenty of platforms run one PostgreSQL instance at serious volume, and a version upgrade with a tuning pass often buys more headroom than a migration would. The question is narrower: does one store serve two access patterns that spike on the same event? Where they do, they compete for the same connection pool, the same query planner, and the same IOPS budget, and the workload that loses is rarely the one the business would have chosen.
Tenant shape: the noisy neighbor problem
A table of 200 walks in. They do not occupy 200 seats and leave the rest of the room alone, because they take every oven, every pan, and the entire attention of the pass. The couple at table four ordered a salad an hour ago and has no idea why it has not arrived, and neither does the waiter.
That is the enterprise onboarding scenario, and it is where the new contract does its damage. A tenant 10 times the size of the average consumes considerably more than 10 times its own share, because in a multi-tenant architecture the expensive resources are pooled by design: connection pools, background job queues, search indexes, cache memory. Engineers call the result the noisy neighbor problem, and Neon's analysis documents how it surfaces in production. The pattern is consistent. A large new customer runs an export across their full history, saturates the shared pool, and smaller tenants begin seeing timeouts on pages unrelated to the query that caused them. Diagnosis runs slow, because the tickets arrive from customers who did nothing.
Isolation is a data-layer decision before it is a networking one. On a multi-tenant HR platform Brocoders took from concept to production across multiple tenants, isolation is enforced through row-level security in PostgreSQL 16 rather than by application code remembering to filter. A new organization of 500 people syncs from its HRIS and comes live in minutes. The guarantee holds at the database layer, which declines to return another tenant's rows regardless of what the query asks for, and that is the property that matters under load, because the WHERE clause a developer forgot is precisely the one a large customer will hit.
AWS published the definitive survey of the available models in its SaaS Tenant Isolation Strategies whitepaper, covering the range from fully pooled to fully siloed. It is worth reading before the first large tenant rather than after, since retrofitting isolation into a running platform is a migration performed with a customer's data in the middle of it. For a single incoming account, one bounded change does most of the work: give that tenant its own connection pool and its own job queue lane, and leave the rest of the estate pooled. The large party gets its own oven and its own server, and the rest of the room carries on.
Failure shape: deciding in advance what to refuse
A kitchen that insists on cooking every dish on the menu perfectly, on the busiest night of its life, sends nothing out at all. A kitchen that pulls the dessert menu at 8pm and says so at the door keeps the main courses moving and keeps most of the room happy.
Perfect uptime is the wrong design target for the same reason. Yerrasani's alternative is load shedding by business priority, which means sorting traffic into tiers before the peak rather than during it. Critical traffic gets served: checkout, authentication, whatever the revenue runs through. Degradable traffic gets a cached or reduced version, which covers the recommendations widget, the live counter, the analytics refresh. Non-essential traffic gets dropped with a clear message. Bulkhead isolation keeps a saturated component from taking neighboring components down with it, in the way a fire door keeps a fire in one room.
The same instinct applies on the client, and EveryPig is the version Brocoders has shipped. It is a pig health and production platform whose users work from farm sites with unreliable connectivity, so an offline mode built on IndexedDB and Workbox lets the application degrade to local storage and sync once the connection returns. Server side or client side, the design question is identical: what does a partially available system still do?
Rehearsal is the part teams most often defer. Yerrasani's teams run game days that stress systems to 50% above projected peak, which is the software equivalent of cooking a full service for an empty room to find out which station falls behind. Where a customer has a contracted go-live date, that expected load should have been run twice in staging, broken something, and been fixed, well before the date arrives. Discovering the limit in production, in front of the account that justified the last funding round, is the outcome the entire exercise exists to prevent.
How much scale is enough
There is an equal and opposite failure, and in 2026 it is arguably the more common one. Building a kitchen for a thousand covers a night when the room seats fifty is not caution. It is a bill that arrives every month, for ovens nobody lights.
The premature scaling failure mode is documented plainly: "The cost of premature scaling is not in writing the code but in operating it." A sophisticated distributed architecture can be generated in an afternoon now and will be operated for years, with every service boundary adding a deployment, a monitoring surface, an on-call page, and somewhere for latency to hide. When real scale eventually arrives, it tends to arrive "in a shape the infrastructure did not anticipate," and the rewrite happens anyway. AI coding tools sharpened that tradeoff in a specific direction, because the cost of producing complex architecture fell hard while the cost of running it did not move.
The bounded version of the rule is to design for the next order of magnitude rather than the final one, and to set explicit thresholds that trigger architectural work instead of designing speculatively. The numbers belong to each team, and choosing them is the exercise: at X concurrent users the read path splits, at Y tenants the platform moves to per-tenant pools. Writing them down converts the next argument into a measurement.
Adact is worth reading in that light. Neither the request collapse nor the database split was speculative work. Both were responses to a load profile the team could already describe, on a platform whose campaigns were already arriving in waves, which is why the answer came to two architectural decisions rather than a rebuild.
Running the audit before the go-live date
The four shapes are answerable in days rather than weeks. Count the calls per page view. Map which access patterns share a store and whether they peak on the same trigger. List every shared resource a single large tenant will touch. Write down the traffic tiers to shed and the order to shed them in.
The output is a ranked list of which layer gives out first at 10x, with a threshold attached to each, and in most cases two or three changes that matter rather than a rebuild. On Adact those changes were server-side rendering through CloudFront and a database split by access pattern, and the platform has carried more than 2 million requests at peak since, across campaigns that arrive without warning and finish inside a fortnight.
Brocoders runs this as a paid scoping engagement before anyone writes code, the same shape as the technical audit that opens most of our modernization and rescue work. Where there is a date on a contract and a system that has never seen that load, that is the conversation worth having, and it costs considerably less than the postmortem.
Frequently Asked Questions
SaaS scalability is a platform's ability to absorb a step change in load, whether from traffic volume or from a single large customer, without degrading service for existing users. It spans four layers: request volume per user action, database access patterns, tenant isolation across shared resources, and controlled degradation once demand exceeds capacity anyway.
Autoscaling adds stateless application instances, which were already the most elastic component in the system. It does not help with the components that saturate first, including database connection pools, cache origins, and shared job queues. It is also reactive, so latency climbs and retries multiply during the minutes new instances take to provision.
Usually the database connection pool. Every new application instance opens its own connections against the same finite pool, so scaling the application tier out drains it faster. Cache stampedes follow when popular keys expire at the same moment and every request reaches origin at once.
Run the expected load in staging at least twice before go-live. Give the incoming tenant its own connection pool and job queue lane so one heavy query cannot reach other customers. Verify that isolation is enforced at the database layer rather than in application code. Freeze configuration changes for the week around launch, since procedural and human error remain a leading outage driver in the Uptime Institute's 2026 data.
It occurs when one tenant's workload consumes shared resources and degrades service for every other tenant. The shared resources are typically connection pools, background job queues, cache memory, and search indexes. It is addressed through tenant-level isolation, per-tenant resource limits, or a siloed model for the largest accounts.
Usually no. On Adact, a platform sustaining more than 2 million requests at peak, the changes that mattered were server-side rendering and a database split by access pattern rather than decomposition into services. Microservices help where independent components genuinely need to scale on different curves. Brocoders has written separately on when that migration is worth the operating cost.
The next order of magnitude rather than the final one. Set explicit load thresholds that trigger architectural work, build to the threshold, and stop. Architecture built for scale a product never reaches costs money every month it is operated, and scale tends to arrive in a shape the speculative design did not predict.