PSA: Keep fetch keepalive/fetchLater requests alive after last-window close

115 views
Skip to first unread message

Helmut Januschka

unread,
Sep 9, 2026, 3:56:49 PM (2 days ago) Sep 9
to blink-dev

On desktop Chrome, we are enabling a change that keeps the browser process and relevant profile alive while fetch(..., {keepalive: true}) or fetchLater() requests are pending. This allows those requests to complete when the last tab in the last browser window closes, instead of being dropped:

https://issues.chromium.org/issues/408010432

The hold lasts only while requests are pending. Existing keepalive request quotas and timeouts continue to apply. Android behavior is unchanged.

Implementation: https://chromium-review.googlesource.com/c/chromium/src/+/8181986
Default-on CL: https://chromium-review.googlesource.com/c/chromium/src/+/8382658

No action is required from web developers.

Mike Taylor

unread,
Sep 9, 2026, 5:49:42 PM (2 days ago) Sep 9
to Helmut Januschka, blink-dev

Can you speak to the interop situation here? Will this only work in Chrome, or do other browsers already do this?

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
To view this discussion visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/bb27f5ec-1546-4142-bfce-ff375e3da300n%40chromium.org.

Helmut Januschka

unread,
Sep 9, 2026, 6:24:32 PM (2 days ago) Sep 9
to Mike Taylor, blink-dev

The exact last-window behavior is not currently interoperable across shipping browsers. Fetch’s keepalive semantics allow a request to outlive its initiating document, but do not require the browser application itself to remain alive during shutdown, so this is still best-effort rather than a delivery guarantee.

For WebKit, I am carrying Yoav’s implementation of fetchLater():
https://github.com/WebKit/WebKit/pull/73271

That implementation explicitly tests delivery after the last WKWebView is closed, including with an ephemeral data store. The PR is still open, so this is intended alignment rather than behavior available in Safari today. Getting it through WebKit review, EWS, and any additional splitting may take some time.

Firefox supports fetch(..., {keepalive: true}) and Mozilla has a positive standards position on fetchLater(), but fetchLater() itself is not implemented yet:
https://bugzilla.mozilla.org/show_bug.cgi?id=1936180

There is also an existing Firefox bug for beacons being dropped when the browser closes:
https://bugzilla.mozilla.org/show_bug.cgi?id=1609653

So, as far as I can tell, Chrome will initially be the only shipping browser with this explicit last-window lifetime handling. WebKit work is underway toward similar behavior; Firefox is supportive of the API, but does not currently have the equivalent implementation.

Once the WebKit work is done, I would also be happy to give the Firefox implementation a try. No promises, though, I am still a Chromium guy at heart. :)

Mike Taylor

unread,
Sep 10, 2026, 9:30:36 AM (16 hours ago) Sep 10
to Helmut Januschka, blink-dev

On 9/9/26 6:24 p.m., Helmut Januschka wrote:

The exact last-window behavior is not currently interoperable across shipping browsers. Fetch’s keepalive semantics allow a request to outlive its initiating document, but do not require the browser application itself to remain alive during shutdown, so this is still best-effort rather than a delivery guarantee.

For WebKit, I am carrying Yoav’s implementation of fetchLater():
https://github.com/WebKit/WebKit/pull/73271

That implementation explicitly tests delivery after the last WKWebView is closed, including with an ephemeral data store. The PR is still open, so this is intended alignment rather than behavior available in Safari today. Getting it through WebKit review, EWS, and any additional splitting may take some time.

Firefox supports fetch(..., {keepalive: true}) and Mozilla has a positive standards position on fetchLater(), but fetchLater() itself is not implemented yet:
https://bugzilla.mozilla.org/show_bug.cgi?id=1936180

There is also an existing Firefox bug for beacons being dropped when the browser closes:
https://bugzilla.mozilla.org/show_bug.cgi?id=1609653

So, as far as I can tell, Chrome will initially be the only shipping browser with this explicit last-window lifetime handling. WebKit work is underway toward similar behavior; Firefox is supportive of the API, but does not currently have the equivalent implementation.

Thanks Helmut! Given that there's (maybe?) alignment in 2 engines... should we try to specify this behavior somewhere (HTML? Not sure...) so we can eventually converge on something like interop? Maybe the answer is no - I'm not sure.

Once the WebKit work is done, I would also be happy to give the Firefox implementation a try. No promises, though, I am still a Chromium guy at heart. :)


Am Mi., 9. Sept. 2026 um 23:48 Uhr schrieb Mike Taylor <mike...@chromium.org>:

Can you speak to the interop situation here? Will this only work in Chrome, or do other browsers already do this?

On 9/9/26 3:56 p.m., Helmut Januschka wrote:

On desktop Chrome, we are enabling a change that keeps the browser process and relevant profile alive while fetch(..., {keepalive: true}) or fetchLater() requests are pending. This allows those requests to complete when the last tab in the last browser window closes, instead of being dropped:

https://issues.chromium.org/issues/408010432

The hold lasts only while requests are pending. Existing keepalive request quotas and timeouts continue to apply. Android behavior is unchanged.

Implementation: https://chromium-review.googlesource.com/c/chromium/src/+/8181986
Default-on CL: https://chromium-review.googlesource.com/c/chromium/src/+/8382658

No action is required from web developers.

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
To view this discussion visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/bb27f5ec-1546-4142-bfce-ff375e3da300n%40chromium.org.
--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

PhistucK

unread,
Sep 10, 2026, 1:27:23 PM (12 hours ago) Sep 10
to Mike Taylor, Helmut Januschka, blink-dev
For some reason, I thought Mike was asking about the other Chromium-based browsers, but that was not the case. :) So I am asking - is this something that other Chromium-based browsers will get for free/they need to be aware of to enable (I think some of them are only content embedders rather than full-blown Chromium)?


PhistucK


Marshall Greenblatt

unread,
Sep 10, 2026, 1:43:14 PM (12 hours ago) Sep 10
to PhistucK, Mike Taylor, Helmut Januschka, blink-dev
From looking at the code, there appears to be no fixed overall
shutdown deadline with this change. The normal case is 30 seconds
after the renderer-side loader disconnects, but retry-enabled requests
can keep it alive much longer. This is likely unexpected behavior for
Chromium-based applications that require deterministic shutdown
behavior (restarting to install updates, etc).
> To view this discussion visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CABc02_JKL5rZuTfg2L-NOtOS5Tza1V0Z%2B8qreEZ_%2Bsz0smhCGA%40mail.gmail.com.

Helmut Januschka

unread,
Sep 10, 2026, 5:32:10 PM (8 hours ago) Sep 10
to Marshall Greenblatt, PhistucK, Mike Taylor, blink-dev
@mike: ack, guess its worth specifying. My first guess is that it belongs in Fetch, around keepalive request termination, rather than HTML. It would need to describe best-effort behavior during an orderly last-window close, while excluding explicit quit, crashes, and OS termination. Testing this interoperably may require an external WebDriver/server harness rather than a normal in-browser WPT. I will file a Fetch issue to start that discussion.

@PhistucK: content embedders do not get the process-lifetime behavior automatically. Content invokes the new ContentBrowserClient callbacks, but their default implementations are no-ops. The actual browser/profile holds are implemented in ChromeContentBrowserClient, using Chrome’s ScopedKeepAlive and ScopedProfileKeepAlive. Full Chromium forks carrying the Chrome layer will likely inherit it, content-only embedders would need their own lifecycle implementation.

@Marshall: The new hold currently follows the full KeepAliveURLLoader lifetime. The usual detached-loader limit is 30 seconds, but retry-enabled requests can extend that to their retry age, currently bounded at up to one day. Explicit user-requested quit bypasses normal keep-alives, but last-window shutdown and restart eligibility can still be delayed much longer than expected.


Reply all
Reply to author
Forward
0 new messages