How Firefox Uses SQLite for History, Bookmarks, and Cookies

This article explores how the Mozilla Firefox web browser utilizes SQLite, a lightweight and serverless relational database engine, to manage and store essential user data locally. Specifically, it examines the architecture of the places.sqlite and cookies.sqlite database files, detailing how Firefox organizes browsing history, bookmarks, and website cookies for fast retrieval, data integrity, and reliable storage.

Why Firefox Uses SQLite

Firefox relies on SQLite because it is an embedded database engine that writes directly to ordinary disk files without requiring a separate server process. This allows Firefox to store complex, relational data inside the user's local profile directory. Because SQLite is ACID-compliant (Atomic, Consistent, Isolated, Durable), it ensures that user data is not easily corrupted if the browser or operating system crashes unexpectedly.

Storing History and Bookmarks: places.sqlite

In Firefox, the system responsible for managing both browsing history and bookmarks is called "Places." Instead of separating history and bookmarks into different files, Firefox combines them into a single SQLite database named places.sqlite. This unified approach prevents data duplication, as a bookmarked URL and a visited URL often point to the exact same web address.

The places.sqlite file relies on three primary tables to organize this information:

  • moz_places: This is the central table of the database. Every unique URL the user visits or bookmarks is assigned a single row here. Columns in this table store the URL itself, the page title, a unique identifier (GUID), the total visit count, and a "frecency" score. Frecency is a custom Firefox metric combining frequency and recency to predict which links should appear first in the address bar's autocomplete drop-down.
  • moz_historyvisits: While moz_places stores the URLs, moz_historyvisits logs the actual events of visiting those URLs. Each row represents a single visit and links back to the moz_places table via a place_id. It records the exact timestamp of the visit, the referring URL (where the user came from), and the transition type (e.g., whether the user typed the URL, clicked a link, or used a bookmark).
  • moz_bookmarks: This table stores the hierarchy and metadata of the user's bookmarks. It uses a tree structure where rows can represent folders, separators, or actual bookmarks. If a row is a bookmark, it contains a foreign key (fk) that points directly to the corresponding URL in the moz_places table. It also stores user-defined titles, creation dates, and last-modified timestamps.

Storing Website Cookies: cookies.sqlite

Cookies—small pieces of data websites use to remember login states, preferences, and tracking information—are isolated in their own database file named cookies.sqlite. Separating cookies from history ensures that heavy cookie read/write operations on complex websites do not slow down address bar searches or history logging.

The core of this database is a single table named moz_cookies. Each row in this table represents an individual cookie and includes the following data columns:

  • host and baseDomain: Identifies the specific website or domain that owns the cookie.
  • name and value: The actual data payload of the cookie (such as a session ID).
  • path: The specific URL path on the host where the cookie is valid.
  • expiry and lastAccessed: Timestamps that tell Firefox when to automatically delete the cookie and when it was last used.
  • Security Flags: Columns such as isSecure (requires HTTPS), isHttpOnly (prevents client-side scripts from accessing the cookie), and sameSite (controls cross-site sending of the cookie) enforce web security standards directly at the database level.

Database Performance and Concurrency

Reading from and writing to a hard drive is one of the slowest operations a browser performs. To prevent the browser interface from freezing every time a user clicks a link or receives a cookie, Firefox implements specific SQLite optimizations:

  1. Write-Ahead Logging (WAL): Firefox configures its SQLite databases to use WAL mode. Instead of writing changes directly to the main .sqlite file, Firefox quickly appends changes to a temporary -wal file. This allows the browser to read from the database and write to it simultaneously without locking up the user interface. Periodically, Firefox merges the -wal file back into the main database.
  2. In-Memory Caching: For cookies.sqlite, Firefox often loads active cookies into the computer's RAM during a browsing session. It processes changes in memory and writes them back to the SQLite database asynchronously in the background.
  3. Idle Maintenance (Vacuuming): When history or cookies are deleted, SQLite does not immediately shrink the file size; it simply marks that space as reusable. When the computer is idle, Firefox runs a SQLite VACUUM command to rebuild the database files, defragment the data, and reclaim disk space.