SQLite is the quiet workhorse behind phones and apps - it backs browser history, cookies, WhatsApp's message store, iOS Messages and the Photos library. What makes it distinctive is that, by default, it does not erase deleted rows: a database that shows nothing in the app can still hold much of what was removed from it, readable straight out of the raw file.
Scan a SQLite fileThe single most important thing a scan surfaces is evidence of deleted data. By default SQLite does not wipe a deleted row - it unlinks it and marks the space free, leaving the original bytes in place until something happens to overwrite them. The scan reads the header's free-page count and reports how many kilobytes of whole free pages the file holds, which is where larger deletions end up. It reports that evidence rather than reading the deleted rows back. Running VACUUM clears it, so a database that looks empty in the app is very often not.
It goes one step further with the AUTOINCREMENT counter. SQLite keeps a high-water mark in the hidden sqlite_sequence table - the largest row id it ever handed out - and never decrements it. By comparing that number against the rows still present, the scan counts how many records were deleted from a table that uses AUTOINCREMENT, for example "142 of 512 records removed". Strictly it is an upper bound, since an insert that failed also uses up a number. Chromium's browsing history uses AUTOINCREMENT, so deleting individual history entries shows up here. That count survives even a full VACUUM, after every other trace of the deletion is gone.
The scan recognises famous app schemas by their table names: Chrome/Chromium and Firefox browsing history, browser cookies, iOS Messages (sms.db), the WhatsApp message store, iOS cached locations, and the iOS Photos library. When it matches one, it tells you the database holds detailed personal activity - contacts, timestamps, URLs, coordinates - rather than making you infer it from the schema. It also flags individual tables whose column names suggest location, email, phone or credentials, with a live row count so empty tables are not false alarms.
From the fixed 100-byte header, readable without opening the database, it also reports the SQLite library version that last stamped the file, with a warning when other software has written to it since, an Application ID some apps stamp to claim the file (GeoPackage, MBTiles, Fossil and others are named), reserved-page space that betrays an encryption or checksum extension, and whether the file uses write-ahead logging - which means the newest writes live in a separate -wal companion file that leaks independently. Saved views and triggers are dumped verbatim, because their hand-written SQL routinely embeds an address, share path or filter that appears in no table.
This is a selection. The full field manual documents the fields read from each format.
Yes. It runs entirely in your browser, so there is nothing to install and no account. Drop a .sqlite, .sqlite3 or .db file into File X-Ray and it reads the header, schema and page structure on your device. The database is never uploaded. It does not display the rows themselves; to read those, open the file in a SQLite viewer.
Often, yes, with a forensic tool. By default, deleting a row in SQLite only marks its space as free; the bytes stay in the file until later writes happen to overwrite them. File X-Ray does not read deleted rows back: it reports the free space the header records, where deleted data can remain, and for AUTOINCREMENT tables it counts how many rows were removed. Running VACUUM on the database is what actually removes it - deleting inside the app does not.
Tables with AUTOINCREMENT record the highest id ever issued in a hidden table called sqlite_sequence, and that number is never lowered. Subtracting the rows that remain gives the number deleted, or an upper bound on it, since an insert that failed also uses up a number. Because that counter is stored separately from the row data, a full VACUUM - which erases the free pages - leaves it untouched, so the deletion count remains after every other trace is gone.
Yes. The database is opened read-only by a WebAssembly build of SQLite that runs entirely inside your browser tab. The file is never uploaded, and the roughly 640 KB engine only loads when you actually open a database.
If the header shows write-ahead logging (WAL) mode, the most recent changes are kept in a companion file ending in -wal, not in the main database. If you were only handed the main .db, the newest writes are in a second file left behind - and that file is a separate copy of the data that leaks on its own.
The scan matches the set of table names against known app schemas (Chrome/Chromium urls and visits, Firefox moz_places, iOS Messages, WhatsApp msgstore, iOS Photos and others). A match just means the structure fits; you can open the database in any SQLite viewer to read the rows directly.
File X-Ray reads SQLite files entirely in your browser - the file never leaves your device. This format is inspected, not modified. Scan a file now.