Here's a story I tell my mentees often—and it's one where I almost made an expensive mistake.
A few years ago, my team was tasked with rebuilding the authentication system for one of our core products. We walked into that room with a massive assumption already locked and loaded: "Authentication isn't our core business. We should buy, not build."
It made perfect sense on paper. We assumed buying a vendor solution like Auth0 would be faster, safer, and cheaper. We assumed building it ourselves was risky—authentication is hard, right? If you mess it up, you leak credentials, you destroy trust, you crater the business. It felt like the "smart senior engineer" decision to make.
But when we looked at the price tag, we hesitated. It was expensive. We were about to commit to substantial annual licensing fees, multi-year contracts, and integration work that everyone assumed was "just configuration."
So, we did something uncomfortable: we challenged our own "smart" assumption.
We looked deeper. We found that OAuth 2.0 is actually very standardized and prescriptive. We realized that integrating an external vendor with our complex web of internal legacy identity providers was going to be a nightmare regardless of who wrote the auth server. The hard part wasn't the OAuth protocol—it was mapping our Byzantine internal user hierarchies and permission structures.
So we decided to be naive. We decided to build it.
The result? It took us one quarter. It cost us a fraction of the vendor price—saving substantial licensing fees annually. It's been running in production for years, scaling to multiple brands.
Don't get me wrong—buying isn't bad. We don't build Git from scratch; we don't build VMware from scratch. But in this specific case, the "obvious" choice was the wrong one. We nearly let a safe assumption cost us six figures and lock us into a decision we'd regret for years.
This experience taught me a lesson that defines how I lead today: Engineering isn't about being right. It's about getting it right. And the only way to get it right is to relentlessly challenge your assumptions.
Assumptions Are Hidden Technical Debt
We talk a lot about technical debt in code—variables named temp2, lack of tests, hardcoded values. But there is a much more dangerous kind of debt: Decision Inertia.
Every time you say, "Well, we just use Git because that's what we use," or "We can't rewrite this legacy app, it's too big," or "We can't move off this bare-metal MySQL cluster, it's too stateful," you are taking out a loan. You are deferring the work of thinking. You are snowballing unverified beliefs into a mountain of constraints that eventually makes it impossible to move.
Why do we do this?
Survivorship Bias: We see that legacy system running and assume it's just "old code"—but forget it solved real business problems that still exist today. That spaghetti monolith? It handles edge cases you don't even know about yet.
Vendor Demo Trap: We've all seen the slick demo where the vendor solution handles every use case with one click. But we forget that the integration is always harder than the demo, and our snowflake infrastructure never fits their assumptions.
Migration PTSD: We've been burned by past migrations that went sideways—databases that didn't replicate correctly, services that couldn't handle production load. So we assume this one will fail too, even when the circumstances are completely different.
If you want to grow from a senior engineer to a principal or staff level, you have to stop accepting "that's just how it is" as an answer.
Assumptions are the hidden technical debt of architecture.
The ACT Framework
Over the years, I've leaned on a simple mental model to help teams break out of this inertia. I call it the ACT Framework.
Full disclosure: This isn't some new magic. It's the scientific method, simplified and repackaged for the chaos of daily engineering. I use it because it's memorable enough to apply in the heat of the moment, without needing a textbook to recall the steps.
1. Awareness
You can't fix what you don't see. Most of the time, we aren't even aware we're making an assumption.
- Recognize the trap: You assume the train knows the way to the destination until you end up in the wrong city.
- The Daily Question: Ask yourself, "What is one thing I am taking for granted today?"
- Challenge "Facts": Maybe it's that your database needs to run on bare metal. Maybe it's that a service needs to be written in Go. Be aware of the "facts" that are actually just habits.
2. Challenge
Once you spot an assumption, poke it. Even if you think it's right, challenge it anyway.
- "What if we didn't use Kubernetes for this?"
- "What if we did rewrite this 10-year-old monolith?"
- "What if the 'industry standard' doesn't apply to our specific constraints?"
This fosters psychological safety. When you normalize challenging ideas, you create an environment where people aren't afraid to be wrong. You shift the focus from "Who has the best idea?" to "What is the best idea?"
3. Test (Evidence is King)
This is the most critical step. Challenging without testing is just intellectual debate—it's just noise.
- Start small: We didn't build the whole thing first; we spun up a quick POC and load-tested it.
- Gather data: We ran benchmarks and proved that modern virtualized instances could match or exceed the bare metal performance we thought we needed.
- Decide with evidence: Opinions are cheap. Senior engineers have opinions; Staff engineers have data.
Scaling to the Team: The Assumption Audit
The ACT framework is great for checking your own biases, but challenging assumptions is ultimately a team sport. If you're the only one doing it, you'll quickly become "that person" who blocks every PR with philosophical questions. You need to bring the team along.
I like to use a technique called Inversion during design reviews.
Instead of asking "Is this the right choice?", I ask the room:
"What conditions would have to be true for the **opposite* of this decision to be the right choice?"*
This forces the team to articulate the hidden constraints they are assuming exist.
For example, if the team assumes "We must use Microservices," the inversion asks: "What would have to be true for a Monolith to be the better choice here?"
Usually, the answer is something like, "Well, we'd need to not care about independent deployments." And then you can check: "Do we actually care about independent deployments for this specific internal tool?"
Here's the irony: we platform teams spend all day promoting microservices to product engineers—"decouple your domains!" "independent deployability!"—but then we turn around and build monolithic internal tools because "it's just for us" and "we don't need to scale that." When you invert your own assumptions, you often find you're giving advice you don't follow.
Suddenly, the assumption is visible. Now you can debate the constraint, not the solution.
The Power of Naive Questions
There is a trap that experienced engineers fall into. We get cynical. We've seen projects fail, we've seen technologies hype cycle and die, and we start to assume that "it's complicated" means "it's impossible."
The most valuable engineers I know retain a degree of "naivety"—the willingness to ask "How hard can it be?" even when the "smart" answer is "don't even try."
I saw this play out recently when someone asked if we could make our database infrastructure fully self-service using Ansible and Terraform. The room went quiet. Databases are the third rail—stateful, critical, full of subtle operational constraints.
I could have said no. I could have cited all the reasons it wouldn't work—stateful workloads are different, replication is hard, compliance adds complexity, we'd need a whole platform team just for this.
But instead, I said: "I don't know. How hard can it be? Let's try and find out."
We gave ourselves one quarter to prove it could work. We defined clear success criteria: spin up a production-ready, compliant Postgres instance in under an hour. The first attempt took three weeks and broke in spectacular ways. But we learned. We iterated. We automated the pain points one by one.
Nine months later, you can spin up a production-ready, compliant Postgres instance in minutes with a single PR. We unlocked velocity that we assumed was impossible because we were willing to try.
The lesson? Sometimes "it's complicated" is true. But sometimes it's just a story we tell ourselves to avoid the work of finding out.
How to Sell the Risk
Now, I can hear you saying: "This sounds great, Alex, but my PM wants this feature shipped yesterday. I don't have time to play scientist."
I get it. The pressure is real.
When you challenge an assumption—especially a "safe" one like buying a vendor or using a standard library—you are introducing risk. You are trading certainty (even if it's expensive or slow) for uncertainty.
Management hates uncertainty. So, don't sell them uncertainty. Sell them a Timeboxed Spike.
Here is the script I use:
"I have a hunch this assumption might be wrong. Give me 2 days to verify it. If I'm right, we save weeks of complexity and significant budget. If I'm wrong, we lost 2 days. Is that a trade you're willing to make?"
Why does this work?
- Capped Downside: You explicitly state the maximum loss (2 days).
- Asymmetric Upside: The potential gain (weeks of time, budget) massively outweighs the cost.
- Business Language: You aren't asking to "refactor" or "explore"; you are proposing a calculated bet with positive expected value.
Most reasonable leaders will take that bet every single time.
The Goal: The Best Answer Wins
If you take one thing from this post, let it be this: Check your ego at the door.
Challenging assumptions isn't about being the smartest person in the room who points out logical fallacies. It's about vulnerability. It's about saying, "I might be wrong about this, and I want to find out."
It's uncomfortable. It requires you to talk to other teams, to push back on managers, to question legacy decisions made by people who are still at the company.
But that is the job.
The best engineers I know are the ones who are happiest when their own assumptions are proven wrong—because that means they just learned something, and the team is about to build something better.
So, here is my challenge to you: What is one assumption you are holding onto right now?
Document it. Challenge it. Test it.
You might just save your company a significant amount of budget, or better yet, you might build something you didn't know was possible.


Top comments (0)