I started writing code professionally in 2012. This year marks eleven years. The milestone prompts a kind of stock-taking that I find useful to do in writing.

This is not a career advice post. It’s a personal retrospective on what happened, what I learned, and what I’d change — useful mostly as a data point rather than a prescription.

What Compounded

Technical depth compounds. The fundamentals I invested time in during the first five years — JVM internals, hardware architecture, distributed systems theory — are still directly useful. They didn’t become obsolete when I moved to Go, or when large language models became a major part of the work. The ability to read assembly output, understand cache hierarchy effects, reason about concurrent state — these are frameworks for thinking that apply beyond any specific technology.

The shallow skills — knowing a specific library API, familiarity with a particular framework — don’t compound in the same way. They’re useful while you use them and then they’re historical knowledge.

Writing compounds. The practice of writing clearly about technical things has made me better at both the writing and the thinking. Working through how to explain something in writing forces a precision that verbal explanation doesn’t. Posts I wrote in 2013 are things I still reference when explaining these concepts to others.

Relationships compound slowly and then suddenly. The engineers I worked with at the trading firm, stayed in touch with, collaborated with later — these relationships are more valuable now than they were when they formed. Not strategically (I wasn’t thinking about networks), just organically. People move through interesting roles and institutions. Knowing someone who’s been doing good work for a decade is different from meeting someone who’s been doing good work for a year.

What Surprised Me

Soft skills are technical skills. The most technically excellent engineers I’ve worked with were also excellent communicators, clear thinkers about tradeoffs, and effective at working across organisational boundaries. The separation between “technical” and “soft” skills is a false one. Both are skills, both can be improved, and both matter for doing good engineering work.

Depth and breadth reinforce each other. I initially thought of technical career choices as choosing between specialisation and breadth. In practice, going deep in systems performance made me better at distributed systems because I understood the physical constraints. Going deep in Clojure’s immutable data model made me better at concurrent Go because I’d thought carefully about shared state. Depth in any technical area teaches you how to think rigorously, which transfers.

The unglamorous work determines the outcome. The most impactful engineering contributions I’ve made weren’t the clever algorithms or the novel architectures — they were the reliability improvements that prevented 3am pages, the observability work that made incidents fast to diagnose, the documentation that prevented repeated debugging sessions. These weren’t exciting to work on. They compounded quietly over years.

Companies matter more than roles. The environment you work in — the quality of the engineers around you, the quality of the problems, the standards for what “good” means — shapes your development more than the specific role you have. I’ve learned more in well-run teams at roles below my “level” than in poorly-run teams at senior roles.

The Decisions I’d Make Differently

Stay longer in the first role. The trading firm was formative. Three years was long enough to learn a lot; it would have been long enough to go significantly deeper. I moved on partly from restlessness, not because I’d extracted all the learning available. Depth comes from staying with a problem long enough to see its second and third-order complexities.

Invest earlier in building and shipping things publicly. Projects I built internally at companies are not visible. Projects I shipped openly — libraries, tools, writing — are visible and useful to others. I did more of this later than earlier, and I’d shift the balance.

Ask more questions earlier. The instinct to figure things out yourself before asking is valuable up to a point. Past that point, it’s a time tax. The senior engineers and technical leads around you in early career are unusually accessible repositories of experience. Using them well is not a sign of inadequacy.

What I’d Tell Someone at the Start

Care about what you build. Not sentimentally — practically. Engineers who are genuinely interested in the problem domain build better systems than engineers who are indifferent. Find work where you’re curious about the domain, not just the technology.

Measure before concluding. This is the most transferable skill from the performance work. Don’t assume — measure. Applies to code, to architecture decisions, to people management, to career choices.

The boring fundamentals compound. Computer architecture, operating systems, networking, distributed systems theory, software design principles — these feel slower to learn than the new framework of the month. They pay back for decades.

The career is long. Decisions that feel permanent aren’t. Technologies that feel mandatory to learn are often irrelevant in five years. Skills that feel niche generalise in unexpected ways. The appropriate horizon for most career decisions is years, not months.


Eleven years is long enough to see how things compound and how things don’t. The pattern that seems clearest: the investments in deep, transferable skills and genuine relationships paid more than any specific career decision or technology choice. The regrets are mostly about depth missed, not opportunities missed.