Over the last ten years of writing software at scale, we’ve developed quite a few systems we like to stick to when it comes to how we work. We’ve seen good teams, bad teams, and good teams hamstrung by a lack of best practices, and decided very early on that we weren't going to go down that same road.
All of our work is country scale, so a lack of best practices, growing developer teams, regression-related bugs and so forth mean that engineering progress often grinds to a halt. Where organisations have been built themselves entirely around a mobile app (think ride-sharing, m-commerce, neo-banks, food delivery), the cost of having apps crash or be locked in technical limbo can rapidly rise to millions of dollars.
With that preface, we’d like to talk about some of the ways we think about building healthy, high-performance engineering teams.
Our engineering philosophy
Engineering teams might find themselves feeling disconnected from both the rest of the organisation, and even further from customers who actually use the products. At Obvious, we’ve found that by situating ourselves as “co-owners” of the product experience, looking at the overall organisational goals, and expending effort to understand the impact of what we’re building, we get a better insight into the product.
Engineering exists within a broader organisation, and understanding that larger goal helps the team predict requirements and find ways to make our end users happier. The only way that this happens at scale is if we remain highly aligned with organisational goals, with other teams, and most importantly, with each other. This ensures that we have the autonomy to explore different approaches, normalises failures, and enables trust at scale.
The Obvious Way
Most teams only take direct “costs” into account which are easy to see, such as time to build a feature, design a screen, migrate a database, and so on. However, they fail to take into account indirect costs that come in as a product becomes mature — fixing regressions, identifying and refactoring pain points, improving developer experience, and onboarding new hires. A lot of what we do at Obvious keeps all costs in mind and follow practices to keep them in check.
Having a common vocabulary allows us to be efficient and avoids bike-shedding. Here’s what it looks like:
- Iteration Planning Meetings (IPMs): We evaluate what was (or wasn’t) done in the previous iteration and ensure that we all know what we are doing over the next iteration.
- Daily Standup Meetings (DSMs): We run a daily quick (~10 min) meeting everyday, to surface blockers or issues and keep everyone aware of what’s going on.
- Resilient architecture: In the rapidly moving landscape within which we work, it’s very rare for us to have visibility into the scale and future complexity that may be required. We distinguish between essential complexity and accidental complexity — the second is to be avoided, while the first, inevitable.
- Technical debt: Inevitably, we put something out that’s not perfect: requirements change, we write something in a hurry. We actively work on reducing friction by removing technical debt, even if it means a difficult conversation with another team or a client.
- Release cycles: Having a repeatable, predictable release cycle gives the rest of the organisation confidence that they can build on top of. This helps other teams factor in consistent engineering timelines into their estimates (whether sales, product or even customer support).
- Developer Experience: Understanding and enabling continuous success is an important part of scaling an engineering team.
- Code reviews: At the team level, having regular code reviews ensure that standards and guidelines are followed and for feedback on ideas and approaches to be shared.
- Trunk-based development: Avoiding “merge hell”, reducing distance between developers (which branch-based development does) and setting the stage for continuous review, integration and deployment are key reasons that we practice TBD.
- Regular, readable commits: We absolutely avoid massive code dumps, and do frequent (daily) commits, along with good commit messages. This speeds up code review, writing release notes and helps future maintainers (and us!) understand why we did whatever it is that we did.
- Project management: We use an agile board to plan and estimate engineering effort on projects, often choosing different tools to suit requirements. Some of the tools we recommend are linear.app and clubhouse.io.
Our key takeaways
We’ve seen some encouraging results from this approach. In our small 2-to-3-people teams, we have consistently punched above their weight. We now regularly build products which reach populations in the mid-to-high tens of millions. At that scale, every single product and engineering iteration has the possibility of unlocking massive business value. Our clients now bring us in to help them set up these practices within their own teams, in addition to helping with mission-critical systems.
Like what you see? We’re hiring!
If the Obvious Way makes sense to you, let us meet over virtual coffees. We’ll tell you more about the work that we do, give you the lowdown on life at Obvious, and answer any questions that you might have about engineering or working here. Or if you want to jump straight in, apply to join our team!