Time To Convince

There was a time—not too long ago—when I’d hear about a bug or a new feature and immediately crack my knuckles, spin up the IDE, and race toward a solution. That reactive energy felt productive. Urgent. Like I was doing what engineers are meant to do: solve things fast. But more often than I’d like to admit, that rush led to tangled implementations, speculative dead ends, or solutions I later had to unravel with a kind of annoyed humility.
Lately, though, something has shifted in how I approach problems. I’ve started giving them time, not out of laziness or avoidance, but out of intent. I’ve begun treating the act of not immediately solving a problem as part of the solution. Letting it sit. Percolate. Drift into the background of my mind while I do other things. I call this process Time To Convince, or TTC—the time it takes not to fix something, but to become truly convinced that the solution I’m about to implement is the right one.
What’s funny is that I didn’t learn this from a book or a conference talk. I stumbled into it through my own trial and error—years of over-engineering, sunk-cost decisions, and speculative coding that never quite paid off. Only recently did I start reading How Big Things Get Done, and to my surprise, the philosophy echoed exactly what I had begun to discover for myself: that thinking deeply before acting isn’t waste—it’s wisdom.
This article explores how that quiet shift has impacted the way I write code, build systems, and even perceive productivity. It’s also a gentle nudge to those caught up in the high-speed haze of “vibe coding” or AI-assisted shortcutting to remember that thoughtful planning isn’t a luxury—it’s the foundation.
How I Used to Work

When I look back on my earlier years as a software engineer, I can see how much of my approach was shaped by speed—and not always in a good way. I prided myself on being the person who could jump into a problem and start shipping within minutes. In consultancy work especially, that mindset felt like a badge of honor. Deliver fast, move on, repeat.
But speed came with a cost! 😨
I’d often write code based on requirements I thought would be needed. I convinced myself I was being proactive, but really, I was just committing speculative generality—engineering solutions for imaginary problems. That made future work harder, not easier. I also spent more time than I should admit entangled in the sunk cost fallacy. I’d pour hours into an approach, and even when I could feel it going sideways, I’d keep pushing—telling myself I’d come too far to stop now. The idea of throwing work away felt like failure.
And of course, there were the untangling sessions—the aftermath of rushing to a solution without enough reflection. You know the ones: where you spend more time unpicking your own logic than it would’ve taken to do it right from the start.
In a previous article I wrote, "The Funny Truth About Why You're Always Behind Schedule", I talked about Yak Shaving—those spiraling detours where a simple task snowballs into a trail of distractions. Back then, my response to those spirals was to work harder and faster. I thought if I could just get through it, I’d regain control. But I’ve come to realize that often, what I needed wasn’t more speed—it was more stillness.
Let the Problem Linger

These days, when a bug lands on my plate or a new feature request comes in, I don’t rush. Instead, I start with something that might sound a bit unproductive: I do nothing 🤫. Or at least, I don’t start coding right away.
I let the problem sit.
It’s not neglect—it’s incubation. I’ll skim the context, maybe form a loose gut estimate of how long it might take, and then I deliberately set it aside. I don’t abandon it, though. I take it with me—to the kitchen, when I vacate my little office in the garden to make a brew. It’s there when I’m brushing my teeth, sometimes even shaking my head slightly like I’m trying to rattle the idea loose. And yes, it’s even there in the shower—where, for some reason, the best architectural decisions seem to bubble up from the steam 😏.
These quiet moments are where the real shaping happens. I’ll imagine a potential approach, then just as quickly play devil’s advocate in my head. What if it doesn’t scale? What if I need to roll it back? What if it breaks something subtle?
It’s a kind of low-friction rehearsal. I’m mentally mapping the edges and risks of the solution long before I write a single line of code. And more often than not, that invisible work leads to a more elegant, sustainable approach than anything I could’ve forced out in a rush.
There’s still a voice—remnants of old habits—that nudges me: “Shouldn’t you be working?” But now I know that this is working. It’s the hidden layer of engineering that prevents rework, saves time, and makes the final build cleaner. What once looked like procrastination, I now recognize as quiet, deliberate design.
Throwing It Away 🗑️

One of the most important things I’ve learned—maybe the hardest, too—is to be okay with throwing something away.
There used to be this tension: once I’d invested hours into a solution, I felt this pressure to make it work, even when it clearly wasn’t going to. I’d keep pushing, tweaking, trying to rescue the effort—because abandoning it would mean wasting all that time, right? Classic sunk cost fallacy. I knew it. But that emotional investment made it hard to let go.
And that’s the thing—we don’t often talk about the emotional connection developers have to their code. I don’t know if it’s a neurodiversiological trait, or just the inevitable result of spending so many hours building something with focus and intent. But it’s real. The first version of any solution often feels personal. Like a little extension of your brain. It can feel weirdly vulnerable to throw it out.
That’s why, in the early stages, I now try to avoid that emotional connection entirely. I go in with what I call the Hacker Mentality—something I wrote about in a previous piece, “An Engineer’s Code Tells You a Lot About the Engineer”. The idea is to approach the problem playfully, experimentally. No polish. No pride. Just rough sketches and technical curiosity.
When I treat that first attempt as a draft, I’m much freer. If it works—great 👌. If it doesn’t—I can toss it aside without feeling like I’ve lost a piece of myself. Sometimes I’ll leave the broken implementation untouched for a while, letting my frustration cool. Then I’ll come back, dissect what didn’t work, and treat it like a mini-retrospective: What was I assuming? What broke? What was I emotionally attached to that I shouldn’t have been?
That mindset shift—from attachment to experimentation—has saved me countless hours. And more importantly, it’s made my code better. Because when I stop trying to salvage the wrong thing, I make room for the right thing to emerge.
How Big Things Get Done

It wasn’t until recently that I picked up How Big Things Get Done by Bent Flyvbjerg and Dan Gardner. I didn’t go looking for a book to justify my new way of working—I just stumbled across it. But as I read, I kept nodding along. The patterns, the warnings, the triumphs—it all resonated.
The central theme of the book is simple but profound: the most successful large-scale projects—from architecture to tech to space exploration—don’t happen because people rushed into them. They succeed because time is spent thinking, planning, and building a strategy before execution. Not over-planning. Not analysis paralysis. Just deliberate clarity.
It reminded me of a quote I’d heard before but only recently started to truly understand—the kind that feels cliché until it doesn’t. General Dwight D. Eisenhower once said:
“In preparing for battle, I have always found that plans are useless, but planning is indispensable.”
And there it was—my entire TTC approach, condensed into a sentence. The idea isn’t that you must have the perfect plan before you start. It’s that having gone through the act of planning—thinking, sketching, imagining, and evaluating—makes you better equipped when things inevitably change.
That’s what I’d been doing. Letting ideas mature before touching the code. Building mental risk maps. Taking a non-attached first stab. All of it, in service of becoming more adaptable, not more rigid.
How Big Things Get Done validated what I’d discovered through years of trial and frustration: that deep thinking before action isn’t indulgent—it’s insurance. It’s what helps you move quickly once you’re ready, because you’ve already done the heavy lifting in your mind. Even small features and low-priority fixes deserve that moment of clarity.
Because big things get done when small things are done with care.
Vibe Coding and the Risk of Offloading Thought

I’ve been noticing a trend more and more—especially in the era of AI copilots and instant scaffolding tools—and it goes by a name that honestly feels about right: vibe coding.
It’s this approach where developers ride the wave of momentum. They start coding fast, guided by intuition, autocomplete suggestions, and maybe a sprinkle of chat-based prompting. There’s energy to it. Flow. A sense that things are getting done quickly, almost magically.
And I get the appeal. I’ve felt it myself. Vibe coding is fun—until it isn’t... 😬
The problem is, that speed can come at the cost of depth. You might ship something that works—but you won’t always understand why it works. Or how it breaks. Or whether it’s going to haunt your future self when you come back to refactor it six months down the line.
What I worry about most is this: when we offload too much of the thinking, we start to forget how to think like we used to. The quiet engineering instincts—designing for extensibility, anticipating edge cases, building rollback plans—those muscles can atrophy if we stop using them.
I say this not as a rejection of AI tools or the flow state they can help unlock. I use them myself. But I’ve learned to be suspicious of code that feels too easy, too frictionless. Because often, the real work is happening outside the editor—when I’m making tea, brushing my teeth, or standing under the shower, quietly interrogating the idea behind the code. That’s where quality is born.
This is why I’ve come to prefer Time To Convince over vibe-driven commits. It’s not that vibe coding is wrong—it’s just incomplete. Without a moment of pause, a sketch of the risks, a rollback in mind, we’re not building—we’re just assembling.
Conclusion

Looking back, I don’t regret the years I spent racing to solutions. That was part of the journey—part of learning who I was as an engineer and how I wanted to work. But I also know that I’m doing my best work now. Not because I’ve gotten faster or smarter, but because I’ve learned to wait. To think. To let the idea convince me, instead of forcing a solution into place just because I can.
Time To Convince isn’t about being slow—it’s about being sure. And being sure doesn’t always mean writing things down or drawing elaborate diagrams. Sometimes it’s just about giving yourself the space to imagine failure before you commit to a build. To sketch something imperfect, throw it away, and come back better informed. To plan, not because the plan will be perfect, but because the process of planning makes you better equipped to adapt.
I know how tempting it is to ship fast, especially in a world where AI tools whisper that every solution is just a prompt away. But if I’ve learned anything recently, it’s this: thoughtful engineering doesn’t happen by accident. It happens because someone made the time for it. Quiet time. Reflection time. Brew-making, teeth-brushing, pub time 🍻.
And so, I’ll leave you with this: the next time a problem shows up in your backlog or your Slack or your head—don’t race it. Let it sit for a bit. See what unfolds in the background. Give it time to convince you.
You might be surprised by how much better the work turns out when you’re not just solving the problem… but understanding it.