When the Platform Had to Handle 20× More Traffic

Impact

~20× more user capacity

During the pandemic, demand and promotional campaigns started pushing our infrastructure far beyond what a single-instance monolithic backend could handle. Instead of migrating to Kubernetes or rewriting the infrastructure, I distributed traffic across multiple instances behind Apache as a load balancer and DNS-level distribution on the frontend, multiplying user capacity by 20× in a very short period.

Software Developer

During the pandemic we ran into a problem many startups discover all at once when their product starts to grow: demand exploded. Until then, our infrastructure had been enough for the platform's usual traffic, but growth combined with promotional campaigns that could generate huge traffic spikes within minutes started pushing it far beyond the levels it was designed for. The problem was especially tricky because the backend was essentially a monolith: each instance had a limited capacity for processing and concurrent connections, and we could keep scaling vertically, but we would eventually hit a physical and economic limit. We also did not have a Kubernetes-based infrastructure or an autoscaling system ready to react automatically to those spikes at the time. We needed to solve it fast, without turning a performance emergency into a full infrastructure rewrite.

Scaling horizontally with what we already had

The first decision was changing how we distributed traffic. Instead of trying to make a single instance handle the whole load, we spun up multiple API instances, both on AWS and on servers we already had internally, and used Apache as a load balancer to distribute requests between them. The idea was simple: if one instance could handle a given amount of traffic, several instances running in parallel gave us considerably more total capacity without having to modify the application right away.

Distributing the frontend's traffic too

The frontend had its own quirk: our web infrastructure was deployed on AWS, so we also needed to distribute those requests across different servers. We implemented a DNS-level distribution strategy to route traffic to different destinations, so it stopped depending on a single entry point. It was not a fully elastic infrastructure platform, but we did not need to build one to solve the immediate problem: we needed to buy capacity quickly and in a controlled way.

Solving the real problem first

One of the most important decisions was not trying to solve every architectural problem we would eventually face right then. We did not migrate everything to Kubernetes, did not rewrite the backend, did not turn the platform into a fully distributed architecture. We built a distribution layer around the infrastructure we already had, which turned a single-instance capacity problem into a load-distribution problem across several instances, and we managed to do it in a very short period.

Result

The strategy worked: with a series of relatively small configuration changes we managed to increase the platform's user capacity by roughly 20× compared to the original setup. This mattered most during promotional campaigns, where we could go from normal traffic to huge spikes almost instantly, and the infrastructure distributed that load across the available servers. The platform kept good performance during one of the periods of highest growth and demand we had experienced.

What I learned

This was one of those problems where the most technically sophisticated solution was not necessarily the right one. In hindsight, we probably could have designed a much more complex, fully automated infrastructure, but the problem in front of us was not building the perfect infrastructure: it was keeping the platform from collapsing while demand grew exponentially. The solution was pragmatic, relatively cheap, and fast to implement, and it gave us something we needed at that moment: time. Time for the product to keep growing, and to later think about a deeper evolution of the infrastructure. To me, this case still represents an idea that matters when working with production systems: good engineering is not always about building the most advanced architecture. Sometimes it is about finding the smallest change capable of solving a huge problem.