A few months ago, CodePen co-founders Chris Coyier and Alex Vazquez spent an hour reflecting on the top 10 lessons they've learned over the last decade of work at CodePen. The entire episode is value-packed; but, the one lesson that has haunted me is 6: One thing at a time (jump to track). And, I just wanted to take a moment and amplify their message.
The whole point of running a company is to solve problems. As Alex teases in the episode, if they weren't solving any problems, they'd be out of business. But, when it comes to solving problems, Alex stresses that only one new problem should be solved at a time.
The example he gives in the episode is "learning Golang". Understanding how to use Golang was a new problem for the company. As such, in order to start integrating Golang into their work, they applied it in the context of an already-solved problem: sending emails. This way, Golang was the "one thing" they were solving—the email-sending logic already existed in Ruby; and, they just had to port it over to a new application server.
This lesson hits me hard in the feels because when I reflect on my own work history, some of the biggest mistakes that I've made in my career revolve around trying to solve multiple problems at the same time. Perhaps one of the most embarrassing examples of this is when I attempting to learn OOP (Object Oriented Programming) on a new project. This was two problems: I had to build a new application; and, I tried to do it in a new programming paradigm.
Needless to say, the project ended up coming in months late and was a horrible mess of hard-to-maintain code. Trying to solve two problems at the same time ended in disaster.
If It Can't Be Done Incrementally, Don't Do It
If I could be so bold as to add a corollary to the rule of "one new problem at a time", I'd suggest that if it can't be done incrementally, don't do it. Over the last 6-years, feature flags have revolutionized the way that I work. And, a majority-stake in that change is the fact that everything I do is now built and integrated incrementally. Until you've worked this way, it's hard to even articulate why this is so powerful. But, I literally can't imagine building anything of any significance without an incremental path forward.
When you build and integrate code incrementally as a rule, you are forced to think about the work differently. You have to break it up into smaller problems. And, the order in which those problems are solved (and integrated) starts to matters. This, in turn, allows you - and your external stakeholders - to create a better sense of how long things will take, how often value will be added, how far the project is progressing, and how the path forward (and expectations regarding delivery) might need to be adjusted.
This is another example of the power of constraints. When we apply constraints - either implicitly or artificially - to our work, we are forced to think more deeply and more creatively. And this ultimately leads to better outcomes.
Well said. Focusing on one problem at a time also forces you to prioritize so that your time is well spent.
Totally agreed - and it also means that you can much more easily switch focus briefly if you need to adjust your work. And, if you work incrementally, then the value that you've already built has already been delivered.
This is a rather simple but profound read! This week I have flown into HQ to start discussions with PM and Co. about a rewrite of a product that is 20+ years of unmaintained code, bad decisions built upon bad decisions as I call it, we have quite the task ahead of us.
I think this is something I need to get the team to adopt as we begin building the new frameworks and foundation, as well as developing the requested features. Easier said than done tho.
If I can give you a warning, my company is in the 5th-year of a ground-up rewrite! 😱 I beg of you, do things incrementally!! But, in all seriousness, good luck to your team, I hope things go smoothly.
Congrats on making Hacker news! Was browsing through it and saw your domain😀.
Thanks! Someone just showed me on Twitter - so random what gets traction. But, I'm happy someone found some value in this.
I haven't read through the comments yet, but here's the Hacker News link if anyone is curious -- https://news.ycombinator.com/item?id=33523032
I'm familiar from experience of the stakeholder need for incremental changes. However, I do wonder if sometimes the existing codebase may be too far gone and incremental changes are far more costly than a rewrite by someone who knows what they're doing (obviously I'm speaking of a personal experience, but with good reason.)
First off, great name 😉 second, I agree. There are always exceptions to the rule. Even within the span of my own company - InVision - we did a complete rewrite of the front-end (v1 -> v2) going from separate jQuery-based pages to an AngularJS single page application (SPA). And, it was quite successful.
On the other hand, we did / are still doing a complete rewrite of both the front-end and the back-end (v6 -> v7); and, it's take several years and is not done and has many feature parity "compromises." I would call this second rewrite significantly less successful (and it probably should not have happened).
I think it ultimately comes down to knowing what problem you're actually solving. If you are very clean on your intentions, and you can see the path forward, then doing "more" can be good. But, if you're unclean as to why you're changing stuff, then scope creep can easily appear, and suddenly things are spinning out of control before you even know what happened.
Thanks for sharing those examples. I'm not sure if this was the case in that v6 to v7 rewrite, but I can definitely see that rewriting with a new language and/or set of tools, without key members having experience with those things, can quickly multiply estimates as devs explore and negotiate the architecture and stack with stakeholders. Ideally the company would have the opportunity to build a greenfield project with the target stack before deciding on a rewrite of the existing product.
Yeah, exactly. We really just didn't have the expertise to build the new system in the way we built it. We were solving lots of problems at the same time.
A well written article. I would even say that this can apply to other type of technical works outside of coding.
Working with as a consultant in infrastructure, i had a lot of those moments where the costumer or the employer had to know that it would be a mess if we solve multiple problems at the time.
Even though the tought of "two birds with one stone" are appealing, it can make things harder at the long run.
Changing infrastructure is a fascinating topic unto itself. It's one of those things where you think the "abstractions" mean that you can do things quietly, behind the scenes, and your application developers don't have to know about it. But, changing infrastructure inevitably has unseen consequences on the application that "bleed through" the abstraction layer and start causing issues in the applications. Best to only change the infrastructure (and not the code) so that at least you can see which changes are causing issues.
Even to this day, after switching to K8 (Kubernetes) years ago, there are still strange bugs and timing issue that show up in the app that I don't know how to solve. For some reason, K8 will take a pod out of rotation ... and keep sending it traffic as it is shutting down. So frustrating!