Multi-process on the Web: The Browser Process Model
While Web Applications are granted a single thread, the Main Thread, to run most of their application and UI logic, Web Browsers are absolutely not a single threaded (or single-process) environment.
In this tip, I will discuss how Web Browsers manage Web Applications and other work across processes and threads considering security and performance.
Once this remote code is loaded and presented, a user may interact with the application within the browser tab or window.
A Web Browser is a compiled C++ binary (i.e.
chrome.exe) that is installed on and launched from a user's device.
It's responsible for interfacing with a variety of sources. Some examples include:
- The device's filesystem, for loading user preferences, history, favorites, etc.
- The network, to load and deliver remote data
- The OS's input events, such as clicking and typing
- The GPU and display, to present pixels on-screen
The Web Browser must also support simultaneous instances of multiple disparate Web Applications across Browser Tabs or Windows.
Web Developers rarely interface with systems level concepts of processes and threads. For a quick refresher, consider the diagram below:
Processes are where software executes on the OS. They have dedicated access to a block of memory to use while executing to store runtime state. A process cannot access the memory utilized by another executing process on the OS.
A process may have one or more threads for programs to execute instructions on. Threads share access to the memory block dedicated to their containing process.
Since processes require a dedicated memory block, creating a new process consumes more memory than creating a new thread.
Processes can communicate with each other through Inter-Process Communication (abbreviated as IPC). Threads can communicate with each other within their containing process as well, but not directly with threads in other processes.
Communicating between processes is, in general, slower than communicating across threads within a process.
Processes can be granted various levels of access to system resources. For example, a process can be run at a Low permission level, excluding it from access to the Filesystem or Registry.
Similarly, a process can be run at a High permission level, and it is able to update sensitive parts of the host system. These processes are powerful and dangerous if exploited or compromised.
While each browser (i.e. WebKit, Chromium, Firefox) will differ in their exact implementation of their process model, they follow a similar pattern.
In general, browsers will:
- Allocate low-privilege, sandboxed WebContent Processes for running Web Applications
- Have a single Browser Process for high-privilege actions. Examples include:
- Accepting User Input
- Accessing Saved Passwords
- Updating Bookmarks and Favorites
- Have a single Network Process for interfacing with the Network and Browser Cache
- Other dedicated processes, for interfacing with Audio, Graphics / GPU, etc.
The exact amount of dedicated processes and their responsibilities / privileges will vary by browser implementation.
Note: the WebContent Process will have different names depending on the browser.
This process model is intentional; its design facilitates a reliable, performant, and secure web browser experience.
From a security perspective, restricting access to high privilege actions reduces the surface area for a malicious actor to exploit.
In the case of the WebContent Process, the code executing in this process is unknown, remote code acquired from an arbitrary third party. The only way to securely execute this code on a user's device is with the lowest possible privilege.
From a reliability perspective, by allocating separate processes for roughly* each Web Application in a Browser Tab, Web Applications are insulated from crashing each other.
For example, if there are two tabs open to different web applications, a crash / segfault in one process will not affect the other tab or browser-processes.
Furthermore, if a browser-internal process like the Network process crashes, the browser can restart it without the user noticing a crash even occurred!
Note: I said roughly* because different browsers have different algorithms for determining when to create a process. Behaviors tend to diverge among scenarios like
<iframe>elements and opening links to new tabs.
Similar to reliability, from a performance perspective, moving web applications and browser related work into their own dedicated processes helps mitigate competition for thread time.
For example, if all processes shared the same Main UI Thread, any heavy work in one web application could degrade speed and responsiveness of the entire browser!
While Web Applications and core browser internal work (like Networking) are encapsulated across process boundaries with properly scoped privileges, they frequently communicate with each other via IPC.
IPC channels allow processes to expose functionality for other processes to utilize. This maintains the benefits of being multi-process described earlier, while exposing core functionality to other processes in the system.
For example, a Web Application in a WebContent Process may request Network data by using IPC channels to notify the Network Process of the desired URL and Method. The Network Process can use an IPC channel to notify the WebContent Process when the data has returned.
For another example, the Browser Process may notify the WebContent Process that a user typed a character from their keyboard.
The WebContent Process may handle this input and dispatch a
While we've discussed the performance benefits of the browser's multi-process model, there are costs and trade-offs associated as well.
While processes provide a powerful security boundary, spinning up new processes requires additional memory allocation.
This means that the more tabs a user opens, the more processes must be created, and more memory must be consumed by the browser.
While the browser has mitigations in place to help alleviate this cost in memory constrained environments, the general trend of increased memory consumption holds.
Example mitigations the browser incorporates to help with memory utilization include:
- Draining stale tabs' memory onto disk
- Combining processes in highly memory constrained environments (like low-end Android devices)
Creating a new process isn't necessarily expensive, but for low-end devices under intense load, it will be more expensive to create a new process rather than simply a new thread in an existing process.
The browser has mitigations in place to help with this as well, including:
- Keeping a spare WebContent Process available for a New Tab or Window to use
- Parallelizing navigation requests with process creation to parallelize network and CPU activity when creating a new Tab or Window
Communicating across processes is slower than keeping communication completely localized within a single process.
Furthermore, if communication channels get clogged up, IPC messages can be delayed and degrade user experience.
In order to mitigate this, each process in the browser usually has a dedicated thread strictly for IPC messaging that's designed to be as lightweight and responsive as possible. Message formats are also optimized for minimal transfer time between processes.
This is described in detail in my next tip on examining the inner workings of a process in Chromium.
Have you ever opened up the Task Manager and noticed how many processes and how much memory Chrome is utilizing? Well, now you know why! You probably have a lot of tabs open!
Chromium utilizes the most processes out of all the browsers, in the name of security and stability.
One area to view the amount of processes you are using is in your device's Task Manager (or Activity Monitor for Mac):
For more more detailed process information, you can use the Browser Task Manager:
In this view, you can see each process for each tab, and the internal browser processes for Network and GPU. Each PID is available as well as each process's resource consumption:
Try creating and closing tabs and observe the processes in this monitor!
While Safari isn't available on Windows, I am able to run a WebKit instance (the browser engine for Safari) via Playwright
Opening multiple windows in a WebKit browser will spawn a WebProcess for each. WebKit utilizes a shared WebkitNetworkProcess and Browser process, but doesn't spawn quite as many other processes as Chromium:
In Safari on Mac, you would see something similar, though the names of the processes will look different in the Activity Monitor.
We discussed how the browser utilizes processes to improve stability, security, and performance. We discussed the trade-offs of the multi-process model and how you can observe the processes created by your browser yourself.
Understanding the browser process model and its motivation is important as it will define the constraints your web application must operate within as it executes.
Consider my next tip, where we take a closer look inside a process in Chromium.
That's all for this tip! Thanks for reading! Discover more similar tips matching Browser Internals.