How Balrog Delivers Differential MAR Updates to Firefox

This article provides a complete overview of how Mozilla's Balrog update server infrastructure delivers differential Mozilla Archive (MAR) patches to the Firefox web browser. It covers the entire lifecycle of an update, starting from the initial client request, moving through Balrog's internal rule evaluation and XML manifest generation, and concluding with how Firefox downloads and applies the binary patch to update the browser efficiently.

Understanding MAR Files and Differential Updates

A MAR (Mozilla Archive) file is the proprietary archive format used by Mozilla to package updates for Firefox. To save bandwidth and speed up the update process, Mozilla uses two types of MAR files:

  • Complete MAR: Contains the entire Firefox application. It is used as a fallback or when a user is updating from a very old version.
  • Partial (Differential) MAR: Contains only the binary differences between the user's current version of Firefox and the new target version. These differences are generated using a modified version of the bsdiff tool called mbsdiff.

Balrog is the system responsible for telling Firefox which MAR file to download. Crucially, Balrog does not host the heavy MAR files itself; instead, it acts as a decision engine that directs Firefox to the correct files hosted on Content Delivery Networks (CDNs).

Step 1: The Client Update Request

The update process begins when Firefox checks for updates in the background. The browser sends an HTTPS GET request to the Balrog server.

Rather than sending query parameters, Firefox encodes its current system state directly into the URL path. This path includes:

  • Product: (e.g., Firefox)
  • Version: (e.g., 120.0)
  • Build ID: A timestamp representing the exact build the user is running.
  • Build Target: The operating system and CPU architecture (e.g., WINNT_x86_64-msvc).
  • Locale: The language pack in use (e.g., en-US).
  • Channel: The release track (e.g., release, beta, nightly).
  • OS Version and System Capabilities: Details about the host machine to ensure compatibility.

Step 2: Balrog Rule Evaluation

When Balrog receives the GET request, it extracts the client parameters from the URL and compares them against its internal database of Rules.

In Balrog, a Rule is a set of criteria (such as channel, version, or operating system) that maps a client to a specific Release. A Release in Balrog is not the software itself, but a massive JSON object (often called a "blob") that contains metadata about a specific version of Firefox, including file URLs, cryptographic hashes, and file sizes.

During this step, Balrog performs the following actions:

  1. Matches Rules: It finds the rule that matches the client's channel and system configuration.
  2. Checks Rollout Rates: If a new Firefox update is set to a 25% rollout, Balrog uses a consistent hashing algorithm or random number provided by the client to determine if this specific request falls within that 25%.
  3. Identifies the Target Release: Once the correct rule is applied, Balrog loads the corresponding Release JSON blob.

Step 3: Finding the Differential Patch

With the target Release JSON loaded, Balrog must determine if a differential (partial) MAR is available for the specific client.

Differential patches are strictly tied to the Build ID and Locale. A partial MAR only works if it is applied to the exact binary files it was generated from. Balrog looks inside the Release JSON to see if a partial update entry exists that matches the client's current Build ID.

  • If the client is updating from the immediately preceding version, a partial MAR entry will almost certainly exist.
  • If the client is updating from a version that is several months old, a partial MAR will not exist in the JSON, and Balrog will prepare to serve only the complete MAR.

Step 4: Generating the XML Update Manifest

Balrog does not return JSON to Firefox; it dynamically constructs and returns a lightweight XML document known as the update manifest.

If a matching differential update was found in Step 3, the XML manifest will include two <patch> elements: one for the partial update and one for the complete update. Each element contains:

  • Type: Indicates whether it is a partial or complete MAR.
  • URL: The direct link to the MAR file on Mozilla’s CDN.
  • Hash Function and Value: Typically a SHA-512 hash used to verify the file was not corrupted during transit.
  • Size: The exact size of the MAR file in bytes.

If no updates are available, or if the client is already on the latest version, Balrog returns an empty XML manifest.

Step 5: Downloading and Applying the Patch

Once Firefox receives the XML manifest from Balrog, Balrog's job is done. The browser takes over to complete the update:

  1. Prioritizing the Differential Patch: Firefox reads the XML and always prioritizes the partial patch to save bandwidth.
  2. Downloading: Firefox downloads the differential MAR from the CDN URL provided in the XML.
  3. Verification: Firefox verifies the downloaded file's size and SHA-512 hash against the values provided by Balrog. It also verifies the embedded cryptographic signature inside the MAR file to ensure it was signed by Mozilla.
  4. Patching: When the browser restarts, a standalone executable (the updater binary) extracts the MAR file. It reads the internal manifest instructions, takes the binary diff files, and merges them with the existing Firefox installation files to create the new version's binaries.
  5. Fallback Mechanism: If the updater detects that a local file was modified or corrupted, the differential patch will fail checksum verification. Firefox will abort the partial update, automatically fall back to the complete MAR URL provided in Balrog's original XML manifest, download the full browser archive, and overwrite the installation cleanly.