Skip to main content

High-Performance Infrastructure for E-Commerce: Handling Traffic Spikes Without Downtime

Online stores do not fail gradually. They work, and then within about ninety seconds they do not usually on the single day of the year when failure is most expensive.

The pattern is consistent enough to be predictable. Traffic rises, response times creep up, PHP workers stay busy longer, the pool fills, requests queue, database connections exhaust, and the site returns errors to everybody including the customers who were already mid-checkout and would have paid. Nothing in that chain is exotic. Every part of it can be designed for in advance.

Key Takeaways

What actually breaks first

Understanding the failure sequence is what makes the fixes obvious.

PHP workers, or the application process pool. A store has a finite number of concurrent request handlers. If each request takes 200 ms, one worker serves five per second. If a slow query pushes that to two seconds, the same worker serves one every two seconds a tenfold capacity loss without a single additional visitor. Slowness and capacity are the same problem seen from different angles.

Database connections. Each active request holds a connection. The connection limit is reached long before the server runs out of CPU, and the errors that follow are the ones customers see.

The session and cart store. Sessions written to disk on a busy store create a small storm of tiny writes. This is the component teams most often forget until it fails.

Storage throughput. Logs, sessions, cache files and image processing all compete for the same disk. On slow storage this is where a spike quietly turns into a queue.

Only after all of that does the web server itself become the constraint.

Layer one: cache everything that can be cached

Most traffic in a spike is reading. Homepage, category pages, product pages, images the same content served to many people. Every one of those requests that reaches the application is a request the application did not need to handle.

Full-page caching for anonymous visitors is the largest single win available to most stores. Logged-in users and anyone with a cart must bypass it, but on a typical traffic spike the majority of visitors are anonymous browsers, and they can be served without touching the application at all.

Object caching in memory Redis or Memcached keeps query results, session data and configuration out of the database. This is also the correct answer to the session-storage problem above.

OPcache for compiled PHP, which costs nothing and is occasionally still switched off.

A CDN for static assets. Images, CSS, JavaScript and fonts are typically the majority of bytes and almost none of the computation. Serving them from the edge removes that load entirely, and for stores with media-heavy catalogues, S3-compatible object storage behind the CDN keeps large libraries off the application server's disk.

Database query caching and correct indexes. Faceted filtering without proper indexes is the most common source of slow queries in e-commerce, and it degrades precisely when concurrency is highest.

Layer two: separate the database

Running the application and the database on the same instance is normal and works well up to a point. That point arrives when the two start competing for the same memory.

Separating them onto distinct instances gives each what it actually needs. The application server wants CPU and enough memory for its worker pool. The database wants memory enough to hold its indexes and working set and fast storage. On Cloud VPS in Bulgaria this maps directly onto the CPU Optimized and Memory Optimized profiles, with 8 GB of RAM per vCPU on the memory-optimised range, and it is generally the single highest-value structural change a growing store can make.

Once separated, read replicas become possible. Catalogue browsing, search and reporting can be served from a replica while the primary handles orders and inventory which matters because reads and writes have completely different scaling characteristics.

Layer three: scale horizontally for the events you know about

Vertical scaling a larger instance is simple and has a ceiling. Horizontal scaling puts several application instances behind a load balancer, and it changes what is possible during a planned event.

Load balancing) distributes requests across instances, removes any single one as a point of failure, and the underrated benefit lets you deploy code without downtime by rotating instances out of the pool.

It does impose requirements. Sessions must be shared, not stored on the local disk of one instance. Uploaded media must live in shared storage rather than on a single machine's filesystem. Deployments must reach every instance. These are one-time architectural decisions, and making them before you need to scale is considerably easier than making them during a campaign.

The practical pattern for a known event Black Friday, a product launch, a television appearance is to scale up in advance rather than to rely on reacting in the moment. Automatic scaling responds to load after it arrives, which means the first few minutes of a spike are served by the old capacity. Provisioning ahead of a date you already know is both cheaper and more reliable. Adding instances takes minutes rather than days, and our one-year plans include up to three free resource upgrades per year, so growing into a larger configuration does not require a migration.

Layer four: protect the checkout path

Everything above is about reading. Revenue is writing, and writes have their own rules.

Checkout cannot be cached. It touches inventory, it creates orders, it calls a payment provider, and it must be correct. That leads to a few specific design choices.

Keep the checkout path short. Every synchronous third-party call tax service, courier rate lookup, CRM sync, analytics is a dependency that can time out under load and take the order with it. Defer everything that is not required for the order to be created.

Move work to queues. Confirmation emails, invoice generation, ERP sync, warehouse notifications, loyalty points. None of these need to happen before the customer sees a confirmation page. A queue worker on a separate instance absorbs them without slowing the transaction.

Watch inventory locking. Under high concurrency, row-level locks on popular products serialise the very orders you most want to process in parallel. This is worth testing explicitly, because it only appears under real concurrency.

Set sensible timeouts. A payment gateway that responds slowly should fail fast and be retried, not hold a worker for thirty seconds while the queue behind it grows.

Layer five: keep the traffic clean

Not all of a spike is customers. Aggressive scrapers, credential-stuffing attempts and outright denial-of-service traffic all arrive as load, and they arrive disproportionately during high-profile events.

Volumetric attacks have to be absorbed upstream of your server, which is why network-level mitigation matters our platform provides layer 3 and 4 DDoS protection backed by 12 Tbps of network edge capacity across more than twenty points of presence. Above that, rate limiting on login and search endpoints, and a web application firewall in front of the store, handle the application-layer noise that never reaches the volume of an attack but consumes real capacity.

A pre-event checklist

  1. Load test on a copy of production, not on staging with a fraction of the catalogue. Establish where it breaks before the day does.
  2. Verify cache hit rates. A cache that is bypassed by a stray cookie is not a cache.
  3. Review slow query logs and add the indexes that faceted filtering needs.
  4. Provision extra capacity 48 hours ahead and confirm it is actually serving traffic.
  5. Check backups and restore one. Under load is the wrong time to discover a backup job has been failing quietly.
  6. Watch the right metrics live: response time percentiles, worker pool saturation, database connections, error rate, checkout completion rate. Averages hide the problem; the 95th percentile shows it.
  7. Write down the degradation plan. If load exceeds capacity, what gets switched off first live search, recommendations, reviews? Deciding under pressure produces worse decisions.

Conclusion

Stores that survive their busiest day are rarely the ones with the largest servers. They are the ones that cached aggressively, separated the database from the application, kept the checkout path short and synchronous only where it had to be, moved everything else to queues, and tested the whole arrangement before the traffic arrived.

The infrastructure has to be capable of it, and it has to be provisioned before you need it. But most of the resilience comes from architecture, and architecture is decided months earlier on an ordinary day, when there is time to think.

Preparing for your next peak? Delta.BG offers Cloud VPS in Basic, CPU Optimized and Memory Optimized configurations on all-NVMe infrastructure with triple replication, plus dedicated servers, S3-compatible object storage, DDoS protection and 24/7 monitoring from an Equinix Tier 3+ data centre in Sofia. Speak to our team on +359 2 4 288 288 or at [email protected].