446d3b9c211dd13335dc82f2343e8851973225ef
Every page-back re-read and re-parsed the whole transcript and then threw away all but the window. That is the cost that grows with the conversation rather than with the answer: measured on a 21 MB, 24,000-event transcript, one page took ~500ms of server time to return 620 KB, and it took the same 500ms whichever page was asked for. A phone scrolling up pays that per page, and every stream reconnect pays it again to discover there is nothing new. Sequence numbers only increase, so the boundary of a range is a bisection. `Indexed` locates the lines without reading them, finds the edge by parsing one line per halving, and parses only what is going to be returned. Same page, 232ms including the 120ms `--delay` -- so ~110ms, of which ~20ms is the file scan and the rest is serialising the 620 KB that was always going to be sent. `catch_up` gets it too, and there the case that looks least interesting is the one that mattered: a subscriber with no cursor asks for the whole conversation and is handed the last CATCH_UP_LIMIT events of it. The file is still read whole, which is a deliberate stop -- finding the tail without reading forwards means a chunked backwards reader, and locating a line is not what the half-second was going to. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Languages
Rust
54%
Kotlin
43.6%
Shell
2.4%