It is exciting to experience fast growth, but often at the cost of reduced velocity. We become nostalgic for when things were smaller, simpler, and quicker.
But, growth does not have to cost us our velocity. This talk is about finding inspiration in software engineering to build teams that ship things, quickly.
Auto-generated transcript - may contain errors.
Tap a timestamp to jump the video.
Hey, good morning. Okay, this is supposed to say move fast and ship things. I assume you've all got a bit of imagination to make that happen. So why am I talking about moving fast and just shipping things? As Brian mentioned, nine years ago I co founded a company here in Edinburgh.
It was my first experience of working in tech. That's when I learned to code. Trial by fire, if you've been in a startup you know what that means. Long story short, we were acquired by Facebook a few years later, and I spent the past four and a half years working on various technologies at a massive scale, building up engineering teams and organizations that could make things happen.
There's only one thing that has really mattered, and that has been consistent all the way from working in a startup to a gigantic tech company is the ability of teams to just ship. And that's the only reason why we write code, why we have growth teams and why we have customers.
Just to make our customers happy, have sticky products, grow revenue streams, or whatever metrics that you really care about. And it's the ability of teams to actually ship and make a difference that matters the most. And I've seen lots of patterns repeating with small teams, large teams, large organizations of hundreds of people, and regardless of the culture of the company, that things start to creep in and just slow teams down.
And if you've been in a startup and then experienced fast growth, you probably know what I mean. Let's see if the next slide turns up. This is oh yeah, there we are. Slide on your right. This is my favorite slide in the deck because it's got nothing on it.
It's empty. You can put whatever you want on it. You've got a few constraints, probably just the screen size and maybe a screen that doesn't work. But that's pretty much all you have. And the feelings I have for this slide is what I feel at the start of a project.
Especially in an early stage company, or if you just started a company, or you're one of the first members on a team. Because you really can do anything. You don't have past decisions that will wing you down. You don't have architecture choices that are just making it really hard.
You don't have things that your past self did that you're starting to question. And if you worked in engineering, this is a common pattern. Now my talk today about moving fast and shipping things is a bit engineering focused, but if you don't come from an engineering background, it's fine.
I will talk about things, I'm quite certain that you'll find parallels regardless of the background you're in. So the early stage of a company, while you're starting off a new project, things are quite effortless. It feels like that. You're putting in energy and things just happen.
It's all nice and smooth. It's just a few people working on problems, things get done, you write code, you ship it, magic happens, hopefully. This is because at the early stage of a project or a company, you're dealing with people sized problems. And by people sized problems, I mean problems that can be understood and resolved in a reasonable amount of time by a couple of people.
And this makes a huge difference when you're a small team. There are fewer people to speak to, fewer people to get buy in from. Solving a problem is just speaking to one other person and getting things done. And even if you're working in a deep tech area and it's a complex area of work, it's quite effortless because the complexity of the overall project and the system is fairly low.
But if you're doing things right, things start to grow. Your team grows, you grow personally, your code base grows, and increasingly things start to feel like this. It's not as effortless, there's a lot of pain involved. As you start shipping things, you put in effort, but you don't really get that back.
Things start to break. Because at this point, you start transitioning into team size problems. As you can guess, team size problems are problems that can be understood and resolved in a reasonable amount of time by teams of people. As you add more teams, as you add more structure, you add more complexity.
But even at this point, you can still get a lot of things right. If the timing of the market is right, your company is generally doing well, you've figured out the right kind of metrics to go after, you're building the right kind of product, your customers are happy, you might find yourself on a rocket ship.
And things feel pretty good because you probably raised a good round of investment, your customers are growing, things look really good. But increasingly, especially if you're in teams working on problems, things feel like a rocket ship on the outside. But as you start shipping code and making things happen, it starts to feel like this.
You're on a slow moving train and you need to shovel out obstacles one after the other. And that's supposed to be what the GIF is about, but there we go. And things are a bit grainy, everything's black and white, and you don't really know what's happening.
It's because the more energy we inject into any kind of a system, whether it's code, processes, people, the faster we build up debt. Now debt is going to be a recurring theme in the stock. And I'm using the way I describe debt is quite broad.
It's not just about the number of bugs you have in your code base, not just about the number of tasks that you have in your backlog. It's things that just increasingly start to creep up and slow you down as a company. And broadly there are two kinds of debt.
There's technical debt. I describe this as the inability to validate decisions quickly. Because this is really why we write code and why we ship products. We have a hypothesis. We do some research, hopefully. Or in the early stage of a company, you're driven by your gut instinct of your founder or a few people.
And you implement that, you ship it, and then hopefully things work out and your hypothesis turns out to be true. And it helps you validate those kinds of decisions really quickly, if you can ship fast enough. And the other kind of debt that builds up is organizational debt.
And this is the inability of organizations to make decisions quickly. Now I've used the word quickly in both cases here because it's really important. There are certain kinds of businesses where you can take all the time in the world, but increasing those are so few.
Especially if you're in a SaaS business or in a high growth market, every moment counts. And this debt that starts to creep up can increasingly also cause a really bad feedback cycle. As technical teams take longer to validate decisions, it gets harder for organizations and companies to validate ideas they have in their business.
When they take longer to make decisions for the business, it slows down engineering teams, or product teams, or marketing teams, to then make decisions because they don't have real input from the rest of the company, and you end up in this downward spiral.
So for the next twenty minutes, I'm going to focus more on this area. It's quite translatable to a lot of things. Organizational debt is a whole other topic. Happy to talk about it on another day. Or if you want to grab me later today, I'm around all day, happy to talk about it then.
And I'd also recommend that you check out Connor from Adminstrate. His talk yesterday about scaling organizations and teams. Lots of good stuff in there about that. So I spoke about people sized problems and team sized problems. This also translates to this broad definition of debt.
Let's talk about people sized debt. At the start of a project, start of a company, things as I mentioned feel quite easy, and you just manage to write code, build products and ship it. I'm going to use a bit of pseudo code to start explaining some of these ideas.
If you're not a coder, it's fine. It's fairly simple, I'll talk through it. If you are a coder, you might understand some of it, hopefully. So let's see what people size debt in an early stage company or a team looks like. So I've got a bunch of pseudo code here.
This is not real code. So most people getting into when you're young and naive in your early days of writing code, as I was, I just believe that there's a problem. I will implement a solution, ship that solution. Job done. In reality, what happens is you've got a function, which is your team, that has to fix a problem.
You've got some kind of amazing solution. And that amazing solution not only returns the solution that needs to ship, but also creates new problems. You've got tech debt that builds up. Maybe you had to implement a spec, and that spec wasn't one hundred percent complete because you didn't have time to make it happen.
You had fifty tasks to get through in that sprint, but you could only really get to ten because of the complexity. Your build system breaks, your production pipeline breaks, you patch it together but still don't manage to fix everything. So if you're not a coder, here's a little flow chart of what that looks like.
To fix a problem, you come with a new solution, you ship it, that generates a bunch of more debt, and you try and fix that debt, and you end up with this feedback loop. This is okay to do in an early stage team, especially if it's a couple of people, it's fine.
If you don't have the market pressure, like breathing down your neck, you can manage to do this and then stay on top of your debt. But this doesn't last very long. Teams quickly pivot into hiding this debt as much as possible. So let's modify that pseudo code that I wrote.
Every time a new solution is created, we end up with new problems. We ship that solution, and then we just put all of those problems into a queue. We'll deal with it later. We all face this. It's a new ticket, a bunch of tickets put into a backlog with the great promise of fixing it in the next sprint, which never really materializes because there's always things to do.
Most teams can still manage to survive this, they go on, they're making impact, they're shipping products, but over time the size of the debt starts to increase. And before you know it, it reaches a point where it starts slowing teams down massively. Things start to break, your build system breaks, bugs that you manage to not address suddenly blow out a proportion, an API you wrote stops working at a massive scale, and things just get harder.
But it's fine, we can still get things done. And this is the point where, again, everything might be on fire, but you're still shipping, making an impact, and your team starts to grow, your company starts to grow, and you start transitioning from people sized debt into team sized debt.
And this is where the growth of debt explodes. You've got your next sprint coming up, right after that you're shipping a new version of your product, you really need to move fast and then everything catches fire, you need to jump in, fix, throw every resource that you have at it, and that little bit of code starts getting refactored, or your team gets refactored to deal with all of those problems first.
So for those of you who don't code, that while section there just basically says, while we have any debt, let's just fix all the debt. And then let's get to shipping whatever we need to ship. But this is a problem, because that section there can take up all the resources you have in the company.
This is a team that's fighting fires by locking up every single resource in the company, and it's frustrating. Product managers are frustrated. Marketing is frustrated. Growth is frustrated. Customer success is frustrated because customers are unhappy. Engineering teams are frustrated too because they just want to ship things and they can't because they're slowed down by all the problems that are starting to build up.
And then the only solution possible at this point is not a blank screen. That's supposed to say, let's spend one sprint just now and delay the launch. So everyone stops work, stops progress, They get buy in from the rest of the company. Everyone agrees that things have to be fixed for them to move on.
And let's see if this turns up. There we go. That tiny chunk of code is now expanded with a bunch of cases. Like, if we've got some debt, let's deal with it, but nobody really knows how much debt they need to deal with, because everything's on fire.
So somebody comes up with an idea to just deal with the biggest debt, but nobody really knows what biggest debt means. The engineering teams can't find consensus about what needs to be fixed because nobody really knows what's broken. Somebody comes up with an idea of just pulling the top ten tasks off their backlog and seeing if that fixes things.
Things get really hacky at this point. Now, I'm showing this as code, but this is how teams function. And at this point, they managed to deal with some of the debt, bend that curve, but at a massive cost. Relationships are frayed, people have worked long nights and weekends, and everybody is frustrated with each other, everyone is frustrated with the codebase, people don't like working with this codebase anymore.
New hires who join the company hate that first two weeks of ramp up, because they can't understand what's happening. They're trying to get help from other members of the team, but nobody's available because they're fighting fires and fixing things. It's absolute chaos. Now I could keep going on with lots of examples and variations of this, but I'm going to stop here for a bit.
I want to summarize a few things and then talk about what can be done to get teams to move faster. So first off, people size problems and debt, which is things that can be understood and fixed by a couple of people or a few people, are usually faster to address, which is why it's easier when you're a smaller team to just move fast and get things done.
Team size problems and debt are harder to address because you require more consensus, you need more buy in, and it takes longer to resolve than fix. But you can't avoid it. Team size problems come with growth. As we grow, we need more people to implement our backlog or the new features or to go into a new market or expand a product.
And team size problems come with growth. There's no way to get around that. And I previously mentioned this. The more energy we inject into the system, the faster we build up debt. I'm going to simplify this further and say any work we do creates more work.
It's what that slide is supposed to say. Any work creates more work. And it's important to recognize this because we often go in with projects thinking that we can just constantly deal with the problems that we have over time. It might be a fixed cost, but not really.
Anything we do will have side effects. You go in to fix a bug, but that fix has an impact on other parts of your code base. You go and improve the speed of your production pipeline, but that has an impact on something else.
But at this point, it all feels really bleak. And I don't want teams at this point to just give up. And we can all have more hope than Dumbledore. So what can we do to address this? First off, we have low tolerance for bad code.
Most engineering teams would hate shipping something like that. That would be ridiculous to ship in production because it would not help me sleep at night. It would not help anyone sleep at night. We hate shipping code like that, but we are okay for teams to function that way.
That's not good. So you've got low tolerance for bad code, but high tolerance for debt. And this just seems to be the case. Over and over again, teams just happen to work this way. It's unfortunate that half the slides don't show up. So this slide is supposed to say what you should be doing is debug your teams and processes with as much care as debugging code.
As engineers, we spend a lot of time improving code quality, arguing about trade offs of one algorithm over another, spending lots of time reviewing each other's code, but there's very little time introspecting what we are doing on a daily basis that actually creates debt and slows us down.
Most teams then figure out, oh, maybe we need to add a bunch of metrics. That's how engineers mostly think. If you are not an engineer and you've tried to work with engineering teams, that's usually the best way to get them to look at problems that you care about, is to show them a metric that's really tanking.
But metrics are imperfect, and metrics hide the truth. So this is a screenshot of a library showing the test coverage of that library. If you're not an engineer, this basically shows how much of the code is covered by tests. This is important, because every time you make a change in the code base and you break something, those tests would then show that you've broken something.
But this just shows you one slice of what your code base looks like without any more information about all the other debt that's building up. The real metric is the time it takes to ship code and validate assumptions. Most teams tend to look at code quality, some static analysis of the code base to figure out if it's any good.
They might look at a whole bunch of other metrics. But the only thing that really matters is the time it takes to ship code and validate assumptions. The only thing that matters is as soon as I write any code, check it in, how long will I see it in production, and how long will I get feedback from customers.
That's the only thing that matters. Everything else is secondary. Also need to pivot from debt elimination to debt management. It's impossible to deal with all the debt that comes up. And most small teams initially just want to fix everything. Most engineers are idealists.
They want to fix everything and get it to a point of perfection. We don't need to do that. If you work in Java or a similar language that works with a virtual machine or similar, you should think about this more like garbage collection.
And it's very similar to your garbage truck showing up once a week to deal with the garbage from your house. Don't have to deal with it constantly, but you need to deal with just enough that gets you over the line. And to do that, teams need to acknowledge that debt is a sunk cost, and it will change over time.
And businesses need to understand this as well. Things will slow you down. Some things will be broken, but hopefully most things will not be broken, and you can deal with the rest of it as a sunk cost for your business. And strategies. You can't have one person on your team jumping in to fix all the problems, because at this point they're so complex that it often requires multiple people who have got the knowledge of the code base or the product to go and fix it.
Spend time in every sprint debrief or whatever agile process you use to discuss debt and tradeoffs. Fixing, as I mentioned, it's about management, not about elimination. So what can you do constantly to manage your debt? And what are those trade offs compared to everything else you need to do?
So two questions I've found work really well with teams. What can we improve in this sprint? What is the impact? Again, you don't have to go and hunt for metrics to prove that. While you're working your code base or while you're working your product, you have a feeling of what needs to be improved.
Capture that in every sprint, dedicate a percentage of time to improving that constantly, don't have a dedicated team fixing all the things that never works. Or even worse, pausing all coding, all product development for a month just so you can fix everything. I've seen teams do that, that's disastrous.
Incentivize debt management and context saving. We talk a lot about context switching, but context saving is just as important. What happens if we don't fix it now, and what context will we need in the future? If we decide to not fix something, or not address some of our debt, let's capture that.
The best place is in your code base, or the documentation that's got a long life. Because in the future, it's either going to be yourself or somebody else on your team or somebody new to the company who needs to know the context of why these decisions were made.
The collective instinct of a team can trump any metric. You can spend all the time you want implementing whatever metrics possible, but there's only one thing that really matters, which is the collective instinct of the team. You know how long it takes to ship code.
You know the problems that you face on a daily basis. That should help guide you. Because metrics can help you understand problems, but they don't describe all problems. And I've seen lots of teams just want to fall back to using metrics to describe everything, but all they are are just tools.
And they don't describe everything. There's always hidden information. So when it comes to moving faster and shipping things, there are lots of things that can help, and there lots of other topics to cover. It could be recruitment, it could be team culture, it could be how organizations are structured, But there's only one thing that I found that has the biggest impact, which is the time it takes to ship code.
And all the focus of a team, especially if you're working in a production team that is shipping things constantly, the only thing that matters is the time to make impact. The time to make impact has the biggest impact on your bottom line. What would that bottom line be?
It could be your revenue, your metrics, so on and so forth. So to summarize, the first thing that I drill down with any team that I work with is that any work creates more work. Let's recognize this, let's acknowledge it, and let's just know that anything we do is going to create more work in the future, and that's a reality of life.
We have to differentiate between team and people sized problems. If I'm managing a two member team, the kinds of problems and challenges we deal with at an engineering level will be very different to a ten member sized team or a one hundred member sized organization working on a code base that is thirty years old.
We should focus more on debt management rather than debt elimination. Don't go and fix everything. And don't go and spend loads of time trying to quantify everything that you do. Rely on what you face as an engineer constantly, just as how we sit in with customers to understand how they use a product.
You know how you use your code base. You should be able to make these decisions quickly and focus on debt management. Context safe for the future. Most likely the future is going to be you, just a future iteration of yourself who wouldn't remember anything of what happened in the past, especially if you're dealing with a massive code base.
So try and save that context as much as possible. And ultimately, how fast you ship and make an impact is what matters. Nothing else. If you're a product team, that's all you should be caring about. And every single thing should be about trying to get your code into production as quickly as possible.
Don't spend weeks on a dev branch that you then need to spend hours a day merging in. You can move much faster. Lots of strategies to do that. Don't spend time trying to fix things in your pipeline that could have lower impact, if there are other things that you can fix that can actually make you ship code faster, more confidently and consistently.
Because there are two things that kill startups. One is the lack of focus, and the second is the inability to ship and really make an impact. And so even at a large company like Facebook, the only thing that mattered ultimately was being able to ship.
Because if you could ship, that was the only way you could make an impact. And if you can make an impact, that's the only way you can improve your product and improve the life of your customers. So if there's one thing you need to take away, whether you are in an engineering team or not, it is just focus on everything that can make you move faster and ship things.
So with that, I'll be around the rest of the day. If you've got ideas or you have things that have worked for you or haven't, I'd love to hear about them or if you have questions, I'll be around. So thank you.