Firefox uses a multi-process architecture — different parts of the browser run in separate OS processes. This improves security (each process can be sandboxed) and stability (one crashed tab doesn't take down the browser). Here's what that means for developers and how to see it in action.
The Process Model
Firefox's processes:
- Parent process (browser chrome): the Firefox UI itself — toolbar, tabs, menus
- Content processes: web page rendering (one per site/group of sites)
- GPU process: hardware-accelerated graphics compositing
- Network process (recent): handles all network requests
- Extension process: WebExtensions run isolated from pages
- RDD (Remote Data Decoder): media decoding (video, audio)
- Utility processes: various helpers
Fission (Site Isolation)
Fission is Firefox's full site isolation — each site gets its own content process:
Tab 1 (example.com) → Process A
Tab 2 (trusted.com) → Process B
Tab 3 (example.com) → Process A (reused)
iframe (other-site.com) inside Tab 1 → Process C (cross-origin iframe!)
Without site isolation, a cross-origin <iframe> could run in the same process as the parent, potentially using Spectre-style attacks to read parent memory.
With Fission: cross-origin iframes run in a separate process with a separate memory space. Exploiting one page cannot access another origin's data.
about:processes
Open Firefox → about:processes to see all running processes:
- Process type (content, extension, RDD, etc.)
- Memory usage per process
- Which sites are in each content process
- CPU time usage
This is useful for diagnosing:
- High memory usage: which tab or site is leaking memory?
- CPU spikes: which process is using the most CPU?
- Extension issues: extension processes shown separately
The DevTools Connection
Firefox DevTools connects to the content process of the page you're inspecting. When using the Debugger:
- JavaScript execution pauses in the content process
- The parent process (Firefox UI) keeps running
- Other tabs continue to run
This is why you can still use Firefox's toolbar while paused in the Debugger.
Remote Debugging
Because processes communicate via IPC (Inter-Process Communication), you can debug from a different machine:
# Start Firefox with remote debugging enabled
firefox -start-debugger-server 6080
# Or in about:config:
# devtools.debugger.remote-enabled = true
# devtools.debugger.remote-port = 6080
Connect from another Firefox:
- DevTools → Remote Debugging → Connect → localhost:6080
This is used for debugging Firefox on Android, Firefox OS, and headless Firefox instances.
Content Security Implications
Separate processes mean:
- Privilege separation: content processes run with limited OS privileges
- Sandbox: content processes can't write to the filesystem directly
- IPC boundary: all communication goes through a verified IPC channel
If an attacker exploits a web page's JavaScript engine (memory corruption, etc.), they're still constrained to the content process sandbox. They need a second privilege escalation exploit to escape to the host OS.
Debugging Extension Issues
Extensions run in their own process, separate from content processes:
- Open DevTools (F12) → no extension code visible here
- For extension background scripts:
about:debugging#/runtime/this-firefox→ Inspect - This opens a DevTools connected to the extension process
Extension content scripts run in content processes (they're injected into pages), but extension background scripts and options pages run in the extension process.
Memory Measurement Per Process
// In the console, check memory usage
performance.memory // Chrome only — not Firefox (privacy reasons)
// Firefox equivalent: about:memory or about:processes
// In JS: MemoryReporter API (privileged only)
For web page memory profiling in Firefox:
- DevTools → Memory → Take Snapshot
- Shows heap allocations, object counts, dominator tree
Impact on Extension Performance
Multi-process means message passing has overhead:
// Content script → background script: async IPC
// This is slower than same-process function calls
const result = await browser.runtime.sendMessage({ type: 'getData' });
// vs. calling a local function (fast)
For performance-sensitive extensions:
- Do computation in content scripts (in the content process) when possible
- Only send data to background script when needed (IPC overhead)
- Use
browser.storage.local(IPC) vs in-memory variables (no IPC) for infrequent-changing data
WebExtension Process Isolation Details
Extensions with content_scripts have their code injected into content processes. But they can't access the page's JavaScript variables directly — the Xray wrapper mechanism wraps page objects for security.
This prevents a malicious page from overriding Array.prototype and causing the extension to behave unexpectedly.
The trade-off: extensions can't directly call page functions; they must use window.wrappedJSObject.someFunction() to deliberately access the unwrapped page object.
Top comments (0)