Skip to content

perf(response): Flush requests early to clients#57991

Draft
nickvergessen wants to merge 1 commit intomasterfrom
perf/noid/flush-response-early
Draft

perf(response): Flush requests early to clients#57991
nickvergessen wants to merge 1 commit intomasterfrom
perf/noid/flush-response-early

Conversation

@nickvergessen
Copy link
Member

If not, the response will wait for async actions, e.g. HTTP requests from IClientService, to be finished before returning. This is not desired in many cases with e.g. with notifications.

Checklist

If not, the response will wait for async actions, e.g. HTTP requests from
IClientService, to be finished before returning. This is not desired in
many cases with e.g. with notifications.

Signed-off-by: Joas Schilling <coding@schilljs.com>
@nickvergessen nickvergessen added this to the Nextcloud 34 milestone Feb 2, 2026
@nickvergessen nickvergessen self-assigned this Feb 2, 2026
@nickvergessen nickvergessen requested a review from a team as a code owner February 2, 2026 10:45
@nickvergessen nickvergessen requested review from ArtificialOwl, icewind1991, leftybournes and salmart-dev and removed request for a team February 2, 2026 10:45
@nickvergessen nickvergessen marked this pull request as draft February 2, 2026 10:45
Copy link
Collaborator

@Altahrim Altahrim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small comments, but I like the idea :)

There is also fastcgi_finish_request for FPM, it may worth a try as it also kills the connection

}

if ($response->getFlushEarly()) {
ob_flush();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ob_flush();
while (ob_get_level() > 0) {
ob_end_flush();
}

I would go with this snippet to ensure all is flushed

Comment on lines +422 to +424
public function setFlushEarly(bool $flushEarly): void {
$this->flushEarly = $flushEarly;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the default is to flush early, maybe this is more explicit:

Suggested change
public function setFlushEarly(bool $flushEarly): void {
$this->flushEarly = $flushEarly;
}
public function dontFlushEarly(): void {
$this->flushEarly = false;
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the default is to flush early

That's TBD. It could be problematic in some cases, but in theory it could break things unintentionally, or at least be a behaviour change

@nickvergessen
Copy link
Member Author

From PHP comments a small reminder:

There are some pitfalls you should be aware of when using this function.
...
Another important thing is session handling. Sessions are locked as long as they're active (see the documentation for session_write_close()). This means subsequent requests will block until the session is closed.

You should therefore call session_write_close() as soon as possible (even before fastcgi_finish_request()) to allow subsequent requests and a good user experience.

We should ensure session was closed before.

@Altahrim
Copy link
Collaborator

Good remark about session.

I think one of the best scenario would be:

  • open session
  • generate HTTP headers
  • flush
  • generate <head>
  • close_session
  • flush // At this point, browser can already load all related resources (CSS, JS…)
  • generate content (all info about users have already been loaded)
  • flush / end-request
  • do post query stuff not needed by client

I didn't check what is possible. It may be possible to reduce session access even more

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants