Back to Indulge
Distributed Systems Field Notes

2 Articles

March 1, 2026 5 min read

Business-driven Development

What licensing Navengine taught me about distribution

Business-driven Development

The mindset shift - from builder to distributor.

distributed systemsproduct engineering

What if your multi-tenant application could be shipped as a distributed SaaS? What if you could have a licensed version of your product as an installable on some corner of the internet? What if we could break the barrier of what it meant to be a revenue generating company? Let's begin.

Software is the means by which businesses achieve mass distribution. Beyond technical acumen and efficiency, software is the bus through which businesses achieve scale.

Over the quarter, I have been working on software distribution. Specifically: licensing. Think of it in terms of introducing a new avenue of revenue. We dare ask: Do the businesses that value this solution want control over where their data lives? Are they willing to pay a premium over this control?

The answer, in both cases, was yes and that opened a door I had not thought to knock on before.

I had to stop thinking about features and lean towards markets and distribution surfaces. Distribution, in this sense, is not about deployments and pipelines. It is about understanding that different buyers have fundamentally different relationships with trust, compliance, and infrastructure ownership. Your architecture either accommodates those differences or silently forecloses them.

Being technical helped me deploy features product needed. Being business-minded led me to more questions. What would it take to ship this as a product someone else operates? What are we assuming about shared infrastructure that a regulated industry, a government agency, or a security-conscious enterprise would never accept?

The answers to those questions are not found in a ticket or a sprint. They surface when you sit long enough with the business model to let it ask questions back at you.

Licensing as a pricing model

For Navengine, the questions came back as licensing. Once you accept that a buyer might want to run your software in their own environment - air-gapped, on-premise, inside a VPS they control - you need a mechanism that lets the software know it is legitimate without phoning home in ways that violate their security posture. You need entitlements, activation flows, machine-bound licenses and expiry.

Somewhere in the middle of designing the activation flow, I realised the license schema was not a technical artifact. It was a pricing model. The fields I was choosing - seats, features, expiry dates, activation limits - were decisions about how we intended to capture value, just expressed as database columns. Nobody handed me those requirements. I was writing them.

That shift in thinking does not arrive cleanly. It sneaks up on you,. By the time you notice it, it has already changed how you read your own codebase.

The second-order effects arrive

When you decide to support self-hosted deployment, you are not making a DevOps decision. You are ratifying a set of architectural choices that were either made deliberately or inherited by accident. Configuration that was hardcoded because "we only have one environment" now needs to be externalized. Database assumptions that worked fine in a shared-infrastructure model now need isolation boundaries. Upgrade paths that were previously your problem - a migration you ran on a schedule you controlled - become your customer's problem, which means they become your support problem, which means they were always your design problem.

The business-minded engineer understands this before the contract is signed. They look at a feature and ask not just "how do we build this" but "how does this behave when someone else is operating it?" That is a different question and it produces different code. It produces code that fails loudly with actionable errors instead of silently with corrupted state. It produces configuration schema that are documented because they have to be, not because someone found time. It produces container images that carry their dependencies rather than assuming a shared environment that may not exist on the other side of a firewall.

Containerizing Navengine using Flatcar images was not primarily a reliability choice - it was a distribution choice. The image had to be self-contained because I could not know what the environment on the other side looked like. Keygen had to be reachable at activation but not required at runtime, because an installation behind a firewall cannot tolerate a dependency on an external service it may never reach. None of that came from an architecture review. It came from thinking hard about the buyer and working backwards from their constraints.

That backward motion - from buyer to architecture - is the discipline that business-minded engineers practice. It is less intuitive than building forward from requirements, and it is rarely taught, because most engineering education treats the business as a context for the technical problem rather than as a force that shapes the technical solution. But the shape of a system tells you exactly what assumptions its builders made about how it would be used, and by whom, and under what conditions.

A system that can only be operated by its creators is not a product. It is a service wearing a product's clothing.

The distinction matters because services and products scale differently. A service scales with people - support engineers, customer success managers, implementation specialists. A product scales with copies. When you ship a licensed, self-hosted deployment, you are betting that the copy can stand on its own. That bet is won or lost in the architecture, long before the first installation.

None of this is free.

I will not pretend this is clean. Supporting two distribution surfaces - a managed SaaS and a self-hosted licensed product - means every feature has to answer for itself in both worlds. Every abstraction either holds across deployment models or eventually creates a seam you will debug at the worst possible time. The surface area grows and so does the discipline required to keep it coherent.

This is why most teams never do it. Not because it is technically beyond them, but because it requires a kind of thinking that does not come naturally when you are moving fast and the backlog is full. It requires you to slow down and ask what you are actually building - not in terms of features, but in terms of the thing a customer would take ownership of, operate independently, and stake their own reputation on. That is a different standard than passing your test suite. It is a harder one.

But it is also where engineering becomes interesting in a way that pure technical depth rarely matches. When you understand the business well enough to make architectural decisions that preserve future revenue options, you are no longer just implementing someone else's vision. You are shaping the product's possible futures. That is leverage of a different kind - not the leverage of writing faster code or designing more elegant abstractions, but the leverage of making choices today that compound into distribution tomorrow.

John Carmack once said the most important thing an engineer can do is build full product skills. I used to read that as advice about career positioning. Working through this, I think it means something more specific: learn to see the economic system your technical system lives in. Features are temporary. Architectural commitments are long. A business model encoded in a data structure outlasts the engineer who designed it.

The business-minded engineer does not stop caring about the craft. If anything, they care more - because they understand what the craft is in service of. Every clean abstraction is a future operator's sanity. Every well-chosen failure mode is a support ticket that never gets filed. Every deployment boundary that was thought through carefully is a market that remains reachable.

Software is the means by which businesses achieve mass distribution. You already knew that. The question is whether the software you are writing is ready to be distributed - not just deployed, not just maintained, but handed to someone else, in a corner of the internet you will never see, running a business you will never fully understand, solving a problem you helped make solvable.

Becoming a business-minded engineer doesn't mean every engineer should be writing pricing decks. It means understanding that every architectural choice is also a business choice - and that some of the most impactful technical work you'll do is quietly expanding the distribution surface of the thing you're building.

That is the bar. Build to it.

Share this article

Stay Updated

Get research notes, engineering insights, and essays delivered to your inbox. No spam, unsubscribe anytime.

Marvin Kweyu

Research Scientist & Software Engineer building scalable systems that solve real-world problems in agriculture, urban tech, and beyond.

Connect

hello@marvinkweyu.net

© 2026 Marvin Kweyu. All rights reserved.

Built with curiosity and code.