fix(installer): raise the shipped statusline refreshInterval from 1s to 30s - #1772
Open
asdf8675309 wants to merge 1 commit into
Open
fix(installer): raise the shipped statusline refreshInterval from 1s to 30s#1772asdf8675309 wants to merge 1 commit into
asdf8675309 wants to merge 1 commit into
Conversation
…to 30s deployStatusline() wires every new install with refreshInterval: 1, so Claude Code polls the statusline once per second. Nothing on the bar changes that fast. A warm render of LIFEOS_StatusLine.sh costs 0.28-0.29s. The usage figures it displays sit behind a 900s cache TTL (USAGE_CACHE_TTL), and the script renders no wall clock, so the fastest timer-driven value on the bar updates once every 15 minutes. A 1s poll re-renders it about 900 times per data change. The waste is not the only cost. Public PR danielmiessler#1767 reports that Claude Code terminates a statusline render which overruns its interval, and that the killed renders leaked 244,760 scratch directories on a headless box until the filesystem ran out of inodes. 30 is a conservative starting point, not a derived optimum. It is far inside the 900s TTL of the slowest-moving source while cutting the duty cycle from about 29 percent to about 1 percent. The principled value tracks how often the underlying data actually shifts, so this number should be revisited if the bar gains a faster-changing source. Everything on the bar that moves on events rather than on a timer, such as the model and the branch, still re-renders at turn boundaries regardless of this interval.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
deployStatusline()wires every new install withrefreshInterval: 1, so Claude Code polls the statusline once a second. Nothing on the bar moves that fast.LIFEOS_StatusLine.shcosts 0.28–0.29s.USAGE_CACHE_TTL, L152).dateformats in the script are+%s,+%Y-%m-%d, and one ISO stamp.So the fastest timer-driven value updates once every 15 minutes, and a 1s poll re-renders it about 900 times per data change.
Wasted work isn't the only cost. #1767 reports that Claude Code kills a statusline render that overruns its interval, and those killed renders leaked 244,760 scratch directories on a headless box until the filesystem ran out of inodes. That PR bounds the leak. This one takes away the pressure driving it.
Change
One literal in
deployStatusline(). The file is mirrored underinstall/skills/, so the same line changes in both copies — identical blobs before and after.About the 30
It's a starting point, not a computed optimum. I picked a round number comfortably inside the 900s TTL of the slowest source. I'd rather say that than dress it up as math.
The principle behind it is what matters: the idle poll should track how fast the underlying data actually changes. Right now that's the usage figure at 900s, so anything from a few seconds up is fine and 1s isn't. If the bar picks up a faster-moving source later, this number should move too. The comment in the diff says so, which keeps the reasoning attached to the number.
One thing for anyone worried about responsiveness:
refreshIntervalonly governs the idle poll. Model, mode, and branch change on events, and those still re-render at turn boundaries no matter what this is set to. A bigger interval doesn't make the bar feel stale while you're working.If you've got a number that fits your source's cadence better, use it.
Why it's safe
Existing installs don't get touched. The write is guarded by
alreadyWired:If
statusLine.commandalready points at the deployed script, there's no write at all, so the currentrefreshIntervalsurvives byte-identical. Only fresh wiring picks up the new default.The flip side, stated plainly: existing users keep
1until they change it by hand or their statusline command path changes.A longer interval fails benignly — a stale bar for up to 30s, well inside the 900s TTL of its own data. No crash path, no new dependency, no API change.
Verification
macOS 15 (Apple Silicon), bash 3.2,
LIFEOS_StatusLine.shfromorigin/mainat 47df8ee. Five warm runs after five discarded warmups:refreshInterval: 1refreshInterval: 30bun build --target=bunon both changed files exits 0. The repo has no test runner, so those numbers and thealreadyWiredread are the reviewable proof.Scope
Found and deliberately left alone:
security find-generic-passwordandcurl --max-time 3inline during a render. Weather and location already moved to detached background subshells for this exact reason — "that's what killed the perf and got the feature ripped out on 2026-05-08." The usage fetch probably wants the same treatment, but that's a different concern and a much bigger diff, so it's not in here.LIFEOS_StatusLine.shitself. fix(statusline): bound the /tmp pai-parallel leak (follow-up to #1297) #1767 is already open against that file. No overlap — this PR only touchesDeployComponents.ts.settings.enhancements.jsonandsettings.system.json. Neither has astatusLinekey, so there's no second default to keep in sync.