
The Best Engineering Teams Are Quiet
TL;DR: Engineering autonomy doesn't come from everyone making their own technical decisions. It comes from a team agreeing on how it wants to work, documenting those decisions and trusting everyone to follow them. Decisions can always be challenged and changed. But until they are, the team commits to them. The result is surprisingly quiet: fewer architecture discussions, boring code reviews, less coordination and engineers who can spend more of their time thinking about the product.
One of my main goals when leading an engineering team is to eventually become unnecessary.
It's not because engineering leadership isn't valuable. Quite the opposite.
A lot of the work needs to happen early. The team needs to agree on how it wants to work. What level of quality it expects. How decisions are made. How Product, Design and Engineering collaborate. When an engineer should decide independently and when something needs to involve the team.
If those things remain unclear, the lead becomes the person everyone asks.
If they become clear, something much more interesting happens.
People stop needing permission.
Technical freedom is not the same as autonomy
Companies like to advertise engineering autonomy.
Usually it sounds something like this:
We hire great engineers and give them the freedom to make their own technical decisions.
I like the intention.
I'm less convinced by the implementation.
Imagine five good engineers independently solving the same kinds of problems.
One engineer introduces a new abstraction for data access. Another structures services differently. Someone handles errors in the controller, someone else in the service layer. One feature uses transactions, another solves the same problem with a sequence of independent writes. Tests are organized differently depending on who wrote them.
Everyone had technical freedom.
But the codebase now contains several different answers to the same questions.
And those answers eventually have to be coordinated.
Through code reviews. Architecture meetings. Documentation. Refactoring. Onboarding. Discussions about which of the five patterns should be used for the sixth implementation.
That's not the kind of autonomy I'm interested in.
Autonomy doesn't come from everyone making their own decisions. It comes from a team knowing which decisions have already been made.
Week one starts with how we work
For years, I used a small onboarding presentation whenever I started working with a new engineering team.
It wasn't primarily about the technology stack.
The important part was how we wanted to work together.
We talked about the Agile Manifesto and why I consider Scrum and Kanban tools rather than religions. Different phases of a product can benefit from different processes. The goal isn't to perform Scrum correctly.
The goal is to deliver the best possible product.
We talked about the role of frontend engineers. I consider them particularly important in cross-functional product teams because they sit directly between Design and Backend. That gives them a perspective on inconsistencies and dependencies that few other roles have.
That doesn't make frontend engineering more important than other disciplines. It simply puts the role in an unusually useful position to see where decisions made by different disciplines don't fit together.
We talked about stakeholder management. Managing requirements. Managing dependencies between Product, Design, Frontend and Backend. Managing expectations.
And, above everything else:
Take ownership.
The presentation summarized the idea roughly like this:
- We agree together on how we work and what level of quality we expect.
- You're expected to challenge the process, make suggestions and take ownership.
- We want to be an autonomous team.
But there was an important addition to all of those rules:
Everything is always up for discussion.
A convention is the team's current best answer
I don't think engineering conventions should be treated as eternal truths.
They're simply the best answer the team currently has.
That distinction matters.
If the existing convention says we solve a problem using approach A and a new engineer strongly believes approach B is better, I want them to challenge A.
Bring the arguments. Bring the experience. Build a small prototype if necessary.
Then we discuss it.
If B convinces the team, we change the convention.
If it doesn't, we continue with A.
That can result in a situation where an engineer still personally prefers B.
That's fine.
I disagree, but I commit.
What doesn't work is continuing the discussion independently inside the codebase.
If five engineers are allowed to disagree with a decision by silently implementing their preferred alternatives, we don't really have a team decision anymore.
The ability to challenge every rule is important.
So is the ability to commit after the discussion is over.
Being wrong is part of the system
Sometimes the team changes from A to B and three weeks later discovers that B was a bad idea.
Good.
We learned something.
We discuss what we learned, change the decision and migrate the codebase as completely as reasonably possible.
There shouldn't be a conversation about who originally proposed B.
If the team evaluated the arguments and made the decision together, the team was wrong together.
Experimentation becomes difficult when proposing an idea means personally owning the consequences if it fails.
The responsibility of the team lead is different.
If the team makes a reasonable collective decision and it turns out to be wrong, dealing with the consequences is part of leading the team.
That's what the role is for.
Exceptions should be loud
Of course, conventions don't cover everything.
Products have edge cases. Requirements change. Occasionally you encounter a problem that simply doesn't fit the existing pattern.
That's not a reason to hide the exception.
It's a reason to communicate it.
If an engineer realizes early that a feature requires us to work differently, I want the team to know about it. Sometimes a Draft PR is the easiest place to explore the problem. Sometimes a short meeting is better. Sometimes we need a spike because nobody has enough experience with the problem yet.
Then we decide what we're actually looking at.
Maybe it's genuinely a one-off exception and we're willing to accept the debt.
But surprisingly often, an apparent exception turns out to be something more useful:
a new category of problems.
If we can identify that category, we can extend the convention.
The exception just taught the system something new.
That's one of the ways a codebase can become better over time without becoming increasingly inconsistent.
Solved decisions should become boring
Good conventions don't eliminate engineering decisions.
They distinguish solved decisions from unsolved ones.
Should business logic live in the controller or the service? Where does authorization happen? Which layer owns database access? Where do transactions begin? How do we represent errors? How do we test this kind of operation?
Those can be important engineering decisions the first time.
They shouldn't remain interesting decisions the fiftieth time.
If a team has agreed that controllers deal with transport concerns, services contain business logic and repositories own database access, I don't want every new feature to reopen that architecture discussion.
Follow the existing decision.
If someone discovers a case where that separation doesn't work, that's interesting.
Now we have something worth discussing.
Solved decisions should become boring. Unsolved decisions deserve the team's attention.
Code reviews should be boring too
One of the clearest signs that this is working is code review.
In well-aligned teams I've worked with, most pull requests were remarkably uneventful.
You read the code.
It looks approximately how you expected it to look.
You approve it.
That doesn't mean nobody is reviewing properly. It means there aren't twenty subjective decisions hidden inside every pull request.
The interesting question in a review changes from:
I would have written this differently.
to:
Why was this solved differently?
Most of the time there is no reason to ask that question because the implementation follows patterns the team already understands.
When there is a deliberate deviation, it's usually known before the final review. The engineer raised it early, people discussed it, and the pull request is implementing a decision rather than starting the discussion.
I've seen this work in larger engineering teams and even with freelancers joining existing teams.
Real discussions about deviations from established patterns might happen once or twice in six months.
That's the outcome I want.
Architecture discussions move out of hundreds of individual pull requests and into a handful of deliberate team decisions.
Conventions are guardrails, not a substitute for understanding
This becomes particularly useful when junior engineers join the team.
A consistent codebase gives them examples everywhere.
They don't have to invent an implementation from first principles. They can find something similar, understand the structure and follow it.
Those are guardrails.
But copying a pattern isn't the same as understanding it.
When reviewing code with junior engineers, I liked asking a simple question even when they had implemented something correctly:
Do you know why you did it this way?
Sometimes they knew.
Sometimes the answer was essentially:
"Because everything else in the codebase does it this way."
That's not a bad answer from someone who is learning.
It's the beginning of a much more valuable conversation.
Now the senior engineer can explain why the pattern exists. Which problems we encountered before. Which alternatives we tried. What trade-offs the convention makes.
And importantly, there is time for that conversation because the review isn't consumed by dozens of trivial inconsistencies.
A bad convention says:
Do this because that's how we do it.
A useful convention says:
Do this while you're learning, and we'll teach you why we do it.
Eventually, that junior becomes one of the people capable of challenging the convention.
Writing good code doesn't make you a senior engineer
This also affects how I think about seniority.
If you're very good at writing code and consistently deliver reliable implementations, that's valuable.
But that alone doesn't make you a senior engineer.
A senior should be able to understand and explain why decisions were made.
They should identify risks before those risks become problems. Recognize when a requirement doesn't fit the existing patterns. Challenge conventions with better arguments. Transfer knowledge to less experienced engineers. Understand enough of the product to question whether the requested implementation is actually the right solution.
The more experienced an engineer becomes, the less interesting their ability to type the implementation should become.
Their value increasingly comes from judgment.
For a lead, I expect another layer on top of that:
business understanding.
A lead should understand not only the software and the product, but the environment in which the product needs to succeed.
Give engineers something better to be creative about
Strong conventions don't remove creativity from engineering.
They move it.
I don't particularly want an engineer spending creative energy inventing a new way to structure a service, access the database or handle an error when the team has already solved those problems fifty times.
I want that creativity applied to questions we haven't answered yet.
Why does the user have to complete this workflow at all?
Could this interaction be simpler?
Does this requirement actually solve the customer's problem?
Are we modeling the domain correctly?
Is there an opportunity here that Product or Design hasn't noticed?
Frontend engineers are particularly interesting in this regard.
Because they implement the interface people actually use, they can easily see a design as a user rather than only as an implementation task.
I've repeatedly seen engineers take more ownership of a product and start asking questions like:
Why does the user have to do it this way? Wouldn't this be easier?
Those questions are far more valuable than finding a cleverer way to implement the original ticket.
Of course, this requires engineers who are interested in the product they're building.
Ownership can't be added through a coding convention.
But you can create an environment where people who want to take ownership actually have the time and authority to do it.
Autonomy means knowing when you need the team
There's another misconception about autonomous teams that I think is worth addressing.
Autonomy doesn't mean never asking for help.
I expect exactly the opposite.
An autonomous engineer should be mature enough to recognize when a decision is local and when it could affect the rest of the system.
If it's local and consistent with what we've already agreed on:
Make the decision.
If it introduces a new pattern, creates debt, changes an important convention or exposes something the team hasn't considered before:
Bring in the team.
Autonomy means knowing when you don't need the team, and knowing when you do.
That distinction removes an enormous amount of unnecessary coordination without turning the codebase into a collection of individual preferences.
Communication shouldn't wait for meetings
The same principle applies outside Engineering.
One of the things I emphasized in onboarding was active communication with Design.
Don't wait three days for an official meeting if a ten-minute conversation can resolve the problem now.
Agree on when to review a chunk of work.
Use preview environments.
Pair-review a feature.
Bring engineers into design discussions before everything has been finalized.
The same applies between Frontend and Backend.
If an API follows the conventions both sides already understand, there isn't much to discuss. Communication becomes valuable when requirements change, a dependency is missing or one side discovers that the existing contract doesn't work for a particular case.
The goal isn't to create more communication.
It's to make communication happen at the point where it has the highest value, so we need less coordination later.
A two-minute question today can prevent a handover meeting, a reimplementation and three tickets next week.
The rules should grow with the team
The onboarding presentation I started a project with was never finished.
It grew.
Every time the team encountered a problem that wasn't covered, we had an opportunity to add something.
Every new engineer could challenge decisions that had become invisible to everyone who had been there longer.
That's one reason I think bringing new people into a team is healthy.
They ask questions everyone else has stopped asking.
Why do we do this?
Sometimes the answer is excellent.
Sometimes nobody remembers.
And occasionally you discover that the answer is basically:
We've always done it this way.
That's a good moment to reconsider it.
The other protection against dogmatism is experimentation.
If a team isn't constantly occupied with writing and reviewing unnecessary code, there should be room to explore.
Watch a presentation about a new language or framework capability. Read about a new PostgreSQL release. Explore a different approach to an architectural problem. Build a prototype. Run a spike on something nobody on the team has done before.
Conventions should make the boring parts predictable.
They shouldn't make the team stop learning.
What a mature team feels like
After several months, a good engineering team starts to feel different.
Engineering itself becomes quiet.
Most meetings aren't about engineering anymore. They're conversations with Product and Design about the product.
Handoffs become short.
Designers and engineers review things together when they need to rather than waiting for formal ceremonies.
Frontend and Backend mostly need to talk when something deviates from what they already expect.
Daily status meetings can become asynchronous because nobody needs constant reassurance that everyone else is doing what they said they would do.
Pull requests become boring.
People trust each other.
As a lead, you stop being involved in most decisions.
And instead of dreading the next major change because it means another round of architecture discussions, the team starts looking forward to it.
There's finally something new to solve.
That is the kind of engineering autonomy I'm interested in.
Not a team where everyone is free to build software however they personally prefer.
A team that has spent enough time agreeing on how it works that its members no longer need to constantly coordinate how they work.
The conventions aren't the goal.
The rules aren't the goal.
Even consistency isn't the goal.
Autonomy is the goal.
And when it works, the best engineering teams are quiet.
Quiet doesn't mean inactive. Quiet means aligned.
This is how I build Vuesion
These aren't just ideas I write about. They're principles I've been building into Vuesion for more than eight years.