Mar 18, 2021

When Velocity Implies Simplicity

Building products is hard. You have to think about the problem you want to solve, the customer you want to delight, design a product through multiple iterations and improve continuously.

In small teams, all hands are on the product, working on anything else can be very expensive in terms of resources allocated. When we look at teams with even fewer people, maybe up to five, time is much more scarce.

When you're building your initial product, you need to get user feedback as quickly as possible, as it is vital to validate your idea and solve the fundamental question of "Can your product be a viable business, or is the environment just not right (yet)?".

Ideally, you'll focus all resources on designing and building the product, acquiring your first customers, and offering the best support out there, driving up user satisfaction, and spreading the word of your product.

In this environment, we want to focus on the product and if possible, only on the product. Especially in engineering, we'd much rather work on shipping features, fixing bugs, and providing a great experience, not on scaling service instances, managing database replication and failover, or which Node.js version to use for all dependencies to work.

Unfortunately, we've created a lot of mostly unnecessary complexity over the years. Kubernetes would be the best example of what not to aim for, even Google admitted it has become too difficult to use on its own.

Sure we get a lot of benefits from a huge ecosystem of languages and systems to choose from, but sometimes it feels as if maintaining a running system can be a full-time job itself.

So, in some cases, when you don't have the resources to spare, it can make sense to choose a couple of proven ("boring") technologies, as you might probably have heard before, so you can focus on building the product instead of fighting your stack the entire day. But this isn't everything.

From deciding on how to deploy your services, to how you host your code or how you'll get notified if your systems aren't running as expected, you'll have to spend time on tasks that are not really the work you'd like to do but are hugely important, as a system that everyone is comfortable working with can save a lot of time, whereas inefficient processes will pile up and slow down everything.

Requirements for Moving Fast

When you want to build your product and iterate quickly, you need to have confidence in your processes. You have to be certain that your code will be deployed successfully in a couple of minutes, that you have tests you can rely on to make sure nothing breaks without noticing, and that any additional errors and incidents will be reported to you.

Make sure to work with technologies you know and think less about whether you should split your architecture up in the tenth microservice or having the most beautiful monolith, I can assure you that no customer will base their decision on whether to buy your product on this.

Allocate your time to figure out not only a great user experience but a great developer experience for your own team. Everybody has to enjoy writing well-tested quality software. If you're lacking test coverage, you're expanding blind spots that can surprise you in the least convenient moments. And if people aren't comfortable working on your project and adding features due to technical debt, you know where to spend your time. Just don't get lost in rabbit holes that don't yield tangible benefits for your team and/or your customers.

Prior to this, you need to have certainty on which features you should spend your time on, which implies a prioritized list of tasks, presumably in an issue tracker. This should be accessible quickly as well, so any bug that comes up can be added. You don't want ten places where your next task could be, you want an ordered list of items to pick from in descending priority and urgency.

One place to take care of all your service insights, logs, metrics, and events will give you the observability required for performing efficient operations, if anything doesn't go as expected and error rates start soaring, you should get notified not hours later but when the issue is occurring, and given the details, you need to perform further investigations.

And last but not least, when you're just starting out with a small team and you need to ship, keep it simple. I know you probably heard this a lot of times now, but it has never been as true. You could learn a lot more or spend more time on the design or implementation, but the value of feedback and getting something out into the public is so much higher than the gradual improvements you could make beforehand.

You shouldn't compromise on quality, but quantity clearly outweighs time-consuming processes you don't have the resources for. And while this is true for most startups, your project might of course be an exception. But if you ask yourself whether you'd rather want to complete tickets in a couple of days instead of weeks and use the remaining time to get feedback and improve what you have, I think you'd get much more out of it.

In the end, choosing what works best for you and your team is the real best practice, but I noticed that for projects big and small, having processes put in place that allow you to move fast without breaking things is quite valuable.