My weekly quota for the MAX plan melted in three days.
Even though I should have had a 20x quota, by Wednesday, the remaining amount was looking suspicious. I usually just brush that off as "well, that happens," but it suddenly made me curious. What is actually going on inside the context window?
In my .
3-Layer Model
Throughline breaks down the conversation into three layers and saves them in SQLite.
L1 (Skeleton) — One-line summaries of old turns. Generated by a lightweight model. About 10 tokens per turn.
L2 (Body) — Conversation body of the last 20 turns. User messages and AI responses are kept as is. No compression, lossless.
L3 (Detail) — Tool I/O, system messages. Evicted to SQLite and never kept in context. When needed, the AI fetches them from SQLite itself.
It’s safe to run /clear. Since the SQLite database doesn't disappear, it inherits the memory of the previous session in a single transaction at the start of the next session. There’s no need to track PIDs or judge by time windows. It works decisively.
In terms of numbers, it looks like this:
Without Throughline (50 turns, no /clear):
Context ≈ 125,000 tokens (80% is finished tool I/O)
With Throughline (50 turns → /clear → resume):
Context ≈ 13,000 tokens
(Last 20 turns of L2 + 30 turns of L1 summary)
About a 90% reduction.
A Note on a Failed Design
It wasn't in this form from the beginning.
In the initial design, I tried to make L2 a "structured extraction of important decisions." I imagined extracting only important information from the conversation with tags like [DECISION] Adopt WebSocket, [CONSTRAINT] Port 8080 cannot be used.
It was beautiful in theory, but I realized something after implementation: You cannot predict what the AI will need in the future.
Information that the classifier deems "not important" might be needed 10 turns later. And you wouldn't even notice that it's gone. 80% accuracy means that the remaining 20% becomes invisible.
In the end, I settled on a method where L2 keeps the full text of the conversation. A subtraction-only design. I just remove the tool I/O from the original Claude Code context. This way, "quality drop due to Throughline" is impossible in principle.
Inheritance between sessions was also initially file-based, attempting to detect /clear within a 10-second window, but that broke with parallel sessions. Eventually, it settled on a single SQLite UPDATE. Simpler is more robust.
Why Summarization Cost is Nearly Zero
The L1 summary is generated using Haiku 4.5, but there's a trick to it.
After analyzing my past 86 sessions, the median number of turns was 13. More than half of the sessions end within 20 turns.
Throughline keeps 20 turns of L2, so the summarization model never runs in short sessions. Summarization is only needed from the 21st turn onwards. And even then, it processes it lazily, one turn at a time.
In other words, the token consumption of the summarization process itself is almost zero. The contradiction of /compact, where you "consume a massive amount to save," simply doesn't happen.
Bonus: Token Monitor
As a byproduct of development, a multi-session capable token monitor was also created.
▶ Throughline 2ed5039c ████░░░░░░░░░░░░░░░░ 205.1k / 21% Remaining 794.9k claude-opus-4-6
Since it reads the API actual values (message.usage) from the transcript's JSONL, it provides accurate values rather than rough estimates like "character count ÷ 4." It also automatically detects 1M context limits.
You can see in real-time how much each session is consuming when running multiple sessions. It’s subtly convenient.
Summary
The true nature of the problem where the quota melts in three days was the conversation history, which occupied 87% of the context window. Most of that was debris from tool I/O.
Optimizing CLAUDE.md or shortening prompts are measures that affect 9% of the total, so they are better than nothing. But that wasn't the main issue.
Perhaps this kind of problem should be solved by the platform side. But I was struggling right now, so I made it myself. Node.js 22.5+, zero dependencies, MIT. It works if you have a MAX contract.
If anyone else is struggling with the same problem, feel free to take a look if you feel like it.
SOCIAL SHARE CARD GENERATOR