BrowsersCoreWeb history and downloads

Chromium History database

SQLite store of visited URLs, individual visits with transition types, downloads and omnibox search terms in Chrome, Edge and other Chromium browsers.

01Location

  • <User Data>/<Profile>/History
  • %LOCALAPPDATA%\Google\Chrome\User Data\Default\History
  • ~/Library/Application Support/Google/Chrome/Default/History
  • ~/.config/google-chrome/Default/History

02Questions it answers

  • Which URLs were visited, when, and how often?
  • Was a page reached by typing, a link, a bookmark, a form submission or a reload?
  • Which files were downloaded, from which URL chain and referrer, and where were they saved?
  • Which search terms were entered through the address bar?
  • Did a visit originate on another device synced to the same account?

03Format and versions

FormatSQLite 3 database written through Chromium's //sql layer. Times are 64-bit integers of microseconds since 1601-01-01 UTC (base::Time serialised with BindTime).
Applies toChromium main branch as read on 2026-10-14. Columns were added over many schema versions; older databases can lack newer columns such as opener_visit or the originator_* fields.

04Key fields

FieldWhat it tells you
urls (id, url, title, visit_count, typed_count, last_visit_time, hidden)One row per URL with aggregate counters; visits.url points to urls.id.
visits (id, url, visit_time, from_visit, transition, visit_duration)One row per visit. from_visit links to the referring visit; transition holds the page transition type.
visits.transitionCore type in the low byte (mask 0xFF): 0 LINK, 1 TYPED, 2 AUTO_BOOKMARK, 3 AUTO_SUBFRAME, 4 MANUAL_SUBFRAME, 5 GENERATED, 6 AUTO_TOPLEVEL, 7 FORM_SUBMIT, 8 RELOAD, 9 KEYWORD, 10 KEYWORD_GENERATED; upper bits are qualifiers such as FROM_ADDRESS_BAR or redirect flags.
visits.originator_cache_guid / originator_visit_idFor visits synced from another machine: the originating client's identifier and its local visit id. Local visits write an empty string and 0.
downloads (guid, current_path, target_path, start_time, end_time, received_bytes, total_bytes, state, danger_type, opened, last_access_time, referrer, tab_url, mime_type)One row per download. state: 0 in progress, 1 complete, 2 cancelled, 4 interrupted. opened is 1 if the file was ever opened from the browser.
downloads_url_chains (id, chain_index, url)Redirect chain for a download: chain_index 0 is the initial target and the highest index the final URL after redirects.
keyword_search_terms (keyword_id, url_id, term, normalized_term)Search terms entered for a search engine keyword, linked to the resulting urls row.

05Timestamps

FieldEncodingNote
urls.last_visit_time, visits.visit_timeChromium/WebKit time: int64 µs since 1601-01-01 UTCUnix µs = value − 11644473600000000. base::Time follows the OS wall clock and can jump when the clock is adjusted.
visits.visit_durationint64 µs duration (TimeDelta)A length of time, not a date; do not convert it with the 1601 epoch.
downloads.start_time, end_time, last_access_timeChromium/WebKit time: int64 µs since 1601-01-01 UTCMigration code shows that very old schemas stored time_t seconds and were converted on upgrade.

Decode raw values with the Timestamp decoder and convert local wall-clock times with the Local time to UTC.

06Examination workflow

  1. Work on a copy of History together with any -journal or -wal file present in the profile folder.
  2. Join visits.url to urls.id and convert visit_time to UTC; keep the raw integer next to the converted value.
  3. Decode transition with the 0xFF core mask and list the qualifier bits separately.
  4. Rebuild download chains from downloads_url_chains and compare target_path with the file system.
  5. Separate locally made visits from synced ones using the originator_* columns before attributing activity to this device.

07Interpretation pitfalls

  • The history backend expires entries older than 90 days (kExpireDaysThreshold), so absence of an old visit is expected.
  • visit_count and typed_count are aggregates and can disagree with the visits rows that remain after expiry or deletion.
  • Synced visits from other devices can appear in the same tables; the originator columns distinguish them only in schemas that have them.
  • A visit records that the browser loaded a URL, not that a person read the page.

09Sources

  1. Chromium source — components/history/core/browser/url_database.cc The Chromium Authors (GitHub mirror) · checked 2026-10-14
  2. Chromium source — components/history/core/browser/visit_database.cc The Chromium Authors (GitHub mirror) · checked 2026-10-14
  3. Chromium source — components/history/core/browser/download_database.cc The Chromium Authors (GitHub mirror) · checked 2026-10-14
  4. Chromium source — components/history/core/browser/download_constants.h The Chromium Authors (GitHub mirror) · checked 2026-10-14
  5. Chromium source — ui/base/page_transition_types.h The Chromium Authors (GitHub mirror) · checked 2026-10-14
  6. Chromium source — history_backend.h (kExpireDaysThreshold) The Chromium Authors (GitHub mirror) · checked 2026-10-14
  7. Chromium source — components/history/core/browser/history_constants.cc The Chromium Authors (GitHub mirror) · checked 2026-10-14
  8. Chromium source — sql/statement.cc (BindTime / ColumnTime) The Chromium Authors (GitHub mirror) · checked 2026-10-14
  9. Chromium source — base/time/time.h (base::Time) The Chromium Authors (GitHub mirror) · checked 2026-10-14
  10. Chromium source — docs/user_data_dir.md (User Data Directory) The Chromium Authors (GitHub mirror) · checked 2026-10-14