Where Cursor Stores Your Chat History
Cursor keeps every conversation in one SQLite file on your disk. Here is the exact path, how to read it yourself, why it is the single point of failure people discover the hard way, and how to back it up.
Cursor does not have an export button, and the history panel is the only place most people ever see their conversations. That makes the question worth answering precisely: the chats are on your disk, in one file, and you can read them without Cursor running.
On the machine this article was written on, that file is 6.4 GB. It holds 521 conversations and 164,200 individual messages. One file, no backup, no export — and every prompt anyone on this machine typed into Cursor is inside it.
The exact location
Cursor is a fork of VS Code and inherits its storage layout, so the path follows the same shape on every platform. The conversations live in the global storage database:
# macOS
~/Library/Application Support/Cursor/User/globalStorage/state.vscdb
# Windows
%APPDATA%\Cursor\User\globalStorage\state.vscdb
# Linux
~/.config/Cursor/User/globalStorage/state.vscdbThere is a second location worth knowing about. Alongside globalStorage sits workspaceStorage, one directory per project you have opened, each named after a hash of the folder's path. That is where per-project state lives — which conversation belongs to which repository, editor layout, and similar. On this machine there are 107 of those directories, most for projects that no longer exist.
# every project Cursor has ever opened on this machine
ls ~/Library/Application\ Support/Cursor/User/workspaceStorage | wc -l
# which project a given hash belongs to
cat ~/Library/Application\ Support/Cursor/User/workspaceStorage/<hash>/workspace.jsonWhat is actually inside the file
state.vscdb is an ordinary SQLite database. Cursor stores conversations in a key-value table called cursorDiskKV, where the key prefix tells you what each row is. Two prefixes matter: composerData rows are conversations — the metadata and message order — and bubbleId rows are the individual messages, one row per prompt or response.
You can confirm the shape of your own database in two commands. Both are read-only and safe to run while Cursor is closed:
DB="$HOME/Library/Application Support/Cursor/User/globalStorage/state.vscdb"
# what tables exist
sqlite3 -readonly "$DB" ".tables"
# how many conversations and messages you have
sqlite3 -readonly "$DB" \
"SELECT substr(key,1,instr(key,':')-1) AS kind, COUNT(*)
FROM cursorDiskKV GROUP BY kind ORDER BY 2 DESC LIMIT 8;"The output on this machine put bubbleId at 164,200 and composerData at 521. Yours will differ, but the ratio will not: a few hundred conversations, a few hundred thousand messages, and no interface that lets you get them out.
Every Cursor conversation you have ever had is one file. There is no second copy, and nothing in the product treats it as something you might want to keep.
Why this is the failure people find the hard way
A single growing SQLite file is a reasonable design for an editor cache. It is a poor design for a record you care about, and the consequences show up in a predictable order.
- It grows without bound. Multiple gigabytes is normal after a year of daily use, and a large state database is a common cause of the editor hanging on startup.
- It is a single point of failure. If the file is corrupted or truncated — an unclean shutdown, a disk that filled up — the chat panel can hang on "Loading Chat" indefinitely, and the usual advice in support threads is to delete the database, which discards every conversation in it.
- Upgrades have lost it before. Users have reported losing their entire history across specific Cursor releases, which is the kind of thing you only notice after the fact.
- There is no export. Nothing in the product writes your conversations anywhere else, in any format, on any schedule.
- The workspace hash is derived from the folder path. Rename or move a project and its per-workspace state no longer matches — the conversations are still in the database, but the link between them and the project is not what you expect.
None of this is a scandal. It is the ordinary consequence of a cache that quietly turned into a record. The prompts in that file are the closest thing that exists to a written statement of intent for whatever Cursor wrote into your repository — and they are being stored with the care appropriate to a cache.
How to back it up, with no product involved
Do this today; it takes one command and needs nothing from anyone. Quit Cursor first — copying a live SQLite database can capture a torn write — then copy the file, along with its write-ahead log if one is present:
SRC="$HOME/Library/Application Support/Cursor/User/globalStorage"
DEST="$HOME/Backups/cursor-$(date +%Y-%m-%d)"
mkdir -p "$DEST"
cp "$SRC/state.vscdb"* "$DEST/"A cleaner alternative, if you would rather not shut the editor down, is to let SQLite make a consistent copy for you: sqlite3 "$SRC/state.vscdb" ".backup '$DEST/state.vscdb'". Either way, put the destination somewhere your existing backups already reach, and repeat it on a schedule you will actually keep.
If you want to know what is at risk across every AI tool on the machine rather than Cursor alone, promptwake doctor scans for AI coding history and reports what each tool is holding and what is inside a deletion window. It runs through npx, needs no account, writes nothing and sends nothing anywhere.
Where the personal fix stops working
Everything above solves the problem for one developer on one machine, which is a real result and worth having. It stops solving anything at team scale, for reasons that have nothing to do with Cursor.
The file is on the laptop it was written on. A wiped machine or a developer leaving takes the record with it, and no offboarding checklist covers Application Support. Nobody but its owner can read it, so a tech lead cannot see what the team asked the model to build. It only covers Cursor — Claude Code, Copilot and the rest keep their own history in their own formats, each with its own rules and its own way of losing it. And a copied SQLite file on a personal laptop is not evidence of anything you could show to a customer or an auditor who asks how a piece of code came to exist.
Version control records what changed. With AI in the loop, why it changed lives somewhere else entirely — and only one of those two is backed up.
What to do this week
Copy state.vscdb somewhere safe today. Then check the size of the file: if it is measured in gigabytes, you are carrying a year of engineering reasoning in a cache that nothing is protecting, and the editor performance problems that come with it are the least expensive part.
If the conclusion is that the record matters and should not live on individual laptops, that is what PromptWake was built for: it captures the prompt, the response and the resulting diff from the AI tools your team already uses, keeps them locally by default, and on the paid tiers syncs them into one timeline the team can search. Back up the file regardless — the failure modes above do not wait for a purchasing decision.
