caching or i owe hackclub money
so heres what my day looked like: nvim was calling hackfetch -status on every redraw for my lualine. tmux was calling it every 60 seconds for the status bar. i had 3 tmux sessions open. and every time i actually opened a new terminal, hackfetch fired again on shell start.
quick napkin math: nvim redraws are basically continuous when im typing, tmux was hitting the api 3x/minute across sessions, plus every terminal open = another fetch. we’re talking hundreds of calls to hackatime in a normal work session. from ONE user.
me 
hackatime is a free hack club service and i was starting to feel bad lol. 
the fix: cache the response
~/.cache/hackfetch/last.json stores the last snapshot with a timestamp. every fetch checks that file first. if its fresh enough, skip the network entirely and just render from disk.
TTL is different depending on the caller:
hackfetch (one-shot): 30 seconds. long enough that a normal re-run inside a devlog attempt is instant, short enough that you dont get badly stale numbers.
hackfetch -status: 60 seconds
tmux polls roughly this often anyway so its basically free now.
hackfetch -watch: ignores the cache, always fresh (thats the whole point of watch mode).
opt out with -no-cache or HACKFETCH_CACHE_TTL=0 if you want. also HACKFETCH_CACHE_TTL=300 to be even more polite.
So yea tmux is now basically free. 
but the real win writing this made me realize the cache does more than save milliseconds:
-
every fetch was a full TLS handshake, wifi radio spin up, etc. now most fetches touch the disk once and nothing else. macbook fan appreciates it.
-
offline. if your wifi drops mid coding session you keep working from the cache instead of showing a spinner forever. tmux bar just keeps saying what it said 40 seconds ago.
-
battery again but for the hackatime server. hackfetch stops asking the api 5-10x more than they need to. multiply by everyone who has it in their tmux config and thats a real thing.
-
atomic write via .tmp + rename so nothing ever reads a half-written file. cache is user-only (0600), because it does contain your top project name.
bonus: -doctor
while i was fixing the polite-to-the-api stuff i added -doctor, which walks a checklist and tells you whats broken:
hackfetch doctor
✓ wakatime config exists /Users/xerneas/.wakatime.cfg
✓ api_key present loaded from config
✓ wakatime-cli found /Users/xerneas/.wakatime/wakatime-cli
✓ hackatime api reachable today: 28m
✓ terminal supports truecolor $COLORTERM=truecolor
✓ browser opener available /usr/bin/open
green if its working, orange if its not, and non-zero exit if anything failed so you can script it. this was going to be a small self-diagnosis feature and it caught a real bug in the api client on the very first run i did while writing it lol (a string field where hackatime returns an int, so one of the fields was silently missing from every fetch since v1.0). fixed that too.
ship
both landed in v1.10.0. update as usual:
brew update
brew upgrade hackfetch
or arch:
yay -Syu hackfetch-bin
then run hackfetch -doctor first, and if anything is broken it’ll tell you exactly what.
Comments 2
w
cool project twin!!! keep it going!
Sign in to join the conversation.