In the fast-paced world of software development, we often fall into the trap of grand, sweeping changes. We dream of complete overhauls, ground-up rewrites, and revolutionary new systems. But here’s a hard truth: these all-or-nothing propositions are often a recipe for disaster.
Let’s talk about incrementality. It’s not glamorous. It doesn’t make for exciting presentations or bold mission statements. But it’s the secret weapon of successful engineering teams everywhere.
Consider a recent example from my time at Airbnb. We aimed to add a critical feature to our device testing lab for end-to-end testing, promising faster and more comprehensive test runs. The project hinged on the edge networking team developing a safe VPN tunneling solution, initially estimated to take one quarter. However, this dependency stretched to nine months due to unforeseen complexities, security challenges, and competing priorities, leaving our e2e testing project in limbo and causing cascading delays across multiple teams.
This experience starkly illustrates the pitfalls of all-or-nothing thinking in software engineering. Complex systems are prone to unexpected challenges and shifting priorities. Our mistake wasn’t in trusting the edge networking team, but in failing to plan for contingencies and interim solutions. It underscores the critical need for incremental progress and flexible planning, breaking large projects into smaller, independently valuable pieces that can deliver benefits even when other components face delays.
This isn’t just an Airbnb problem. It’s an industry-wide issue. We get caught up in the allure of the perfect solution, the comprehensive fix. We convince ourselves that if we just wait a little longer, we’ll have everything we need to do it “right.”
But software doesn’t work that way. Neither does business.
Instead of waiting for the perfect solution, we should have broken the project into smaller, manageable pieces. We could have implemented an interim solution, something that got us 80% of the way there without the network dependency. Then, we could have iterated, improved, and adapted as new capabilities became available.
This approach does more than just deliver results faster. It de-risks the entire project. By shipping incremental improvements, we get real-world feedback earlier. We catch issues before they become critical. We build momentum and maintain team morale.
Incrementality isn’t about lowering our standards or settling for less. It’s about recognizing that progress is better than perfection. It’s about understanding that in the real world, requirements change, technologies evolve, and businesses pivot. By working incrementally, we stay flexible and responsive to these changes.
So how do we put this into practice?
- Break big projects into smaller, independently valuable pieces.
- Prioritize these pieces based on immediate value and feasibility.
- Ship early and often, even if it means using temporary solutions.
- Gather feedback and iterate rapidly.
- Be transparent about the incremental nature of the work to set proper expectations.
Remember, every line of code you ship is a line of code that’s providing value, being tested, and moving you closer to your ultimate goal. Every feature you roll out is an opportunity to learn and improve.
The next time you’re faced with a big project or a daunting dependency, resist the urge to wait for everything to be perfect. Instead, ask yourself: “What can we do right now, with what we have, to move in the right direction?”
Incrementality isn’t just a development strategy. It’s a mindset. Embrace it, and watch as your projects start delivering value sooner, adapting to change more easily, and ultimately succeeding more often.
In software engineering, as in life, the journey of a thousand miles begins with a single step. So take that step. Then take another. Before you know it, you’ll have traveled further than you ever thought possible.