TL;DR / Summary: A seasonal sale is a capacity test disguised as a marketing event. Model the peak hour, not the peak day, and size dedicated server headroom around the checkout path rather than around the homepage.
The peak hour is the number that matters
Traffic graphs summarised by day hide the shape of a sale. A promotion that runs for six hours often concentrates a third of its traffic into the first twenty minutes, and that twenty minutes is what your infrastructure must survive.
Build the model from last year’s data if you have it, and from a conservative assumption if you do not. Take total expected visits, assume a pessimistic share arrive in the first hour, and add the effect of every reminder email landing at the same minute.
Then compute requests per second at the checkout endpoint, not at the homepage. Browsing traffic is cacheable; add-to-cart and payment callbacks are not, and they are what actually falls over.
Where dedicated metal buys you something cloud does not
Dedicated hardware gives you predictable single-tenant performance and no noisy neighbours. It also gives you a fixed amount of capacity that you must size in advance, which is either the whole point or the whole problem.
The advantage appears in workloads with steady, high baseline load: a large catalogue, heavy database work, or persistent connections. The disadvantage appears in unpredictable spikes, where cloud elasticity is genuinely better.
A common compromise is dedicated metal for the database and the application tier, with a CDN absorbing the cacheable front end. That keeps the expensive, stateful layer stable while the cheap, stateless layer absorbs the spike.
- Database: dedicated metal, provisioned for peak writes
- Application servers: dedicated, behind a load balancer
- Static assets and images: CDN, long cache lifetimes
- Search: separate node or managed service
- Queue workers: scalable, often the first bottleneck
Load testing that resembles the sale
A test that hits the homepage repeatedly proves nothing. Build a scenario that arrives, browses a category, adds an item, applies a discount code, and proceeds to checkout, with realistic think times between steps.
Run it at the modelled peak and then at fifty percent above, because your model will be wrong in the optimistic direction. Watch the database’s connection pool, the queue depth, and the error rate—not only response time.
A system that responds in 400 ms while the queue grows without limit is failing politely. Queue depth is the honest signal that capacity has been exceeded.
Discount code stampedes
The single most reliable way to break a sale is to release a limited code to a large list. Thousands of users hit the same validation endpoint at once, and if that endpoint touches the database per request, it becomes the bottleneck.
Cache code validity, rate-limit attempts per session, and precompute the redemption counter so the hot path is a fast read. Validate the final redemption at the payment step rather than greeting every visitor with a database query.
Pre-sale checklist for the infrastructure
Freeze changes at least a week before the event. The worst possible time to discover a configuration regression is during the first peak, and every deployment carries that risk.
Verify backups and restores before the sale, not after. A backup taken during a crash is often the only copy you have, and an unrestored backup is an untested assumption.
Confirm that monitoring alerts reach a human, with an escalation path that does not depend on one person being awake. Test the alert by triggering it deliberately.
Warm caches before the doors open. A cold cache turns a manageable peak into a stampede against the origin, and the first hundred visitors pay for the whole crowd’s warming.
During the sale: what to watch and what to leave alone
Watch four numbers: error rate, database connections, queue depth, and p95 latency on checkout. Everything else is secondary during the event.
Resist the urge to change code under load. If a fix is genuinely necessary, prefer configuration changes that can be reverted in one step, and write down what you changed and when.
Have a documented degradation path: disable recommendations, hide recently-viewed sections, queue non-essential emails. Deciding this in advance is the difference between a controlled slowdown and a scramble.
A sale plan that has no degradation step is a plan that ends with a 502 page.
After the sale: the useful postmortem
Record actual peak requests per second, error rates, and the time at which the first bottleneck appeared. Compare them to the model and note the error factor. Next year’s sizing starts from a measured number instead of an opinion.
Look for the near-misses too: the connection pool that reached ninety percent, the disk that filled to eighty, the queue that cleared only after midnight. Those are the failures you avoided by luck, and luck does not repeat.
Retire temporary capacity after the event but keep the configuration. Rebuilding it under pressure next season costs more than the savings from tearing it down.
Choosing the platform between sales
The hardware decision should account for the other fifty weeks, not only the peak. A server sized for the sale will sit mostly idle otherwise, which is fine if the price is fixed and low, and wasteful if it is metered.
For teams that need single-tenant performance year-round with a predictable bill, dedicated web hosting servers are a reasonable fit, provided the peak model is honest and the degradation plan exists.
Capacity planning is unglamorous work that happens weeks before anyone sees a banner. It is also the only reason a sale looks effortless from the customer’s side.
