I’m building a chat application in Laravel where I’m using the openai-php/laravel package to interact with the ChatGPT API. The AI responses can be quite large, and I want to stream them to the frontend in real-time for a better user experience.
I know Laravel supports streaming responses with return response()->stream(...), and there are packages for frontend integration like stream-react or stream-view.
The issue is: I’m struggling to properly implement the streaming logic within my Laravel controller and consume it effectively on the client side (using Vue 3 and Inertia.js).
- How do I correctly set up the
response()->stream()function to receive chunks from the OpenAI API and pass them to the client? - What is the best way to handle the connection and ensure all data is sent without the request timing out in Laravel?
- Are there any specific headers I need to set for this to work with an Inertia/Vue frontend?
// Current (problematic) Controller Code
public function generateResponse(Request $request) {
$prompt = $request->input('prompt');
// This code waits for the full response, not ideal for streaming
$result = OpenAI::chat()->create([
'model' => 'gpt-3.5-turbo',
'messages' => [
['role' => 'user', 'content' => $prompt]
],
'stream' => true, // I want to use streaming but don't know how to implement
]);
// How to stream $result chunks to the client?
return response()->json(['response' => $result['choices'][0]['message']['content']]);
}
Any guidance or code examples for the controller and frontend logic would be greatly appreciated!
This is a very good question.
Short version: no, Laravel does not automatically stop your streaming loop, and yes, you should explicitly handle client disconnects if you care about cost, resource usage, or correctness.
Below is the practical, PHP-level explanation.
What actually happens when the client disconnects
When you stream a response with response()->stream():
-
PHP keeps executing your callback until it finishes
-
OpenAI will continue streaming tokens
-
Your loop will keep running unless you stop it
-
The fact that the browser closed the page does not magically stop PHP
Laravel itself does not manage this for you. Once the request is handed off to PHP-FPM, it’s your responsibility.
In other words:
If you do nothing, you will keep paying for tokens no one sees.
How to detect a disconnected client in PHP
PHP provides a built-in way to detect this:
-
the browser navigates away
-
the tab is closed
-
the fetch request is aborted
However, you must explicitly check it.
Correct way to handle this in your streaming loop
Update the loop like this:
-
You stop reading from OpenAI
-
The loop exits immediately
-
The PHP request terminates cleanly
This is the single most important missing piece in most examples.
Do PHP-FPM or Nginx handle this for you?
No.
-
Nginx will close the client socket
-
PHP-FPM will keep executing until your script exits
-
Laravel does not wrap or intercept the streaming loop
Unless you break the loop, OpenAI keeps streaming.
What about ignore_user_abort()?
By default, PHP behaves as if:
You still need:
Frontend: how this ties back to fetch()
When you cancel the request on the client:
-
TCP connection close
-
connection_aborted()→truein PHP -
Your loop exits (if you check it)
Without the server-side check, aborting on the client does nothing useful.
Why this matters more with OpenAI streaming
OpenAI streaming is pull-based:
-
Your loop keeps pulling tokens
-
There is no automatic “stop” signal
-
The SDK won’t stop unless you stop iterating
So client disconnect handling is mandatory in production.
SSE / WebSockets note
-
SSE: same issue, same solution (
connection_aborted()) -
WebSockets: easier, because disconnect events are explicit
-
If you expect frequent cancels, WebSockets are cleaner
But even SSE does not solve this automatically.
Bottom line
-
Laravel does not stop streamed responses automatically
-
PHP continues executing after client disconnect
-
You must check
connection_aborted()inside the loop -
Without this, you waste tokens and server resources
-
This is not optional for production systems

Thanks!