The Other Side of Technical Freedom

Technical freedom sounds great until you realize nobody else is coming to make the difficult calls. Over time, I've learned that being trusted to make technical decisions is less about choosing what I prefer and more about owning the trade-offs that come with them.

The Other Side of Technical Freedom

A few days ago, I wrote something about working on side projects:

Working on your own side project is fun because you can make every technical decision yourself. It's also terrible because you have to make every technical decision yourself.

I originally wrote it as a somewhat funny observation about building something on your own. There is nobody telling you which stack to use, how to structure the application, where to host it, which database to choose, or whether that abstraction you're considering is actually necessary. You get complete technical freedom.

But the more I thought about it, the more I realized I've experienced the same feeling professionally, and it wasn't always funny. Some of the most interesting projects I've worked on have been the ones where the client or team didn't give me an architecture to implement. They gave me a problem and trusted me to figure out the rest.

That's when technical freedom stops feeling like a gift and starts feeling like weight.

When Nobody Is Going to Make the Decision for You

Earlier in my career, technical freedom sounded like the ideal situation: give me the problem, get out of the way, and let me build it.

Over time, I learned there's another side to that arrangement. When people trust you to make technical decisions, eventually you realize that nobody else is coming to make the difficult calls. Should we introduce another dependency or build this ourselves? Is the existing architecture still good enough, or have we reached the point where it needs to change? Do we need to solve this for the next three years, or just get something reliable into production for the next six months? Is the technically cleaner solution actually worth the additional complexity?

There isn't always a senior engineer somewhere above you with the answer. Sometimes you're the person everyone is waiting for.

The first few times that happens, it's a strange feeling. You catch yourself looking around for whoever is supposed to sign off, and slowly realize that person is you. There's no one else's judgment to hide behind if the decision turns out to be wrong.

I felt that very clearly while building a wellbeing and life-planning app from the ground up. I wasn't handed an existing mobile architecture and asked to implement screens inside it. I was responsible for figuring out how the iOS application should be structured, how it would interact with Firebase, where the boundaries between the app and backend logic should live, and how the system would behave when connectivity wasn't reliable.

There wasn't a document somewhere containing the correct answer. Most of those decisions were made with incomplete information about what the product would look like six months or a year later.

What made that uncomfortable wasn't the implementation itself. I knew how to build the pieces. The difficult part was knowing that the structure we chose would shape almost every feature that came afterward. You make the call, ship it, and then wait for reality to tell you whether your assumptions were reasonable.

That changes the way you think about technical decisions. It stops being about being right. It starts being about being accountable.

Freedom Doesn't Mean Building It Your Way

One of the biggest changes in how I think about architecture is that I care much less about whether something matches my personal preferences.

I've worked with technologies and architectures I probably wouldn't have chosen myself, and I've also kept systems in place that I could have redesigned into something I considered cleaner because sometimes changing them would have been the wrong decision.

The team already understood the existing system. The product had deadlines. A migration would introduce risk. The infrastructure was already working. Or the problem simply wasn't important enough to justify the engineering effort.

Having the authority to change something doesn't mean you should.

A recent example reminded me of this while working on a healthcare application that was being moved from a legacy backend to a new GCP environment. From the mobile side, the new integration was essentially ready. I had already built the new path against the real API responses, and switching the application over would have been technically easy.

But when I inspected the production data, there were still signs that content parity wasn't there yet. Test data was present, and some assets the app depended on were missing.

I could have made the switch. The code was ready.

I didn't.

The better decision was to leave the existing backend in place until the rest of the system was actually prepared for the migration. It wasn't the more interesting engineering decision, and it certainly wasn't the cleaner architecture on paper. But changing something simply because your part is ready is a good way to turn a technically successful migration into a production problem.

That kind of restraint has become just as important to me as knowing when to introduce something new.

I think that's one of the easiest traps to fall into when you finally have more technical freedom. You spend years developing opinions about architecture, tooling, frameworks, and engineering practices, and then you reach a position where people actually trust those opinions. It becomes tempting to finally build things "the right way," as if there were one.

Side projects make this same trap obvious from the other direction. When you're building your own product, almost every technical question is open: frontend, backend, database, hosting, authentication, deployment, monitoring, analytics, email, and everything in between. At first, that freedom feels great. Then you realize every decision consumes time and attention that could have gone toward actually building the product.

The same thing happens professionally when a client hands you significant ownership. The absence of constraints doesn't remove the decision-making problem. It just moves the responsibility for creating those constraints onto you.

Which is why I've increasingly found myself asking a short set of questions instead of chasing the "right" architecture:

  • What does this product actually need right now?
  • What is the simplest thing that gives us enough room to grow?
  • What happens if this decision is wrong, and how hard is it to undo?
  • Is this problem even worth solving yet?

Those four questions have saved me from more unnecessary engineering than any architecture pattern I've ever read about.

The Decision Doesn't End When the Code Ships

There's another part of technical freedom that isn't discussed as much: you have to live with your decisions.

An architecture diagram can look perfectly reasonable when you create it. The interesting part happens six months later when another feature needs to fit into it. A dependency can save weeks of development until it becomes difficult to upgrade. A shortcut can be completely justified when you're trying to ship, then quietly become infrastructure everyone depends on.

I saw a version of this with Firebase on that same wellbeing application.

Firebase made a lot of sense early on. We were building a product from scratch, needed to move quickly, and it gave us authentication, storage, data synchronization, and backend capabilities without first building an entire infrastructure team around the product. I would still consider that a reasonable decision. But reasonable decisions still have consequences.

As the product grew, the way the application accessed data started to matter much more. Reads that seem insignificant when the product is small become something you pay attention to when the application has more data and more activity. We eventually put more effort into offline behavior and reducing unnecessary Firebase usage, not because the original decision had suddenly become wrong, but because the conditions around it had changed.

That's an important distinction I've learned over the years: sometimes the architecture doesn't fail. You simply reach the point where the assumptions that made it attractive originally are no longer completely true.

If I were making that decision again, I wouldn't necessarily avoid Firebase. I would think earlier about access patterns, caching, offline behavior, and which pieces of data really need to be synchronized every time. The lesson wasn't that we picked the wrong technology. It was that convenience at the beginning can move complexity somewhere later in the system.

I've also seen the opposite happen: decisions I initially questioned turned out to be perfectly adequate years later, simply because the future I was worried about never arrived. That's part of the job.

The goal isn't to somehow predict every future requirement. It's to understand the trade-offs well enough that you're comfortable owning the consequences, whichever way they go.

When someone trusts you to make the call, they're not expecting you to know the future. They're trusting you to evaluate the situation, make a reasonable decision with the information available, explain why you're making it, and adjust when reality proves one of your assumptions wrong.

Technical Freedom Is Really About Trust

I used to think technical freedom meant being able to build things the way I wanted.

Today I see it differently: technical freedom is being trusted to decide what the right approach means for a particular situation, and living with whatever that decision costs later.

Sometimes that means introducing a new architecture. Sometimes it means keeping the boring system that's already working. Sometimes it means investing in infrastructure before the product grows. And sometimes it means deliberately accepting something imperfect because solving it properly isn't the most important problem yet.

The freedom to make those calls is one of the things I enjoy most about engineering. It's also one of the parts I take much more seriously than I used to.

Because eventually you realize that technical freedom and technical responsibility were never two different things.

They're the same thing, seen from before and after the decision.