PHP Multiple Ajax requests First request block second request
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
If two AJAX calls hit the same PHP application and the second one appears to wait for the first, the browser is usually not the real problem. In many cases PHP is serializing those requests because the session is locked for the lifetime of the first request.
Why This Happens
By default, PHP stores session data in files. When a request calls session_start(), PHP opens the session storage and places an exclusive lock on it. That lock is kept until the script ends or until the session is explicitly closed.
If a second request from the same user arrives while the first request still holds the lock, the second request cannot read or write $_SESSION yet. It waits, which makes the two AJAX requests look sequential even though the browser sent them concurrently.
This is easy to reproduce with a slow endpoint:
If another request from the same browser session also calls session_start(), it will often pause until the five-second sleep finishes.
Release The Session Early
The standard fix is to close the session as soon as you no longer need it. Read the values you need, write any updates, and then call session_write_close().
Now the session lock is released before the expensive work starts, so a second request can continue immediately.
This pattern is especially useful for endpoints that:
- check whether a user is logged in
- read a small amount of session state
- perform long database or API work afterward
The Browser Is Usually Not The Bottleneck
Modern browsers can send multiple requests to the same origin. A simple frontend example proves that the client is willing to do work in parallel:
If one PHP endpoint blocks the other, the cause is typically server-side state management, not fetch() itself.
When To Avoid Sessions Entirely
Some endpoints do not need session data at all. For those routes, do not call session_start(). If the request only needs a bearer token, API key, signed cookie, or request payload, keeping it stateless avoids unnecessary locking and makes horizontal scaling easier.
A useful rule is:
- use sessions for small authentication or preference data
- avoid sessions for long-running background-like requests
- do not hold the session open while waiting on I/O
Other Sources Of Apparent Blocking
Session locking is the most common reason, but not the only one.
Single-threaded development servers can also serialize requests. A file lock, database row lock, or external API rate limit can create the same symptom. That is why it helps to inspect timing in server logs instead of assuming the session is always the cause.
For example, if both requests are hitting different PHP-FPM workers but still waiting, look for shared resources:
With logs from multiple endpoints, you can see whether the second request started immediately or only after the first released some shared lock.
Common Pitfalls
- Calling
session_write_close()too late. If you put it after a slow query orsleep(), the second request still waits. - Reopening the session accidentally. Libraries or included files may call
session_start()again and recreate the lock. - Assuming every concurrent issue is a browser problem. Test the backend timing before changing frontend code.
- Using sessions for large mutable state. The more often requests need to update
$_SESSION, the more often you serialize user traffic.
Summary
- PHP sessions commonly block concurrent AJAX requests from the same user.
- The lock starts at
session_start()and lasts until the session is closed or the request ends. - Call
session_write_close()as soon as session access is finished. - Skip sessions completely for endpoints that do not need them.
- If the issue remains, investigate other shared locks such as files, databases, or a single-threaded dev server.
Related reading
- Php script halts when called via async curl
- PHP send POST request in separate thread and forget
- Platform.runLater and Task in JavaFX
- Play framework job queue
- Please point out the misfacts in my learning regarding Asynchronous Javascript
- Pool.apply_async nested function is not executed
- Populating NSImage with data from an asynchronous NSURLConnection
- Portable Compare And Swap atomic operations C/C library?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.