There is a particular kind of bug that gets worse the harder you look at it. I had one of those before Christmas. A race condition, the sort that shows up once in a few hundred runs, never in the debugger, never when you add the logging that would actually catch it. I spent the best part of a day on it. I read the code until the words stopped meaning anything. I added print statements, removed them, added them somewhere else. I stared.
By mid-afternoon I had that flat, jammed feeling where you are no longer thinking, you are just re-reading the same eight lines hoping they confess. The honest move at that point is to admit you are done for the day, but the holidays were close and I wanted it gone. So I did the next best thing, which was to leave entirely. I got the bike out and rode.
It was cold and clear, the kind of December afternoon where the light goes amber by half three and your fingers are numb by the first hill. I wasn't thinking about the bug. I was thinking about not falling off, and whether I'd left the immersion heater on, and how much I disliked the headwind on the long flat bit past the reservoir.
Somewhere around the halfway point, with no warning and no effort, the answer arrived. Not the fix exactly, but the shape of it. The race wasn't in the code I'd been staring at. It was in the assumption underneath it: that two callbacks I'd treated as sequential could actually overlap, because one of them did a bit of async work I'd forgotten was async. The whole day I'd been auditing the wrong half of the program. The moment I stopped trying to hold the entire thing in my head, the part I'd been ignoring floated up on its own.
I don't think there's anything mystical about this. The riding doesn't solve the bug. What it does is break the loop. When you stare, you keep activating the same wrong path, the one that already failed, because it's the one most recently in your head. Stepping away lets that path go cold, and then the brain is free to wander somewhere it wouldn't have gone whilst you were forcing it. The forcing is the problem. The bike is just a reliable way to stop.
I got home, made tea, and wrote the fix in about ten minutes. A small lock around the shared state, a comment explaining why the callback was not as sequential as it looked, a test that reproduced the race by deliberately delaying the async bit. Done. The thing that had eaten a day took ten minutes, because by the time I sat back down I already knew the answer and just had to type it.
So this isn't really advice, because "go for a bike ride" is useless guidance when the build is broken and someone's waiting. But I've stopped treating the time away from the desk as time lost. Some bugs are genuinely a matter of grinding through the logic. Plenty of others are stuck because you are stuck, and the cheapest fix is to physically remove yourself from the chair until your head lets go of the wrong idea. The reservoir, the headwind, the numb fingers: cheaper than another three hours of staring, and a great deal more pleasant.