There's a piece of advice I've been seeing a lot lately...reduce friction, protect your engineers' focus, make the common path the easy path, and cut the unnecessary approvals, tickets, and handoffs.
And honestly, I think most of that is good advice. A lot of engineers end up as part-time administrators. They fight with environment setup, hunt for the right doc, and chase a permission across four different teams before they can even start on the actual problem. That stuff should go, no argument from me.
But "reduce friction" isn't the entire idea, at least the way I see it. And the missing half matters a lot more now that AI is in the picture.
AI moved the bottleneck
Coding agents made writing code a lot faster, and by now there are tons of posts about where the work went. It piled up downstream...in planning, in review queues, in QA, in release approvals. PR volume jumped, and delivery dates barely moved.
The fix I keep seeing for that is to reduce friction across the whole delivery process, so all that new code can flow through every step faster. That's where I think it starts to go wrong. When a team decides it has a speed problem, it tends to treat every bit of friction as waste, and some of that friction was actually doing a valuable job.
Two kinds of friction
The way I think about it, there are two piles.
The first is accidental friction...things like environment setup, hunting for docs, and chasing permissions across teams. That's pure tax, and it should go to zero.
The second is essential friction, which is the small "wait, should we?" before a change. In my experience that little pause is the cheapest insurance a team has.
The water filter
To explain this, I like to use an analogy of a water filter. A filter needs friction to catch anything. Take all of the friction away and nothing gets caught...the water just runs straight through. Add too much and nothing flows at all. Clean water comes from getting the balance right between the two.
Code review is friction like that...it's where the risky changes get caught before users find them.
"Make the common path the easy path" is great right up until the common path runs straight through a risky change with no speed bump left on it. Optimize away all the friction, and you usually pull the guardrails out along with the bureaucracy. And it works for a while...you feel fast, right up until that first risky change slips through with a bug in it that impacts every one of your users.
So which kind is it?
I don't have a clever framework for this. For me it comes down to the pros versus the cons. When I look at a step in our process, I ask three questions. Is there a benefit to having this friction? What do we gain by getting rid of it? And what do we lose?
If you run environment setup through those questions, there's no real benefit to it, you get time back by fixing it, and you don't lose anything.
Run the "wait, should we?" before a migration through them and you'd get a little time back by removing it. But you'd also lose the one moment where someone stops and asks whether this change could hurt users.
From my perspective, the teams getting the most out of AI, put the friction where the risk is and strip it out of everywhere else.
So before your team removes the next step from its process, it's worth asking what that step is getting you, and what you'd lose without it.
I'm building Merge Lantern, risk intelligence for small engineering teams. It flags which open pull requests most need senior eyes before they merge, in one short daily digest. It's early, and the first 5 design partners get their first 3 months free. If your team feels this problem, join the waitlist at mergelantern.com.
Top comments (9)
Agree with the two piles. In smart contracts the essential kind is pretty much the whole job, a deploy can't be rolled back, so the "wait, should we?" before a deploy or an upgrade is the one step I'd never cut.
Do you count deploy and config changes in this too? In contracts the code often gets a careful review, and then the deploy script, the constructor args or the multisig settings go out with nobody really looking at them.
I’d count them. “Are we ready to deploy?” is a question that should almost always get asked...and deploys deserve a little friction of their own, in the form of checks. If a team does those checks by hand today, I don’t think the answer is to rip them all out. More than likely the better move is to remove only some of that friction by automating the checks.
Config is more of an “it depends” for me. What is the config actually configuring, and how vital is it? I’ve seen a simple config change bring down a whole system, and I’ve seen others with virtually no impact. It’s an area where big bugs get overlooked easily, so I’d want to know what it configures before deciding how much review it needs.
Fair point on config being "it depends". In contracts a lot of it stops being config after deploy: the oracle address or a fee cap goes in as a constructor arg, sometimes into an immutable, and from then on it's basically code. That's why I'd review the deploy script and its args like code, same diff, same reviewer.
The test I'd add for telling the piles apart: accidental friction slows the work, essential friction slows the decision. The problem is they look identical in a cycle-time dashboard, and the essential kind only proves its value in the incident review nobody connects back to it. How do you defend the "wait, should we?" step when the case against it is measured and the case for it is anecdotal?
In cases like this, I think there’s almost always some kind of number you can find for the anecdotal side. A few I’d look at:
Time today vs time later. Taking an hour today to fix something that could cause hours of downtime later is a valuable number to share. But if the time involved is minimal, that could be a signal you don’t need the pause.
Cost today vs cost later. Businesses understand money, and revenue lost from an outage or disruption is a powerful number. If the cost is low, though, that’s a signal against the “should we?” too.
The company’s priorities. Sometimes the answer to “should we?” is yes...followed by “not right now, we have higher priorities.” That new feature might be the difference between landing a big client or not, keeping an existing one, or stopping users from leaving for a competitor. An imperfect feature can often keep users around and get improved later.
As engineers it’s really easy to get tunnel vision and only focus on the technical impact. But a business is more than the tech...there’s sales, users, customers, finances. Which is why I think it’s so important for engineers to understand more of the business side, so their decisions aren’t just biased toward the tech.
understanding what a change can break is the main work. cutting review time doesn’t remove that work. It just means teams need to be more deliberate about which changes get a closer look.
Agreed...and I think what a change touches is a pretty good guide to which ones get that closer look.
The split between accidental and essential friction is the best framing I've read on this. Kill the environment-setup tax, keep the 'wait, should we?' pause. AI made the code arrive faster, but it didn't make the person who has to say yes any less tired. Saving this one for the next time someone wants to remove review approvals to 'move faster'.
I used to treat all process slowdown as waste. This article makes me stop and ask: what risk are we accepting if we remove this step entirely?