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

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 size900 MiB conversations.json (944 MB), 300 MiB ZIP, 12,200 chats
Time to open in Chrome3 to 5 minutes (two runs: 180 s and 280 s)
Largest Chrome process during importAbout 390 MiB
Parser alone, Node with a 192 MB heap limitAll 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

Sources