Tab Unloading in Firefox 93

Starting with Firefox 93, Firefox will monitor available system memory and, should it ever become so critically low that a crash is imminent, Firefox will respond by unloading memory-heavy but not actively used tabs. This feature is currently enabled on Windows and will be deployed later for macOS and Linux as well. When a tab is unloaded, the tab remains in the tab bar and will be automatically reloaded when it is next selected. The tab’s scroll position and form data are restored just like when the browser is restarted with the restore previous windows browser option.

On Windows, out-of-memory (OOM) situations are responsible for a significant number of the browser and content process crashes reported by our users. Unloading tabs allows Firefox to save memory leading to fewer crashes and avoids the associated interruption in using the browser.

We believe this may especially benefit people who are doing heavy browsing work with many tabs on resource-constrained machines. Or perhaps those users simply trying to play a memory-intensive game or using a website that goes a little crazy. And of course, there are the tab hoarders, (no judgement here). Firefox is now better at surviving these situations.

We have experimented with tab unloading on Windows in the past, but a problem we could not get past was that finding a balance between decreasing the browser’s memory usage and annoying the user because there’s a slight delay as the tab gets reloaded, is a rather difficult exercise, and we never got satisfactory results.

We have now approached the problem again by refining our low-memory detection and tab selection algorithm and narrowing the action to the case where we are sure we’re providing a user benefit: if the browser is about to crash. Recently we have been conducting an experiment on our Nightly channel to monitor how tab unloading affects browser use and the number of crashes our users encounter. We’ve seen encouraging results with that experiment. We’ll continue to monitor the results as the feature ships in Firefox 93.

With our experiment on the Nightly channel, we hoped to see a decrease in the number of OOM crashes hit by our users. However, after the month-long experiment, we found an overall significant decrease in browser crashes and content process crashes. Of those remaining crashes, we saw an increase in OOM crashes. Most encouragingly, people who had tab unloading enabled were able to use the browser for longer periods of time. We also found that average memory usage of the browser increased.

The latter may seem very counter-intuitive, but is easily explained by survivorship bias. Much like in the archetypal example of the Allied WWII bombers with bullet holes, browser sessions that had such high memory usage would have crashed and burned in the past, but are now able to survive by unloading tabs just before hitting the critical threshold.

The increase in OOM crashes, also very counter-intuitive, is harder to explain. Before tab unloading was introduced, Firefox already responded to Windows memory-pressure by triggering an internal memory-pressure event, allowing subsystems to reduce their memory use. With tab unloading, this event is fired after all possible unloadable tabs have been unloaded.

This may account for the difference. Another hypothesis is that it’s possible our tab unloading sometimes kicks in a fraction too late and finds the tabs in a state where they can’t even be safely unloaded any more.

For example, unloading a tab requires a garbage collection pass over its JavaScript heap. This needs some additional temporary storage that is not available, leading to the tab crashing instead of being unloaded but still saving the entire browser from going down.

We’re working on improving our understanding of this problem and the relevant heuristics. But given the clearly improved outcomes for users, we felt there was no point in holding back the feature.

When does Firefox automatically unload tabs?

When system memory is critically low, Firefox will begin automatically unloading tabs. Unloading tabs could disturb users’ browsing sessions so the approach aims to unload tabs only when necessary to avoid crashes. On Windows, Firefox gets a notification from the operating system (setup using CreateMemoryResourceNotification) indicating that the available physical memory is running low. The threshold for low physical memory is not documented, but appears to be around 6%. Once that occurs, Firefox starts periodically checking the commit space (MEMORYSTATUSEX.ullAvailPageFile).

When the commit space reaches a low-memory threshold, which is defined with the preference “browser.low_commit_space_threshold_mb”, Firefox will unload one tab, or if there are no unloadable tabs, trigger the Firefox-internal memory-pressure warning allowing subsystems in the browser to reduce their memory use. The browser then waits for a short period of time before checking commit space again and then repeating this process until available commit space is above the threshold.

We found the checks on commit space to be essential for predicting when a real out-of-memory situation is happening. As long as there is still swap AND physical memory available, there is no problem. If we run out of physical memory and there is swap, performance will crater due to paging, but we won’t crash.

On Windows, allocations fail and applications will crash if there is low commit space in the system even though there is physical memory available because Windows does not overcommit memory and can refuse to allocate virtual memory to the process in this case. In other words, unlike Linux, Windows always requires commit space to allocate memory.

How do we end up in this situation? If some applications allocate memory but do not touch it, Windows does not assign the physical memory to such untouched memory. We have observed graphics drivers doing this, leading to low swap space when plenty of physical memory is available.

In addition, crash data we collected indicated that a surprising number of users with beefy machines were in this situation, some perhaps thinking that because they had a lot of memory in their machine, the Windows swap could be reduced to the bare minimum. You can see why this is not a good idea!

How does Firefox choose which tabs to unload first?

Ideally, only tabs that are no longer needed will be unloaded and the user will eventually restart the browser or close unloaded tabs before ever reloading them. A natural metric is to consider when the user has last used a tab. Firefox unloads tabs in least-recently-used order.

Tabs playing sound, using picture-in-picture, pinned tabs, or tabs using WebRTC (which is used for video and audio conferencing sites) are weighted more heavily so they are less likely to be unloaded. Tabs in the foreground are never unloaded. We plan to do more experiments and continue to tune the algorithm, aiming to reduce crashes while maintaining performance and being unobtrusive to the user.

about:unloads

For diagnostic and testing purposes, a new page about:unloads has been added to display the tabs in their unload-priority-order and to manually trigger tab unloading. This feature is currently in beta and will ship with Firefox 94.

Screenshot of the about:unloads page in beta planned for Firefox 94.

Screenshot of the about:unloads page in beta planned for Firefox 94.

Browser Extensions

Some browser extensions already offer users the ability to unload tabs. We expect these extensions to interoperate with automatic tab unloading as they use the same underlying tabs.discard() API. Although it may change in the future, today automatic tab unloading only occurs when system memory is critically low, which is a low-level system metric that is not exposed by the WebExtensions API. (Note: an extension could use the native messaging support in the WebExtensions API to accomplish this with a separate application.) Users will still be able to benefit from tab unloading extensions and those extensions may offer more control over when tabs are unloaded, or deploy more aggressive heuristics to save more memory.

Let us know how it works for you by leaving feedback on ideas.mozilla.org or reporting a bug. For support, visit support.mozilla.org.Firefox crash reporting and telemetry adheres to our data privacy principles. See the Mozilla Privacy Policy for more information.

Thanks to Gian-Carlo Pascutto, Toshihito Kikuchi, Gabriele Svelto, Neil Deakin, Kris Wright, and Chris Peterson, for their contributions to this blog post and their work on developing tab unloading in Firefox.

About Haik Aftandilian

More articles by Haik Aftandilian…


19 comments

  1. Uristqwerty

    Some thoughts as a user with frequent long-lived tabs:

    – Many sites show a snapshot of actively-changing content when you open the page, so being able to restore using the original set of responses for that tab would be a valuable option (consider: opening the front page of a site multiple times, 6 hours apart. If they all reload as clones of each other, that is a loss of browsing state). I don’t know if this is how it works already, but if not, it’s something to consider.

    – Often, user interaction changes page state in a way that won’t be automatically recovered (collapsing/expanding replies, for example), so a heuristic that prioritizes unloading tabs with no user interaction time or no DOM changes would also help preserve non-recoverable state.

    – If nothing else, an extension API for deciding which tabs should be unloaded first could eventually allow user choices like “unload youtube even in a foreground tab; it’s both heavy and preserves its own state well enough”, or “prefer not to unload reddit, it is decidedly *not* idempotent”, or a toolbar toggle for “I care about this particular tab instance; keep it loaded at all costs”. Or better yet, “don’t unload tabs in the container named ‘Important'”, re-using a UI the user might be familiar with rather than requiring them to learn something new. Leaving it to extensions would allow them cater to different levels of technical expertise, rather than a single UI that settles on a compromise.

    Overall, sounds like a nice feature for many users, though.

    October 5th, 2021 at 12:53

  2. Bela

    The #1 thing I want in this regard is for ‘open in background tab’ to create tabs which are *already unloaded*. i.e. just the notion of a tab open to the specified URL. I’m in the habit of opening a site full of articles, then ctrl-clicking a dozen of them into the background. This causes a storm of activity which is completely unnecessary as I’m not going to look at any of those tabs for a while.

    Note: NOT asking for slowed down loading of background tabs. I don’t want the resources consumed slowly, I want them consumed not at all. Until I invoke a tab by*switching* to it.

    Likewise, don’t load any tabs other than the focused one, when restarting from a saved session.

    Obviously this has to be an option, as many users would hate it. Heavy users of tabs would love it.

    October 5th, 2021 at 18:50

    1. Haik Aftandilian

      @Bela, there is an extension available which opens new tabs in the unloaded state so that may be worth giving a try. Take a look at Lazy Tabs:

      https://addons.mozilla.org/en-US/firefox/addon/lazy-tabs/

      I tested the latest version, last updated Jul 3, 2021, and it works as advertised. It’s a small extension and easy to read through the entire source code to see what it does.

      October 5th, 2021 at 20:41

      1. Reik Red

        Just wanted to voice my support for “just-in-time” tab loading, as described by Bela above. IMPORTANT: favicon must be loaded, though. Favicons are such a big visual navigational help.

        (Around firefox 60(??), I lost all my favicons because of some new security policy implemented in a new version of firefox, and that caused massive trouble having to revisit 1000s of tabs to try and get the favicons back on display. Ran out of memory, too! But I digress.)

        Just-in-time tab load could be a user-selectable feature. When you switch to a tab, maybe the tab could display “Just-in-time loading in progress” until the content has been fetched/rendered) from network *r cache if no network).

        I just tried the above linked lazy tabs app, and it does not at all do what I want. You have to go in and pause (unload?) each tab manually. very different from Just-in-time.

        October 7th, 2021 at 13:17

    2. moose

      Funny, because I want the opposite. I want to load a great pile of tabs, then have them available (and /not/ unloaded) when I am away from the Internet (e.g. on a plane…).

      Similarly, I never want to have to reconnect to the Internet because /Firefox/ (as opposed to a particular page) decided to reload or whatever one of my tabs. (Particularly annoying on my mobile device where I have enough RAM to not to have to worry, but I don’t want to have to turn on mobile data or whatever. Or I want to be able to read something when I cannot connect to the Internet (e.g. on a plane). Having to reload/refresh my tabs loses context, and potentially results in a page not existing any more.)

      October 5th, 2021 at 23:52

      1. Gian-Carlo Pascutto

        The point that the article makes (but apparently doesn’t manage to get across very well :-/) is that we trigger this when we’re about to crash because we ran out of memory. So the choice is between trying to pick one tab to unload, or crashing – which unloads all tabs. So tab unloading helps rather than hurts your scenario.

        October 7th, 2021 at 05:56

    3. Reik Red

      Just wanted to voice my support for “just-in-time” tab loading, as described by Bela above. IMPORTANT: favicon must be loaded, though. Favicons are such a big visual navigational help.

      (Around firefox 60(??), I lost all my favicons because of some new security policy implemented in a new version of firefox, and that caused massive trouble having to revisit 1000s of tabs to try and get the favicons back on display. Ran out of memory, too! But I digress.)

      Just-in-time tab load could be a user-selectable feature. When you switch to a tab, maybe the tab could display “Just-in-time loading in progress” until the content has been fetched/rendered) from network *r cache if no network).

      I just tried the above linked lazy tabs app, and it does not at all do
      what I want. You have to go in and pause (unload?) each tab
      manually. very different from Just-in-time.

      October 7th, 2021 at 13:24

  3. Cookie Engineer

    This is great!

    A little comment on the tab hoarding problem: Can we get a local search page that is able to search the html/text content of bookmarks?

    People usually are afraid of losing tabs, because the omnibar is useless for finding content in bookmarks. A dedicated search page (about:search?) that uses a local index of bookmark urls, tags, and more important – their contents – would help _so_ much in rediscovering a reading list or tabs you’ve bookmarked before already.

    Maybe automatically archive the reader view of a bookmark and use that as a baseline for search?

    October 5th, 2021 at 20:56

    1. zakius

      there used to be easily accessible library (ctrl+shift+b) but that was too simple

      October 6th, 2021 at 03:23

    2. Reik Red

      I like the idea of “full-page (regexp) text search in all open tabs”, whether local or otherwise. Perhaps local is better — I might not like to tell google 1000s of tabs I have open so that it can limit a search to those, even if google supported such a concept.

      On tab hoarding in general: One reason I hoard tabs is because searching in bookmarks or history and such does not give me the context of neighboring tabs that I looked up that are related to some specific tab I have bookmarked, even if all the tabs were bookmarked (hope that sentence makes sense).

      October 7th, 2021 at 13:01

  4. zakius

    “unloading” definitely should just offload the current state to non-volatile memory, there are way too many cases when reloading from network won’t work at all, especially for these resource heavy websites
    and there’s always the edge case of returning to the unloaded tab when your connection is down

    October 6th, 2021 at 02:38

  5. martixy

    > a surprising number of users with beefy machines were in this situation, some perhaps thinking that because they had a lot of memory in their machine, the Windows swap could be reduced to the bare minimum.

    This is not surprising. Virtualized memory is a tricky concept to grasp.

    It is worth noting that windows can set a min and max page file size. That way you can have the benefit of a small page file and room for fictitious commit. Tho I do wish windows would allow overcommit.

    October 6th, 2021 at 03:08

  6. Janio Sarmento

    Great, but I think Firefox should modernize their JS engine rather than solving issues that are not that important.

    I’m using Firefox less each day because some tools I use (Proxmox, e.g.) do not work in it because of the lack of support to modern JS features. Frustrating.

    October 6th, 2021 at 03:32

  7. Dan

    Web browsers should stop becoming operating systems, it directly goes against the KISS philosophy the best technologies were built on in the past, such as Unix.
    We need a new model for running internet-era apps that doesn’t involve terrible technologies such as the DOM, JavaScript, and using a markup language such as HTML and CSS to build applications. Today’s web applications are slower and feel much less responsive than Windows 3.11 era applications.

    October 6th, 2021 at 09:53

  8. Dmitry

    So, how can I disable this option?

    I’ll explain my point. I actively use the Internet and a computer. I often have many tabs and programs open. However, I independently monitor the free memory in the task manager and can independently close tabs or programs that consume memory, but are no longer needed. However, I need the tabs not to be unloaded from memory. I don’t want to be in a situation where I won’t receive notifications from mail because the mail tab has been unloaded. I don’t want to lose the text that I entered an hour ago in the form of the site. I don’t want to lose the notification from my messenger. Even if my computer goes to SWAP and starts to dump in pagefile. I won’t experience any problems with this, because I have an SSD. But it’s important to me that my tabs are always up to date.
    So how can I disable this damn option?

    October 7th, 2021 at 00:37

    1. Haik Aftandilian

      Firefox tries to only unload a tab when an out-of-memory crash is imminent. Heavy swapping should not trigger a tab unload. It’s when swap file space is almost exhausted that this is more likely to occur. However, you can disable tab unloading by setting “browser.tabs.unloadOnLowMemory” to false in about:config. The way you disable it could change in the future. If you leave it on and encounter a tab being unloaded when you believe there was no out-of-memory crash risk, please let us know about it by filing a bug on https://bugzilla.mozilla.org

      October 7th, 2021 at 14:09

  9. Reik Red

    (accidentally submitted half-written comment above, pls delete that one, and also this comment if you want)

    Tab-unloading is a wonderful idea. I am eagerly awaiting the linux version getting tab-unloading enabled.

    Some additional features would be useful, though.

    1. set a user-defined memory limit individually for each firefox instance, via about:config. When reaching limit, invoke tab unloading

    2. same as 1, but with a global limit on all firefox instances (profiles) running for a user or for all users
    (not as important).

    I also liked Bela’s comment above about not loading tab contents at all unless they are being displayed (selected, visibly open) in a window. But still show the favicon in the tab, so easier to find relevant tabs. I have not tried “lazy tabs” for a long time. Some previous (and possibly unrelated) incarnations of lazy tabs used to be not so great. After the big firefox speedup about 2 years ago I was less concerned about loading time or browser restart time in general, but nowadays I have such high memory usage even right after restart that something built-in like lazy tabs is very relevant in addition to tab-unload.

    Just to give you an idea of my memory usage situation, here is an instance/profile reikHH with about 12GB for 1620 tabs, one of my worst profiles in terms of memory used per tab :)

    FirefoxHH -P reikHH
    mapped: 12395992K writeable/private: 5793320K shared: 839428K

    The above memory footprint is from a pmap script I found (linux).

    October 7th, 2021 at 12:46

    1. Reik Red

      Clarification: I started using the term “just-in-time tab loading” further up in the comments now, rather than calling it “lazy tabs”. Load-on-demand might be another term to describe it.

      October 7th, 2021 at 13:20

  10. Joel Crumpler

    Wonderful

    November 4th, 2021 at 07:38

Comments are closed for this article.