Over the last ten years of writing software at scale, we’ve become quite opinionated about how we work. Here’s how we code, the Obvious Way.
Over the last ten years of writing software at scale, we’ve become rather opinionated about how we work. We’ve seen good teams, bad teams, and good teams hamstrung by a lack of best practices.
All of our work is “country-scale”, which means it goes out to millions of people every day. A lack of best practices, growing developer teams, regression-related bugs and so forth mean that engineering progress often grinds to a halt. Where orgs have been built themselves entirely around a mobile app (think ride-sharing, m-commerce, neobanks, 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.
Engineering teams often think of themselves 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, by looking at the overall org goals, and by expending effort to understand the impact of what we’re building helps us to get a better insight into the product.
Engineering exists within a broader organisation, and understanding that larger goal helps the team to 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 — time to build a feature, design a screen, migrate a database, etc. 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, onboarding new hires etc. 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): 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 (at a broad level).
- 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 org 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 you!) understand why you did whatever it is that you did.
- Project management: Pivotal Tracker is our current go-to for managing complex software projects. You’re welcome to look through the Pivotal board of one of our active open-source projects, which is representative of how we use it.
We’ve seen some encouraging results from this approach. Our small — 2-3 people — teams 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 buy you breakfast. 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 jump straight in, and apply to join our team!