Growing traffic puts pressure on different parts of a website. A busy checkout may overwhelm the database, while a popular article may need little extra server capacity if a CDN serves most requests. Find the part that slows down before deciding whether to optimize the application, choose a larger server or add more instances.
This guide walks through traffic estimates, caching, databases, background jobs and load testing so you can plan capacity around the work your site actually does.
Estimate the traffic you need to handle
Start with the event you expect: a product launch, a campaign, seasonal demand or steady growth. Use access logs and previous events to estimate requests per second, concurrent sessions and how long the peak will last.
Include the mix of anonymous and signed-in visitors, reads and writes, uploads and downloads, and visitor locations. Identify the journeys that must keep working, such as checkout or account login, and set acceptable response times and error rates for each.
Monthly visits alone cannot tell you the server size. Ten thousand cached page views spread across a day create a different workload from hundreds of simultaneous checkouts. Mark estimates that you still need to test.
Reduce the work behind a slow request
Profile the application and follow the slow request through its dependencies. Look for repeated database queries, slow templates, unnecessary plugins, large responses, external API calls and image processing that makes the visitor wait.
Fix missing indexes, unbounded loops and repeated work before adding capacity. A larger server may hide the problem for a while, but the cost of each request still matters as traffic grows.
Measure response-time percentiles alongside request rate, errors and resource use. The median, or p50, shows a typical request; p95 and p99 help reveal the slower requests that an average can hide.
Use a CDN for cacheable traffic
Serve versioned images, scripts, styles and downloads with suitable cache headers. A CDN can serve those files closer to visitors and reduce requests to the origin server.
Check cache keys, expiry, invalidation, compression and partial-file requests against how the site works. Personalized pages, authenticated responses and dynamic APIs need rules that prevent private content from being shared between visitors.
Measure the cache-hit rate and the requests still reaching the origin. Test what happens after a purge or when popular content is missing from the cache: that is often when the origin sees its hardest burst.
Cache expensive application work
Application caches can store page output, fragments, computed results or frequently read database objects. Choose the cache by the work it removes, then define its keys, expiry, size limit and invalidation rules. Give someone responsibility for those rules when the underlying data changes.
Plan for an empty or unavailable cache. If many requests rebuild the same expired item at once, the resulting cache stampede can overwhelm the database. Depending on the application, bounded locks, combining duplicate requests or serving a stale value while refreshing it can help.
Test warm and cold caches separately. Include session storage in your failure tests if the application relies on a cache service for logins.
Check the database separately
Track slow queries, connection use, locks, memory used for active data, write volume and storage latency. A quiet web-server CPU does not rule out a database bottleneck.
Review queries and indexes before increasing connection limits or adding application workers. More workers can make contention worse if they all wait on the same database operation.
If you add replicas or move the database to another host, decide which reads can tolerate replication delay, how failover works and who handles it. Back up and restore-test the data. Adding web servers alone does not solve the limits of a shared database.
Move background jobs out of web requests
Queue work that can finish after the response: email API calls, media processing, reports, imports and suitable webhook processing. Set worker concurrency, retry limits and the oldest acceptable job age.
Make retries safe with idempotency: processing the same job twice should not create duplicate orders or payments. Send jobs that repeatedly fail to a dead-letter queue or another place where an operator can investigate them.
Test web requests and workers together. Traffic can look healthy while a queue quietly falls behind. Alert on job age and failures as well as queue depth and CPU use.
Choose a larger server or more instances
Vertical scaling means giving one server more resources. It is often simpler to operate, but confirm the provider's resize procedure, available plans and downtime before relying on it. The application still depends on that one instance.
Horizontal scaling spreads requests across multiple application instances. It needs repeatable deployments, health checks, load balancing and a way for instances to share required data. It also adds deployment and recovery work.
| Next step | Evidence to look for | What to check afterwards |
|---|---|---|
| Optimize the current stack | Profiling identifies avoidable work | Repeat the same test after each fix |
| Test a larger server | CPU, memory or storage remains saturated after software fixes | Headroom, resize procedure and recovery from instance failure |
| Add application instances | The application can serve requests across concurrent instances | Shared database, cache, queue and storage limits |
| Use managed autoscaling | Variable demand and available operating time justify the service | Quotas, startup time, cooldowns, state, rollback and total cost |
Make sessions and files work across instances
Check every place the application stores changing data before adding a second instance. Sessions, uploaded files, generated assets, locks and scheduled jobs may currently depend on one machine.
Use suitable shared storage or a token-based session design where appropriate. If you deliberately use sticky sessions, test what happens when the selected instance fails. Prevent multiple instances from running the same scheduled job unintentionally.
Try removing an instance during an active session, deploying mixed application versions and interrupting access to shared storage. Confirm whether the application retries, rejects the request or provides a reduced service, and check for lost or duplicated work.
Run a realistic load test
Use a test environment with representative software, configuration and data. Use synthetic accounts and test integrations so the run cannot place real orders, send customer notifications or overload an outside service.
- Record idle resource use and a warm-cache baseline.
- Increase traffic gradually to the expected peak.
- Mix critical reads and writes in realistic proportions.
- Run long enough to expose growing queues, logs, storage use and connection pressure.
- Repeat with a cold cache and a deliberately unavailable dependency, then test recovery.
- Stop at your agreed safety threshold and save application, server, database, cache, queue and network measurements.
Check response time, errors, data integrity, queue age and recovery against the targets you set. Leave measured headroom for variation instead of treating one successful run as the server's permanent capacity.
Monitor growth and prepare for overload
Combine external availability checks with application and server monitoring. Watch request rates, latency, errors, busy workers, CPU, memory, swap, disk capacity and storage latency. Add database connections and locks, cache hits and evictions, queue age, network transfer and dependency failures.
Each alert needs a useful threshold, an owner and a next action. Write down how to reduce optional work, pause imports, serve a safe reduced response, increase tested worker capacity or roll back a release. Choose the action according to the component that is failing.
Test the application on a Virtarix VPS
Cloud VPS S is one possible starting point for a measured workload. Its listed resources are:
| Item | Cloud VPS S |
|---|---|
| Standard monthly price | $5.50/month |
| CPU | 3 CPU cores |
| RAM | 6 GB |
| Storage | 50 GB NVMe |
| Bandwidth | Unlimited* |
| Access | Full root |
| Network | IPv4 + IPv6 |
| Snapshot | One included |
| Availability | Uptime SLA of 99.99% |
* Unlimited bandwidth is subject to fair use, acceptable-use requirements, network integrity and service limits.
Virtarix is self-managed, so include operating-system updates, application security, firewall rules, monitoring and incident response in the work estimate. Keep independent backups and test recovery; the included snapshot does not replace those copies.
Choose a plan you can test with the application. Confirm how a later resize or migration would work before making it part of the growth plan.
Compare hosting options using the same workload
| Hosting model | When it may fit | Costs and limits to check |
|---|---|---|
| Shared hosting | A supported application fits the host's limits and needs little server administration | Traffic limits, renewal price, support, restore options and migration |
| Self-managed VPS | Root access or custom software is worth the operating work | Server resources, security, monitoring, recovery and operator time |
| Managed platform | The application fits the platform and managed operations save useful time | Scaling rules, quotas, startup time, state, database, transfer and rollback |
| Multiple application instances | Tested demand or continuity requirements justify the added components | Load balancing, shared state, deployment, failover and data recovery |
Include databases, storage, transfer, monitoring and support when comparing costs. A monthly server price covers only part of a multi-service application.
Keep a short record of the expected traffic, measured bottleneck, changes tested, result, total cost and next review trigger. That gives you a practical basis for the next capacity decision when traffic changes.
Plan capacity around your traffic
Compare Cloud VPS plans with the CPU, memory and storage needs measured in your application test.
VPS S
For small sites, dev servers and Docker
- ✓ 3 cores
- ✓ 6 GB
- ✓ 50 GB NVMe
- ✓ Unlimited
VPS M
For growing apps, websites and staging
- ✓ 6 cores
- ✓ 16 GB
- ✓ 100 GB NVMe
- ✓ Unlimited