How to open a huge ChatGPT export without crashing
Short answer: do not open conversations.json in a text editor or by double-clicking chat.html. Read it as a stream, one chat at a time. The streaming script below used under 20 MB of RAM on a 100 MB file where the normal approach used about 800 MB.
People with years of history end up with very large exports. One r/ChatGPT user asked how to move about 850 MB of conversations to another assistant, and several replies described parsing it with their own scripts, one splitting it into a Markdown file per chat.
Why big exports crash things
- It is one giant line. The convoviz project's audit guide notes that
conversations.json"is typically minified into a single, massive line". Most editors struggle with a single line that long. - Normal JSON loading needs the whole file at once. Python's
json.loadbuilds every chat in memory before you can touch the first one. On a 100 MB synthetic export we measured a peak of about 800 MB of RAM. Scale that to 850 MB and a laptop runs out. - Browsers have a hard string limit. JavaScript's
JSON.parseneeds the whole file as one string. In Node 22 (V8) the maximum string length is 536,870,888 characters, so a file past roughly that size cannot be parsed in one piece at all, whatever your RAM. chat.htmlembeds everything. The offline viewer that comes in the ZIP renders all chats on one page, which is slow long before it is huge.
Option 1: Stream it with Python (free)
The ijson library reads JSON as a stream and hands you one array element at a time. This script writes one Markdown file per chat and never holds more than one chat in memory (download):
# pip install ijson
import datetime, pathlib, re, sys
import ijson
src, out = pathlib.Path(sys.argv[1]), pathlib.Path(sys.argv[2])
out.mkdir(parents=True, exist_ok=True)
def kept_branch(conv):
mapping, node, msgs = conv.get("mapping", {}), conv.get("current_node"), []
while node in mapping:
msg = mapping[node].get("message")
if msg:
msgs.append(msg)
node = mapping[node].get("parent")
return list(reversed(msgs))
used = set()
with open(src, "rb") as f:
for conv in ijson.items(f, "item", use_float=True): # one chat at a time
title = (conv.get("title") or "").strip() or "Untitled chat"
lines = [f"# {title}", ""]
for msg in kept_branch(conv):
role = msg.get("author", {}).get("role")
if (msg.get("metadata") or {}).get("is_visually_hidden_from_conversation"):
continue
if role == "assistant" and msg.get("recipient", "all") != "all":
continue
parts = (msg.get("content") or {}).get("parts") or []
text = "\n\n".join(p for p in parts if isinstance(p, str)).strip()
if role in ("user", "assistant") and text:
lines += [f"## {'You' if role == 'user' else 'ChatGPT'}", "", text, ""]
day = datetime.datetime.fromtimestamp(conv.get("create_time") or 0).strftime("%Y-%m-%d")
name = re.sub(r'[\\/:*?"<>|\x00-\x1f]', " ", title)[:80].strip() or "Untitled chat"
path = out / f"{day} {name}.md"
n = 2
while path.name.lower() in used:
path = out / f"{day} {name} ({n}).md"
n += 1
used.add(path.name.lower())
path.write_text("\n".join(lines), encoding="utf-8")
print(f"wrote {len(used)} files to {out}")
Run python export_to_markdown_streaming.py conversations.json markdown. On our 100 MB synthetic export (1,359 chats) it finished in 2.4 seconds with a memory peak under 20 MB, and produced the same files as the non-streaming version.
If your export uses the {"conversations": [...]} wrapper instead of a bare list, change "item" to "conversations.item". If it came split into conversations-000.json, -001.json and so on, run it once per file.
Option 2: An open-source CLI
convoviz converts a ChatGPT export ZIP into Markdown and makes charts of your usage. It is free and actively maintained. We have not measured its memory use on a very large export.
Option 3: A private Chrome extension
Chat Archive Viewer opens the ZIP without unzipping it. It reads the file in 1 MB slices in a background worker, splits out one chat at a time, and stores them in your browser, so the page stays responsive while it works. You get a month-by-month list of every chat, full-text search, and Markdown or full-length PDF for any chat.
| Our test (synthetic export, one Linux PC) | Result |
|---|---|
| Export size | 900 MiB conversations.json (944 MB), 300 MiB ZIP, 12,200 chats |
| Time to open in Chrome | 3 to 5 minutes (two runs: 180 s and 280 s) |
| Largest Chrome process during import | About 390 MiB |
| Parser alone, Node with a 192 MB heap limit | All 12,200 chats parsed, about 290 MiB peak memory |
It has no website permissions and never contacts ChatGPT. Free covers your newest 100 chats; Pro ($12 once) opens everything and exports the whole archive.
Before you start
- Download the export within 24 hours; OpenAI's link expires after that, and big exports can take days to arrive.
- Check the ZIP finished downloading. A cut-off file is the most common "corrupt export". Chat Archive Viewer will open what is complete and tell you the file looks cut off.
- Keep the original ZIP. Every tool here reads it without changing it.
Sources
- r/ChatGPT, "How can I export ~850MB of ChatGPT conversations to migrate to another AI model?", March 4, 2026: reddit.com/r/ChatGPT/comments/1rkpact
- convoviz, ChatGPT export audit guide: github.com/mohamed-chs/convoviz
- OpenAI Help Center, "Exporting your ChatGPT history and data": help.openai.com/en/articles/7260999
- Memory figures: measured by 1088 Labs on synthetic data, October 2026 (Python 3.12 for the json script, Python 3.14 with ijson 3.5.1 for the streaming script, Node 22.22, Chrome for Testing 152).