If there’s one lesson I learned as a first-time software CEO–it’s this saying from the military: “Slow is smooth, and smooth is fast.”
Startup CEOs place too much emphasis on initial speed. They focus on “rapid iteration,” “failing fast,” or “moving fast and breaking things.” That’s so early 2000s. Outside of the ideation phase, it was always bad advice. What worked for Facebook probably won’t work for you for too many reasons to enumerate. But even more, this strategy hasn’t always worked for Facebook. Facebook moved fast and now it has broken too many “things”–most notably its trust with its customers.
We’re moving into a post-strategy business world. It’s a world where every startup knows the right strategy. Every business is a technology business. And every technology business is competing in winner-take-all markets with varying degrees of network effects. So execution determines the winner. She who executes best wins.
Execution in code-based businesses requires technical knowledge. If you want to optimize your chance of success, you should acquire technical knowledge. I taught myself how to code. You don’t need to do that, but you will need to understand the principles in this article. Plenty of CEOs will succeed with little or no technical knowledge. But that success comes in spite of their lack of technical knowledge not because of it.
It turns out winning is mainly about velocity. But you will only achieve maximum velocity indirectly–by creating smoothness first. Going after velocity right from the start will actually slow you down in the middle- and long-run.
In this post, I’ll talk about how to avoid the biggest rookie mistake first-time software CEOs make, how to avoid technical debt and build technical assets, and how to achieve maximum velocity. We’ll talk about:
- Getting Boat Raced: Technical Debt at Capshare
- What Is Technical Debt?
- The Psychology of Technical Debt
- Building Technical Assets
- Conclusion: Winning the Mid-Game
But first a little background.
Getting Boat Raced: Technical Debt at Capshare
Focusing too much on initial speed nearly killed my last startup Capshare. I spent 6 years feeling seconds away from becoming a washed-up, middle-aged entrepreneur marooned on the island of misfit startup ideas.
About 11 years ago, I taught myself how to code in Ruby. Having previously worked in Venture Capital, I felt like having a deep understanding of software would provide me with a long-term career advantage.
I used my newfound coding skills to write the first version of Capshare. I loved being able to envision what I wanted and realize that vision without relying on others. In the early days of Capshare we moved fast.
By fast, I mean we wrote awful code rapidly. We busted out “features” in weeks. In our biggest gift to our future selves, we wrote the core of our code base especially rapidly. My philosophy about testing our code at the time was to test only if it felt helpful. Since “speed” was all I cared about and testing slowed us down, we never tested our code.
Many developers feel so strongly about testing that they recommended writing tests first and never writing an untested line of code. We ignored those “old-school voices” that didn’t understand how “real startups work.”
I started noticing problems when our biggest competitor raised their Series A. This was the time we most needed to stay feature competitive. But we found that maintaining our code base had become a game of technical whack-a-mole. Our code was riddled with bugs. We would fix one bug only to find two more.
The technical term for these kinds of bugs is regressions. This is a classic sign of technical debt (we’ll discuss that in the next section). Regressions are a specific kind of bug where code that previously worked in one area no longer does so after new code is added. Regressions are particularly problematic because they show that parts of the code are connected in ways that are difficult to understand. I.e., you change code in section A and suddenly code stops working section X. Regressions are almost impossible to cure without testing.
I knew we had a big problem when a senior developer we hired tendered his resignation 2 days later. He said he had no idea how bad our technical debt problem was and he didn’t sign up for years of solving it. After spending an entire day, I persuaded him to stay but he agreed only if I made getting our code under testing harness our top priority.
Two years later–no joke–we finally got our code base tested enough to begin to add features in a meaningful way. By that time, we had become a distant second in our industry. We got boat raced.
I got a front row seat to our own technical-debt-fueled meltdown. I didn’t know about technical debt. And even if I had, I wouldn’t have thought it should concern the CEO.
What Is Technical Debt?
“The fast pace that characterized the past 12-18 months, when you would germinate an idea and write the code in less than a few days, has evaporated. Suddenly, the product and engineering teams are bogged down. Every innovation requires a Herculean effort to achieve. Why? Why does this fact pattern evolve in many software companies? Here are the most common reasons I’ve seen. First, technical debt. The freewheeling, hedonistic days of idea to instantiation in an instant are over. They’ve left you with the hangover of technical debt.”–Tomasz Tunguz, “Why Product Innovation Slows After the Series A”
Software is complex. Being great at building software means being great at managing complexity. It has to start with the CEO. Very few first-time CEOs have the self-control to reign in the urge to go on a technical-debt-fueled feature spending spree.
So let’s make sure you understand what technical debt is. Ward Cunningham, a software developer, coined the term in a report in 1992. Technical debt is the accumulation of problems with your software’s code that makes every subsequent change to the code base more difficult. Just like credit card debt, it often feels great to spend freely until the debt comes due.
I typically like to think of technical debt in the following 3 buckets:
- How well tested your code is (test coverage)
- How easy your code is to understand (understandability)
- How easy it is to build on to the code (extensibility)
Here’s a little graphic to display what I call the 3 Heads of the Technical Debt Hydra:
Of the three, the first (test coverage) is the most important. It subtly forces a developer to do the other two. But more than anything, it makes code easier to refactor. And refactoring is how you pay down technical debt. Refactoring is the process of rewriting code to improve it.
Testing also gets your code under “harness.” Tom Tunguz put this way in a recent article:
“There’s a colloquialism for a collection of testing software within the quality assurance world: harness. The idea is to harness the furious efforts of the thoroughbred engineering team into a smooth release process that ensures few errors for customers in production. At this stage, the mot juste isn’t a harness, but a yoke, a heavy wooden cross beam braced across the shoulders of oxen.”Tomasz Tunguz, “Why Product Innovation Slows After the Series A”
Personally, I think of the testing “harness” a bit differently. Modern software is probably the most complicated thing that humans can still handle. It is so complex that it can easily get out of control and become totally unmanageable. Testing is what straps in all that complexity and makes it manageable. That’s why we call it getting software under “harness.” Complex software itself is the thoroughbred horse that requires a harness.
Refactoring is critical because as we will discuss next even the best code requires refactoring and technical debt (on some level) is unavoidable.
The Psychology of Technical Debt
“Annual income twenty pounds, annual expenditure nineteen [pounds] nineteen [shillings] and six [pence], result happiness. Annual income twenty pounds, annual expenditure twenty pounds ought and six, result misery.”–Charles Dickens
I really like this diagram created by Martin Fowler. It really helps clarify the psychology that often accompanies tech debt decisions.
It would be easy to interpret this graph as justifying some tech debt. In my opinion you should almost never justify technical debt. In other words, making a conscious choice to accept technical debt should probably happen once or twice in the life of your company.
But what about “prudent accidental” tech debt? There’s nothing you can do about that right?
Even accidental technical while on some level “excusable” could be risky enough to sink a startup. So my interpretation of “prudent accidental” tech debt is debt you incur after doing everything you can to avoid even accidental tech debt.
You will certainly get some things wrong in your code. Not all refactoring is due to technical debt. Fixing or extending your software to handle use cases you really couldn’t have foreseen isn’t technical debt. I haven’t seen a single startup (even from my VC days) get it completely right from the start. But there is a gigantic difference between those who build the right way and those who don’t. That brings us to our last topic, something I’m going to call Technical Assets.
Building Technical Assets
“It must have seemed to our competitors that we had some kind of secret weapon– that we were decoding their Enigma traffic or something. In fact we did have a secret weapon, but it was simpler than they realized. No one was leaking news of their features to us. We were just able to develop software faster than anyone thought possible.”—Paul Graham, “Beating the Averages”
As a technical CEO you should care a lot about technical velocity.
Technical velocity is the speed with which you can make valuable additions to your code base. Technical velocity is the precursor to product velocity, which is a precursor to winning the game of execution.
Remember where we started “slow is smooth and smooth is fast.” It’s counter-intuitive but the fastest route to your optimal velocity is to go slow at first until you achieve “technical smoothness.” Then you will be able to reach a velocity you didn’t think was possible.
You’ll do this by creating the opposite of technical debt. What is the opposite of technical debt? I’ll call it Technical Assets. Technical Assets take all these ideas we’ve been discussing and give you a road map for turning them into competitive advantages.
Debt has compounding interest that makes it harder and harder to pay off. Conversely, technical assets create smoothness, a velocity-inducing lubricant, that leads to competitive advantages that grow over time.
Great. So how do you create technical assets?
I’ve created a list for you!
Here are 6 Ways Technical CEOs Can Avoid Technical Debt and Build Technical Assets:
- Take time to build the “core” right
- Celebrate technical victories
- Test, test, test
- Develop your technical skill
- Get involved (with care and humility) in technical decisions
- Refuse to succumb to the “ship it now” reflex
#1 Take Time to Build the “Core” Right
Not all of your code has equal importance. Code that touches lots of other code is generally more important. In networking theory parlance, branch nodes are more important than leaf nodes.
Get to a clear understanding of what the core of your system is before you build it. Coding is so much more expensive than discussing, white boarding, flow charting, etc. Diagram out what you need to build. Write pseudo-code before actual code. Then stress-test your thinking like crazy with the smartest people you know.
#2 Celebrate Technical Victories
“Private victories always precede public victories. You can’t invert that process any more than you can harvest a crop before you plant it.”–Stephen R. Covey
Technical victories will precede product victories. Product victories will precede revenue victories. Technical victories will be much more private. So it’s even more important for you as a CEO to foster and celebrate them. The world and VCs won’t care about them nearly as much as revenue. But this is how you will get revenue. Don’t forget where your bread is buttered.
#3 Test, Test, Test
Testing is the single best way to build prevent technical debt and foster technical assets. Don’t work with a CTO who doesn’t agree with you about the importance of testing. Shun engineers who don’t believe in testing. Create a testing culture. Always try to use automated tests before hiring human QA.
Testing is a whole art and science in its own right. Not all tests are created equal. Knowing what to test, how to write tests, and how extensively to test something is critical. But we’ll have to discuss that in another post.
#4 Develop Your Technical Skill
Could you imagine being a car company CEO without knowing anything about manufacturing? How do you expect to be an effective software CEO if you’ve don’t know anything about coding? Start reading. Take an introductory coding course. There are tons of resources if you start looking.
Then remember humility. The only thing worse than a software CEO who knows nothing about coding is a software CEO who thinks she’s an expert after taking an online course.
#5 Get Involved In Technical Decisions
Technical decisions always have business impact. Often they have the biggest impact of all decisions for a software company. So involve yourself in the technical decisions. Ask your CTO to walk you through the decision in layperson terms.
Ideally as your technical knowledge ramps and you gain experience as a CEO, your input will become extremely valuable as you make important technical decisions.
#6 Refuse To Succumb to the “Ship It Now” Reflex
The biggest impulse of every first time CEO will be to rush out features as quickly as possible. Learn to almost enjoy that feeling of losing in the short run. Put differently, build trust that if you invest heavily in technical assets you will appear to lose the first lap of the race but you’ll end up lapping your competition.
Conclusion: Winning The Mid-Game
“This is not just a theoretical question. Software is a very competitive business, prone to natural monopolies. A company that gets software written faster and better will, all other things being equal, put its competitors out of business. And when you’re starting a startup, you feel this very keenly. Startups tend to be an all or nothing proposition. You either get rich, or you get nothing. In a startup, if you bet on the wrong technology, your competitors will crush you.”—Paul Graham, “Beating the Averages”
Experts have studied opening sequences and end games in most board games (like Chess) extensively. But it’s harder to find strategies for the mid-game. Similarly, startup CEOs get plenty of advice about how to start out and iterate rapidly. But there’s no real advice about how to win the middle of your journey.
Technical velocity is key to winning in software. It’s counter-intuitive but reaching optimal velocity requires slowing down at first to build technical assets. You’ll feel like your losing in the first lap of the race. But if you develop the skill to build technical assets, you’ll end up lapping your competition and winning the mid-game.