How Firefox Multi-Account Containers Isolate Browser Data

This article explains the underlying architecture of Firefox's Multi-Account Containers and how it achieves strict data isolation within a single browser window. By leveraging an internal mechanism known as OriginAttributes, Firefox partitions cookies, local storage, and cache data by assigning unique context identifiers to different tabs. This allows users to maintain separate online identities and prevent cross-site tracking simultaneously without needing to open multiple browser profiles or separate windows.

The Core Architecture: OriginAttributes

Traditional web browsers isolate website data using the Same-Origin Policy, which defines an origin strictly by its scheme (protocol), host (domain), and port. Firefox expands this definition using an internal architecture called OriginAttributes.

When you open a tab inside a Multi-Account Container, Firefox assigns a specific attribute called a userContextId to that tab. For example, a "Personal" container might be assigned userContextId=1, while a "Work" container gets userContextId=2. This ID is appended to the standard origin tuple. As a result, the browser treats the exact same website as two completely different origins if they are loaded in different containers.

Firefox stores cookies in a central database, but it uses OriginAttributes to partition them into separate virtual "cookie jars."

When a website requests or sets a cookie, Firefox checks the userContextId of the active tab. A cookie set by a website in the "Personal" container (userContextId=1) is written to the database with that specific ID attached to its key. If you open the same website in an adjacent "Work" container tab (userContextId=2), Firefox queries the cookie database for entries matching both the website's domain and userContextId=2. Because the IDs do not match, the "Work" tab cannot see or access the "Personal" tab's cookies. This allows you to log into two different accounts on the same service simultaneously.

Local Storage and IndexedDB

Websites frequently use APIs like localStorage and IndexedDB to store persistent data directly on your hard drive. Firefox isolates this data by binding disk storage allocations to the OriginAttributes.

At the file system level, Firefox creates separate storage subdirectories and database keys that explicitly incorporate the userContextId. When a script runs in a container tab and attempts to read from or write to localStorage, the browser's storage manager intercepts the request and routes it exclusively to the data bucket associated with that tab's specific userContextId. Data written in one container is completely invisible to scripts running in another.

Cache Partitioning

To prevent websites from tracking you via cached files (such as images, scripts, and stylesheets), Firefox also partitions the network and memory cache using the same architecture.

Whenever the browser fetches a resource from the web, it generates a unique "cache key" to store and retrieve that file later. Firefox injects the OriginAttributes, including the userContextId, directly into this cache key. Consequently, if two different containers load the exact same file from the exact same URL, Firefox downloads and caches the file twice—once for each container. This prevents side-channel attacks, ensuring that a malicious site cannot determine your browsing history in another container by measuring how quickly a cached file loads.

Coexisting in the Same Window

Containers can exist side-by-side in the same browser window because Firefox applies the userContextId at the tab level, rather than the window level.

In Firefox's architecture, the main browser window acts merely as a visual shell. Each tab operates within its own isolated BrowsingContext (an internal representation of a document environment). The userContextId is a property of this specific BrowsingContext. When a tab makes a network request or asks for local data, it passes its individual userContextId to Firefox's underlying networking and storage processes. Because the window itself does not dictate the security context, an unlimited combination of different container tabs can run side-by-side in a single window while maintaining strict data boundaries behind the scenes.