Profile    Mohammed Shiroz Status   Loading  
Logo
Share This
Back to blog
Filter by:
Tags
//Article title

Load Balancers Explained: Spreading Traffic Without Losing Sessions

About Post

You add a second server so the app can handle more traffic. You put a load balancer in front. Everything looks great, until users start getting logged out at random, file uploads vanish half the time, and the nightly report emails go out twice.

Nothing is broken, exactly. Your app just quietly assumed it was the only server in the world, and now it isn't. Load balancers are simple in principle, and most of the trouble comes from what they change about your application. Let's cover both.

What a load balancer does

Think of the host at the door of a busy restaurant. Guests don't pick their own table; the host looks at which waiters are free, skips the section that's closed, and seats people where they'll be served fastest. If a waiter goes home sick, the host stops sending guests to that section.

A load balancer is that host. It accepts every incoming request, picks a healthy backend server, and forwards the request there. That gives you three things:

  • Capacity: more servers, more requests handled.
  • Availability: one server dies, the others keep serving.
  • Easier deploys: take servers out of rotation one at a time, update, put them back.

Layer 4 vs layer 7

The layers come from the OSI model, and the difference is how much of the request the load balancer looks at.

Layer 4 (transport)Layer 7 (application)
SeesIP addresses and ports (TCP/UDP)The full HTTP request: path, headers, cookies
Can route byConnection onlyURL path, host name, header, cookie
TLSUsually passes it throughUsually terminates it (holds the certificate)
SpeedVery fast, very little work per packetA bit more work per request, far more flexible
ExamplesAWS Network Load Balancer, HAProxy in TCP modeAWS Application Load Balancer, Nginx, HAProxy in HTTP mode

For a typical web app or API, layer 7 is what you want. Sending /api/* to one group of servers and everything else to another, or redirecting HTTP to HTTPS in one place, are layer 7 features you'll use.

How it picks a server

  • Round robin: one each, in turn. Simple and fine when requests are similar in cost.
  • Weighted round robin: bigger servers get a bigger share.
  • Least connections: send to the server with the fewest active connections. Better when some requests are slow (reports, exports, file uploads) and others are instant.
  • Hash-based (by IP or a key): the same client always lands on the same server. Useful for caches, but uneven when many users share one IP, like an office network.

Round robin is the usual default, and for most apps the choice of algorithm matters much less than the next two topics.

Health checks: the part that gives you availability

The load balancer regularly calls a URL on each server. If a server fails enough checks in a row, it's taken out of rotation until it recovers.

Laravel 11 and 12 ship with a health route out of the box, configured in bootstrap/app.php:

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        health: '/up',
    )
    // ...

/up answers 200 when the app boots without errors. That's a shallow check: is this process alive? You might be tempted to write a deep check that also tests the database, Redis and every external API. Be careful. If the shared database has a hiccup, a deep check fails on every server at once, and the load balancer removes all of them, turning a slow database into a full outage. Keep the load balancer's check shallow, and monitor dependencies separately.

Sessions: why users get logged out

Here's the classic. The file session driver, the default for years and still common in older apps, stores sessions on the local disk. (New Laravel 11 and 12 apps default to database, which avoids this, as long as every server talks to the same database.) A user logs in on server A, so their session lives on server A. The next request goes to server B, which has never heard of them. Logged out.

There are two fixes:

Sticky sessions. The load balancer sets a cookie and keeps sending that user to the same server. It works, and it's a quick patch. But load becomes uneven, a deploy or crash on that server still logs its users out, and you're back to depending on one machine.

A shared session store. Every server reads sessions from the same place, so it doesn't matter which one handles the request:

SESSION_DRIVER=redis   # or "database"
CACHE_STORE=redis

This is the right answer almost every time. Servers become interchangeable, which is the whole point of having more than one.

The stateless rule: any server should be able to handle any request. If something lives only on one server's disk or memory (sessions, uploads, cache, locks), move it somewhere shared before you add the second server.

The rest of the checklist

  • Uploads: store files on S3 (or another shared disk) instead of local storage/, or half your images will 404.
  • Scheduled tasks: every server runs the scheduler, so every task runs once per server. Add ->onOneServer() to tasks that must run once. It needs a shared cache driver to coordinate the lock.
  • Real client IPs: behind a load balancer, $request->ip() returns the load balancer's address. Configure trusted proxies so Laravel reads X-Forwarded-For, for example $middleware->trustProxies(at: ...) in bootstrap/app.php. Trust only your load balancer's addresses where you can.
  • HTTPS detection: the same trusted proxy setup tells Laravel the original request was HTTPS, so generated URLs don't flip to http://.
  • Queue workers: they already pull from a shared queue, so they scale out happily. Just make sure jobs don't depend on local files.

If you remember one thing

Adding a load balancer is the quick part. Making your app ready for one is the real work: shared sessions, shared files, scheduled tasks that run once, and shallow health checks. Do those first and the second server really is just "more capacity".

Which one caught you out the first time you scaled past a single server: sessions, uploads or the scheduler running everything twice?

Comments (0)
Leave your review

Thanks for your valuable comments. Your comments has been updated and appreciate your getting in touch...

01. About Shiroz

Mohammed Shiroz

Hi, I'm Mohammed Shiroz, a software engineer and AI enthusiast from Sri Lanka who turns ideas into intelligent, real-world solutions. With over 9 years of hands-on experience, I currently lead real estate ERP development at Kate Group, a...

03.My Projects

04. Categories

Ready To order Your Project ?

Get in Touch
Close