Scaling a PHP application across multiple servers sounds simple:
1 server
↓
2 servers
↓
4 serversBut adding servers does not automatically make an application scalable.
In many cases, horizontal scaling exposes problems that already existed in the architecture — especially poor state management.
This is the next post in Batch 5: Scaling PHP Without Losing the Architecture.
What Is Horizontal Scaling?
Horizontal scaling means adding more application instances instead of making one server more powerful.
For example:
Load Balancer
/ | \
/ | \
App 1 App 2 App 3Requests can now be handled by any application instance.
This gives you more capacity and can improve availability.
But it introduces an important rule:
Any request should be able to reach any application instance without breaking the application.
That is where state becomes a problem.
The Hidden Single-Server Assumption
A PHP application may accidentally depend on data stored inside one server.
For example:
$_SESSION['cart'] = $cart;Or perhaps the application stores temporary data in:
/tmp
local filesystem
in-memory cache
static variables
local session filesWith one server, everything appears fine.
Then you add another server.
A user logs in through App 1:
User
↓
App 1
↓
Session stored locallyTheir next request reaches App 2:
User
↓
App 2
↓
Session not foundNothing is technically wrong with the load balancer.
The problem is that the application assumed all future requests would return to the same machine.
Sticky Sessions Are Not a Real Architectural Fix
One common solution is sticky sessions.
The load balancer keeps sending the same user back to the same server.
User A → App 1
User B → App 2
User C → App 3This can work, but it often hides the underlying architecture problem.
What happens when App 1 fails?
If important state exists only there, User A may lose it.
Sticky sessions can be useful operationally, but they should not become an excuse for letting important application state live inside one process or machine.
Shared State Should Live Outside the Application Instance
A horizontally scalable application usually treats application servers as replaceable.
Instead of:
App 1 owns user state
App 2 owns different user stateyou want:
Shared State
/ | \
App 1 App 2 App 3That shared state might live in:
- a database
- Redis or another shared cache
- object storage
- a queue
- another dedicated service
The important point is not the technology.
The important point is ownership.
Application instances should not secretly become the authoritative owner of business-critical state.
Stateless Does Not Mean “No State”
This is an important distinction.
Applications still need state.
Users have sessions.
Orders have statuses.
Jobs have progress.
Carts contain products.
The goal is not to remove state.
The goal is to avoid tying important state to one replaceable application process.
A better model is:
Request
↓
Any App Instance
↓
Shared Authoritative StateNow App 1 can disappear and App 2 can continue serving the next request.
Local Files Can Cause the Same Problem
Consider file uploads.
An application writes:
App 1
└── uploads/invoice.pdfLater the user requests the file, but the load balancer sends the request to App 3.
App 3 does not have it.
Again, horizontal scaling did not create the problem.
It revealed the fact that storage ownership was tied to one machine.
Moving shared files to object storage or another shared storage layer makes the boundary explicit.
Long-Running Workers Make State Problems Worse
Traditional PHP requests are short-lived, which can hide state leaks.
With workers or persistent runtimes, memory survives between executions.
Suddenly things like:
static $currentUser;
$GLOBALS['tenant'];
$container->set('request', $request);can become dangerous if they are not reset correctly.
One user's state may survive long enough to affect another execution.
That is why scalable PHP architecture needs clear execution boundaries and disciplined lifecycle management.
A Useful Rule
When designing for horizontal scaling, ask:
If this application instance disappears right now, what important information disappears with it?
If the answer includes:
- user identity
- orders
- workflow state
- uploaded files
- business decisions
- retry information
- job progress
then that state probably belongs somewhere more durable or explicitly shared.
Scaling Exposes Architecture
Horizontal scaling is not just an infrastructure decision.
It tests whether your application has clear boundaries around:
- state
- storage
- sessions
- caching
- execution lifecycle
- ownership
A system that only works correctly when every request reaches the same machine is not truly horizontally scalable.
The servers may multiply.
The architecture still has not.

No comments:
Post a Comment