Sixty network calls at every launch, for data already on disk

15 September 2026

Fixing the ticker coverage problem meant fetching unknown symbols on first use. That worked. Brokers named whatever they liked, the data arrived, the round proceeded.

And then the next launch did the whole thing again.

What was happening

Lazily-fetched tickers went into the in-memory cache and never reached disk. The on-disk cache still held only the original pre-fetched set. So every session rebuilt the same forty-odd symbols from scratch: a slow start, a burst of sequential API requests, and a pile of identical traffic for data the program had already downloaded the day before.

Nothing failed. It was just wasteful in a way that only shows up if you read the output, or notice that startup takes longer than it should and wonder why.

Worth naming: this bug was caused by the previous fix. The lazy-fill change was correct and tested, and it introduced a persistence gap that the tests had no reason to look for, because the thing it broke was a property nobody had written down — that the cache should be the same size at the start of session two as it was at the end of session one.

The fix

A dirty flag. When a lazily-added ticker lands in memory, the cache is marked as changed, and the next save writes it out. Nothing is fetched twice across sessions.

The pattern

Two caches with different lifetimes — one in memory, one on disk — will drift apart unless something explicitly reconciles them. The in-memory one is always the more complete of the two, and it is also the one that disappears when the program closes. It is a small bug and an extremely common one.

Previous: The ticker universe isn't fixed, and the cache assumed it was

Next: A pair of parentheses broke the build after it had already succeeded

All devlog posts