How Being Both a Founder and Engineer Changed How I Write Software

There's something clarifying about wearing both the founder and engineer hats. When you're the one who has to sell the product, support the customer, and debug the outage at 2am, your relationship with code changes fundamentally.

I've been building software for years, but founding Versytech and shipping products like BalancingIQ and SOA Assist Pro forced me to confront a question I'd been avoiding as a pure engineer: Does this actually matter?

The Four Questions That Now Guide Every Feature

Before I write a single line of code now, I ask myself four questions. They sound simple, but they filter out a surprising amount of work that feels productive but doesn't move the needle.

1. Who Actually Uses This?

Not "who might use this someday" or "what if a user wants to…" but who, right now, is asking for this? If I can't name a specific customer or use case, I don't build it.

As an engineer, I used to build features because they were interesting or because they made the architecture more "complete." As a founder, I realized that every feature has a carrying cost: maintenance, documentation, support burden, cognitive overhead. If no one's asking for it, it's not a feature, it's tech debt I'm paying interest on.

Example: Early on in BalancingIQ, I wanted to build a sophisticated role-based permissions system with granular controls. But when I talked to customers, they just needed "admin" and "viewer." We shipped the simple version in a day. Months later, still no one has asked for more. That's weeks of engineering time saved.

2. What Happens When It Breaks at 2am?

This one is personal. If you're the founder, you're also the on-call engineer. There's no "escalate to the team" when you are the team.

So before I ship something, I ask: If this fails at 2am, can I understand what went wrong from the logs? Can I roll back safely? Is there a dead man's switch or alert that wakes me up before customers notice?

This mindset has made me ruthless about observability and simplicity. Clever code that saves 10 lines but makes debugging impossible isn't clever, it's a liability. Boring, explicit, well-logged code that I can fix half-asleep is gold.

Example: In SOA Assist Pro, we process Medicare compliance forms that have strict deadlines. If the pipeline fails, people miss submission windows. So every critical step logs to CloudWatch with structured JSON, includes request IDs, and has retry logic with exponential backoff. When something breaks, I know exactly where and why within 30 seconds.

3. Can This Scale Without a Rewrite?

I used to think "premature optimization is the root of all evil" meant you could ignore scalability early on. Now I realize it means: don't over-engineer, but don't paint yourself into a corner either.

As a founder, I can't afford to rewrite the system every six months. So I think ahead, not about hypothetical millions of users, but about whether this design will handle 10x growth without fundamental changes.

Can I add more Lambdas if traffic spikes? Can I partition the database by tenant without a migration? Can I swap out the LLM provider without touching business logic?

Example: In BalancingIQ, we partition customer data by organization ID from day one. It's a simple pattern, every DynamoDB table has `orgId` as the partition key, but it means we can scale horizontally forever. No sharding rewrites, no migration scripts, just add capacity.

4. Does This Reduce Real Cognitive Load?

This is the question I didn't ask when I was purely an engineer. I'd build features that were technically impressive but mentally exhausting to use.

Now I think about cognitive load constantly. Does this feature make the user's life simpler, or does it add one more thing to remember? Does this abstraction make the code easier to reason about, or does it require holding three levels of indirection in your head?

As a founder, you realize: your customers are busy, tired, and distracted. If your product requires a manual to use, you've already lost. If your codebase requires a PhD to modify, you're blocking yourself from shipping fast.

Example: In BalancingIQ, we auto-generate financial insights with AI. Early versions had a complex UI with dropdowns, filters, and customization options. Usage was low. We simplified it to: connect your books, get insights. One button. Usage tripled. Sometimes the best feature is the one you don't build.

What I've Become Ruthless About

Asking these questions has made me ruthless about cutting things that don't pass the test. Here's what I now actively avoid:

Over-Engineering

Engineers love building flexible, extensible systems. But flexibility has a cost: complexity. Every abstraction layer, every plugin system, every "future-proof" interface adds cognitive overhead and maintenance burden.

I used to build systems that could handle any use case. Now I build systems that handle this use case really well. If requirements change, I'll refactor. But I won't carry the weight of hypothetical futures that never arrive.

Shiny Abstractions

New frameworks, new patterns, new paradigms, they're exciting. But they're also risky. Every time you adopt a shiny new abstraction, you're betting that it'll still be maintained, documented, and supported when you need to fix a bug at 2am.

I now favor boring, battle-tested tools. AWS Lambda, DynamoDB, S3. Next.js, React, TypeScript. Python, Rust. These aren't the newest or coolest, but they're reliable, well-documented, and have massive communities. When something breaks, I can find answers in minutes, not days.

"Future-Proofing" That Never Arrives

"What if we need to support multiple payment providers?" "What if we need to run on-prem?" "What if we need to handle billions of records?"

These are valid questions, if they're grounded in reality. But most of the time, they're just fear-driven engineering. You spend weeks building abstractions for problems you don't have, and when the real problems arrive, they look nothing like what you planned for.

I now build for the problems I have today, with an eye toward making future changespossible but not premature. Ship, learn, adapt.

Shipping Reliable Systems Beats Clever Code Every Time

Here's what I've learned wearing both hats: No one cares how clever your code is.They care that it works, that it's fast, that it doesn't lose their data, and that when it breaks, you can fix it quickly.

The most beautiful abstraction in the world doesn't matter if it ships three months late. The most extensible architecture doesn't matter if it crashes under load. The most "future-proof" system doesn't matter if no one uses it.

What matters is:

Being a founder-engineer means constantly balancing: Ship fast vs ship right. Simple vs scalable. Clever vs maintainable. And the answer is almost always: boring, reliable, and shippable beats clever every time.

Building a product as a founder-engineer? I'd love to hear about your experience. Reach out at adamdugan6@gmail.com or connect with me on LinkedIn.