In our First Line of Code series, Commit co-founder Beier talks to prominent tech founders and tech leads building the next generation of companies to hear their experiences and lessons learned from their early days.
Nicholas Clark is the chief technology officer and co-founder of Divvy Homes, a property-technology startup that helps renters become owners. Prior to starting Divvy, Nicholas was the CTO of DoubleDutch, a provider of cloud-based geosocial mobile applications, where he helped scale the engineering team from two to 40 engineers.
Commit co-founder Beier Cai sat down with Nicholas to talk about the early days of Divvy Homes and DoubleDutch and what it was like writing the first lines of code. See the second post here.
Beier: How did you get into software, and what was the first technology you used?
Nicholas: I got my first computer when I was around 10 years old, in the early ’90s. My dad had computers at his office, and when he got a new computer he would bring the old one home.
I had an older brother and a younger brother and we each had our own computers when we were 10 or 11 years old, in our own rooms. My parents got us internet access super early—dial up initially but not even a 56K modem, whatever came before it.
Both my older brother and I taught ourselves how to program when we were kids. I started by taking existing projects, mostly Perl scripts, and changing things to see what would happen. The first thing I ever built was a website that was dedicated to Windows CE, the Microsoft Palm Pilot-like devices. I built it into a fan site where people could submit content, so it was kind of a content management system in the mid to late ‘90s.
Beier: I saw you studied electrical engineering and computer engineering at university and you worked at Microsoft for a few years, then you jumped into the startup world. Can you tell me a bit about that transition?
Nicholas: As a self-taught programmer, I didn’t study computer science. I took some classes, but I built little businesses when I was in college. I built websites and whatnot and contracted my services out. When I was in Microsoft I actually started a mobile software business. I was writing apps in the early 2000s for Palm Pilots and Windows mobile devices.
I always wanted to build a startup—not really knowing what a startup was. After I’d been at Microsoft for four or five years, it became clear that I wasn’t going to learn at the pace I wanted to. There was too much structure and a focus on long ship cycles. I wanted to innovate and iterate quickly.
I happened to come across a four-person startup called DoubleDutch, and I liked the CEO. I was going to be their first engineer. I didn’t really know what to think, I just figured I’ll give it a shot and see what happens. I quit Microsoft to go work there and ended up getting lucky. The company went from four people to 300 over the next four years. And I learned a lot.
It was kind of impulsive, I guess—my logic to go there.
Beier: That’s a pretty bold move, going from a very stable job at Microsoft to a four-person startup as the first engineer. But if you want to learn quickly, it was probably the right move for you.
Nicholas: I think there are a lot of different ways people learn. Some like to read a book, others like to be taught by somebody else. I like to learn by doing. That’s the best way for me to learn a new technology or a new environment or whatever. Just go and do it. So jumping into it felt like the right thing to do.
Beier: Let’s talk about technology. In the early stages of DoubleDutch and Divvy Homes, how did you choose between the modern technology of the day and the technology that you were used to?
Nicholas: I’ll talk about each situation separately, because my thinking has changed quite a bit.
At DoubleDutch, the first line of code was written in C#, so very much from my Microsoft background. It was what I was most comfortable with, given that at that stage of my career I hadn’t played with 500 different languages, but it was a handful. There was so much else I needed to learn about what it meant to be in a startup, what it meant to work with other parts of a company besides engineers. So limiting myself to a technology I already understood made sense.
At Divvy, my mindset was different. It was focused around picking a technology that I’m comfortable using, since in the early stage you have to write a lot of code yourself, but also picking a technology that’s going to be easy to hire for. C# in San Francisco—maybe not the most popular language.
That was the change in my thought processes. It’s not just about what’s most comfortable for you as an individual to use, it’s what allows you to iterate quickly, to hire people to come and work with you.
Beier: These two criteria for choosing a language—your own comfort and the ability to hire people who know it—can be in conflict. Which one do you weigh more heavily?
Nicholas: It depends. If you’re going the venture-funded route, you’re going to be expected to hire a team, so you need to think more about picking a technology you can recruit for.
If you are going the bootstrapping route, I would say overwhelmingly that you should pick a technology you’re comfortable with, because you will likely be writing most of the code. Most startups don’t die because they made a bad technology decision in the beginning, they die because they didn’t find product market fit and iterate quickly enough. So I would say optimize for comfort level, because—worst case—you can start breaking things into services and pick new technology.
Beier: As you were building the initial product and getting product-market fit, and your team was getting bigger, what was your strategy in terms of adopting new technology that seems like it could be a great fit?
Nicholas: Shiny object syndrome—
Beier: Ha! Yes.
Nicholas: I think consistency matters a lot, early on. Having a codebase in which every engineer can read every line of code and understand what’s going on. That’s important, because you want people to be able to unblock themselves by digging into different parts of the codebase.
If you’re always chasing shiny new technologies or tools, you’ll see fragmentation of the technology that your business is using. Which adds a lot of risk, because you have more complexity.
I’m generally against adopting new technology unless there’s a clear reason why that technology allows you to do something that nothing else does. For the most part I can’t think of too many pieces of technology that that’s the case for.
Beier: Have you ever adopted a piece of new technology? How did you do it—was it top-down or bottom-up or a mix of both?
Nicholas: I’m a big fan of prototyping. When I say we shouldn’t just bring new technology into a business, it doesn’t mean we shouldn’t do a quick proof-of-concept, demonstrating what a piece of technology can do. If it creates a worthwhile solution that we couldn’t solve in other ways, I’m all for exploring that.
At DoubleDutch, we were a mobile software company. We built apps for conferences and events—if you’ve ever been to a conference and downloaded an app, we probably made it. At any given time we had 4,000 apps in the app stores. One of the difficulties with that is that any time you needed to ship an update you had to update 4,000 different apps. It made adding new functionality very expensive.
Then we invested in integrating it into our apps so we could have a native application that also benefited from this over-the-air deployment. That’s one of those situations where technology created a solution or an opportunity for us that we couldn’t get through traditional means. To me it felt worth the investment.
That one happened to be more of a top-down directive, although I’ve found it’s generally a good idea to socialize ideas with the team, so they’re supportive of it, rather than just telling people they have to do something.
Beier: Technical debt plays different roles at different stages of a company. When you’re at the early stage you want to move fast, and that involves accumulating debt. But at a later stage you want to be more actively addressing debt. What is your strategy for tackling technical debt with your team, in both the early stage context and more mature later stage?
Nicholas: There are a handful of decisions you should make early on that are critical to get right. I’ll throw some out, though this is not an exhaustive list.
Database backups. That should be something you don’t even think about. Make sure you back up your database hourly, by the minute, whatever—before you even get going.
Certain types of tooling or process. Like, if you’re using GitHub, make sure you require pull requests and code reviews.
I’d say the most important strategy for paying down technical debt is to make decisions early on that minimize how much you end up accruing.
That being said, I like to think of—I hate the term technical debt—opportunities to improve your codebase in terms of business value. At Divvy we manage an engineering roadmap alongside our product roadmap, and every quarter we integrate the two roadmaps so we’re investing in technical improvements that will help quality or velocity or our ability to add certain pieces of functionality as we build the product.
That’s the way that we prioritize. We think, what is the business impact this is going to have?
Early on, business impact focuses on the things that are going to kill you. If we don’t do database backups, or if we don’t stop logging PII in plain text, or if we don’t refactor how we’re modeling certain parts of our data to change with the business, it’s going to become a much bigger problem.
So when we prioritize it, we think, how big of a problem is this? How much work is it going to take to fix it? What’s the urgency? What is the cost of delaying this work? Then we move that to stack rank it.
Beier: One thing I picked up is that you’re an advocate of merging features and technical components and creating visibility, so people aren’t hiding the technical work. It’s all visible to the business stakeholders.
Nicholas: Yes, and to make sure the engineers have time to focus. I think in a lot of companies they’re expected to pay down technical debt and do all of their feature work, and it becomes too much of a burden to actually make progress on technical debt. Actively prioritizing them is important, I think.
Beier: How do you surface up the technical debt? Through the team, or do you have an architect dedicated to do it—or is it a combination of both?
Nicholas: Through the team. We run quarterly road-mapping exercises where the opportunities are sourced by the engineers on the team. You end up with different levels of granularity of problems. Perhaps a more junior engineer sees an opportunity for something to improve within the portion of the code they’re working on. Whereas a more senior engineer might see a pattern that’s a problem across the entire codebase.
We developed an asynchronous process where we sourced a list of opportunities that outlined what the problem is, what the impact to the business value is, the rough ‘t-shirt sizing’ of cost, impact, and urgency. Then we got together and walked through the entire list and adjusted the priorities and picked off the top ones on the list.
Beier: Got it. Would you do it this way in a team of three engineers, or 10 or 20 or 50? At what stage would you think it’s actually worth the more collaborative, coordinated effort?
Nicholas: I think it depends how you’re organized. At Divvy, early on, we were three engineers, each doing different parts of the codebase. Some of this technical debt prioritization was happening with the individual engineers. They’d be working on part of the code that they wrote and they’d clean up some of it.
Everyone probably remembers that moment they had their first bad regression and broke something horribly. I think we were around six or seven engineers when we started noticing patterns or systematic situations that we wanted to start addressing. That’s when we started doing a lightweight version of a roadmap. Once we hit 12 or 14 engineers we started doing this more formal process.
One good strategy is to add as much observability into your system as possible from the beginning. Sentry is a great low-cost tool to group and estimate the impact of errors in your system. There are a handful of tools like that that can help.