← Back to blog

How to Scale Infrastructure: From One Server to Many

Maria Ilinca Bostan

Scaling infrastructure means adding capacity without adding fragility. In practice that is four decisions: scale up or out, make the application stateless, move the database deliberately rather than last, and put a cache in front of everything. Each has a point where it stops working, and knowing those points is more useful than any growth chart.

Vertical or horizontal

Scale up (bigger instance)Scale out (more instances)
EffortA plan changeLoad balancer, shared state, deployment changes
CeilingLargest plan — 32 GB / 8 vCPU, then bare metalPractically none
RedundancyNone — still one machineSurvives losing an instance
Cost curveSteps up per tierLinear per instance
Good forDatabases, stateful services, buying timeWeb tiers, APIs, workers

Scale up first — it is one action and it buys months. Scale out when you need redundancy as much as capacity, or when the largest single instance is no longer enough.

Make the application stateless before you need to

Horizontal scaling only works if any instance can serve any request. Four things usually keep state on the box and block that:

  • Sessions on local disk. Move them to Redis. Sticky sessions at the load balancer are a workaround, not a fix — they unbalance traffic and lose sessions when an instance dies.
  • Uploaded files on local disk. Move to object storage, or a shared volume. This is the change that takes longest to retrofit, which is why it is worth doing early.
  • Local caches with no shared invalidation. Two instances with disagreeing caches produce bugs that are very hard to reproduce.
  • Cron jobs on every instance. Three instances means the nightly job runs three times. Use a leader election or a dedicated worker instance.

Doing this while you still have one server is an afternoon. Doing it during an incident is not.

The database is where scaling actually gets hard

Web tiers scale by adding boxes. Databases do not, and this is where most scaling projects run into difficulty. The realistic order:

  1. Index and query tuning. Almost always the largest single win, and free. Enable the slow query log for a day and fix the top three.
  2. Right-size the buffer pool. innodb_buffer_pool_size or shared_buffers sized so the working set stays in memory.
  3. Connection pooling. PgBouncer or ProxySQL. Ten application instances each opening fifty connections will exhaust a default connection limit long before the database runs out of capacity.
  4. Read replicas. Send reads to replicas, writes to the primary. Effective for read-heavy loads, and it introduces replication lag your application must tolerate.
  5. Its own machine. A dedicated database server with physical cores, all the memory channels and ECC memory — see database server hosting.
  6. Sharding. Powerful and genuinely difficult. Exhaust the five steps above first.

Cache aggressively at every layer

The cheapest request is one your infrastructure never processes.

  • CDN for static assets — served from the edge, never reaching your instances.
  • Full-page cache at the proxy for anonymous traffic. See the Nginx reverse proxy guide.
  • Object cache in Redis for query results and computed values.
  • HTTP cache headers so browsers stop asking.

A well-cached application often handles ten times the traffic on the same hardware. That is a larger multiplier than any plan upgrade on the price list.

The growth path, priced

StageShapeRoughly
LaunchOne Pulse or Core instance, caching on€6–10/mo
TractionCore or Forge, Redis, CDN€10–16/mo
Redundancy2× Core behind a load balancer, database separate€30/mo
Growth3–4 app instances, Apex database instance€60–90/mo
ScaleApp tier on VPS, database on bare metal€209+/mo for the database

The last row is the pattern most mature deployments end up with: elastic stateless capacity on VPS instances, and the stateful part on hardware with guaranteed cores and memory bandwidth.

Scale down as deliberately as you scale up

Growth is not monotonic. Post-campaign, post-season and post-launch traffic falls, and the capacity added for the peak often stays. With hourly billing, removing an instance stops the cost immediately — but only if someone removes it. Put a review in the calendar; forgotten capacity is the most common form of infrastructure waste.

What to measure before adding anything

  • p95 and p99 response time, not the average. Averages hide the experience that makes users leave.
  • Saturation, not utilisation. Queue depth and wait time tell you when you are about to fall over; CPU percentage does not.
  • Error rate under load. The first symptom of insufficient capacity is usually errors, not slowness.
  • Database connection count and slow query volume. The usual real bottleneck.

Add capacity in response to a number, not a feeling. The performance guide covers the tuning that often removes the need entirely.

Frequently asked questions

When should I move from one server to several?

When you need redundancy, or when the largest single instance no longer fits. Redundancy usually arrives as the reason before capacity does.

Do I need Kubernetes to scale?

No. A load balancer, a handful of instances and a deployment script take most businesses a very long way. Kubernetes solves problems you should be certain you have before adopting it.

How do I handle sudden traffic spikes?

Cache first, so most of the spike never reaches the application. Then add instances — sub-minute provisioning makes that a live response rather than a plan.

Should the database be on a VPS or bare metal?

VPS until tail latency or memory bandwidth becomes the constraint, then bare metal. Databases are the workload that benefits most from physical cores.

Build the next stage cheaply

Every step above can be rehearsed before it is needed. Deploy the instances, wire up the load balancer, test the failover, then destroy them — at €0.0056/hr, a full dress rehearsal of your next architecture costs less than lunch.

Ready in under a minute

Deploy your first server now.

No contracts, no minimums. Start on an Ion KVM VPS at €0.0063 an hour and move to a monthly bare-metal server the day you outgrow it.

$ voxa deploy --plan ion --location amsterdam

KVM VPS billed hourly, capped monthly · Dedicated billed monthly · No setup fee

Included on every plan
Free IPv4 + IPv6
Every VPS
Unmetered traffic
1–10 Gbps
DDoS mitigation
2.5 Tbps
Root / IPMI access
Included
Setup fee
€0.00
Minimum term
None