RethinkDB operates like a tribe (or, more accurately, a band). We spend a lot of time together, and have a shared set of goals and values. We’re also small enough that decisions can be made by consensus, but big enough that no one person could keep track of everything going on. Under these circumstances, we evolved a simple and effective decision making process.
The vast majority of decisions are made by consensus. The relevant people get together, interrogate the issue for a while, and voluntarily arrive at a unanimous decision. When a decision is reached, everyone goes off and does the work. Most technical and many non-technical decisions are made this way. This process is self-sustaining — it works smoothly on its own, and requires very little management. However, there are circumstances where this process breaks down.
Occasionally when matters of taste are involved, consensus cannot be reached. When discussions don’t converge to a unanimous decision, I (as a product lead) appoint a tie-breaker who makes the final decision. Typically, it’s a person who has really good taste at the relevant class of issues.
We currently have three official tie-breakers — one for coding style, one for language design, and one for visual design. We also have many informal tie-breakers — people who are masters of their craft that others trust to make good decisions and concede to their judgment in case of ties. Between consensus and tie-breakers, we can resolve close to 99% of all issues.
Occasionally, the team arrives at unanimous consensus and I feel the decision is wrong. Usually it means something about the underlying goals or values had to change to accommodate reality, but I failed to communicate it to the team. (One example of this is being user-focused). Most of the time I can sit everyone down, explain my concerns, and have everyone re-evaluate the decision. In some cases, it takes time for people to adjust, in which case I have to override their decision by authority.
Our company is small enough and everyone here is talented and mobile enough that I can’t use formal authority to enforce my will (nor would I want to). I have to use the political capital I’ve built up, which requires an enormous degree of bilateral trust. I have to trust people to do their jobs, and they have to trust me to accept decisions they disagree with. Cultivating this trust is a big part of what makes RethinkDB tick.
The way we work is only possible because everyone on our team consistently displays the following qualities:
There is one more quality that doesn’t necessarily follow from the process outlined above, but is so important it deserves a special mention:
In aggregate, these questions provide a good framework for deciding whether someone is a good fit for the team (and conversely, whether the team is a good fit for them).
When you feel that people don’t consistently display these qualities, you have to let them go. It doesn’t necessarily mean the person isn’t good at their job (it’s never up to you to make that judgment), but it does mean they’re probably not a good fit for your company. I say “probably” because there is never a way to be sure until later. Firing is fraught with strong emotions, especially when you’re first placed in a position to do it.
“Fire fast” is a conventional wisdom and a cliche, but it’s correct, and it’s a cliche because most people still screw it up. It took me years to learn that I have to let people who don’t fit find their own way, and that firing slowly is unfair to my team, myself, and the person who’s being kept in the wrong job.
Remember — your first responsibility is to your team. Fire quickly, be compassionate about it, and get the person out of a job that doesn’t fit.