12/5/2024
Understanding when and where to invest in software quality, and how to build systems that last
Written by: Jonathan Haas
In my last post, I argued against perfectionism in startup environments. Today, I want to explore the other side of that coin: when quality really matters, and why craft isn’t just about satisfying our engineering ego.
While perfect shouldn’t be the enemy of good, there’s a corollary worth examining: quick-and-dirty shouldn’t be the enemy of sustainable. I’ve seen teams take the “move fast” mantra too far, creating problems that would haunt them for years:
At ThreatKey, we learned that certain areas of our system demanded uncompromising quality from day one. These weren’t always obvious at first, but they became clear as we scaled:
When handling security data, there’s no room for “we’ll fix it later.” Customer data needs to be reliable, consistent, and protected from the start. Refactoring data models after they’re in production is exponentially more difficult than getting them right initially.
// This isn't over-engineering, it's essential protection:
interface AuditEvent {
readonly id: string;
readonly timestamp: Date;
readonly actor: Actor;
readonly action: AuditedAction;
readonly target: AuditTarget;
readonly metadata: Readonly<Record<string, unknown>>;
}
Auth is another area where “MVP” thinking can be dangerous. We invested heavily in our permission system early, and it paid dividends as we added enterprise features:
Public APIs are like contracts - breaking changes can destroy trust. We learned to treat API design with the respect it deserves:
In certain markets, quality itself becomes a key differentiator. For security tools like ThreatKey, customers actively evaluate:
These aren’t nice-to-haves; they’re core purchase criteria. In such markets, cutting corners on quality isn’t just technical debt - it’s market debt.
The key is developing what I call “quality intuition” - knowing where to invest in excellence and where to accept good enough. Here’s my framework:
Quality isn’t just about code - it’s about culture. Here’s how we foster it:
Quality investments compound over time:
Every team needs to find its own quality equilibrium. Here’s how to start:
The art of software engineering isn’t about choosing between speed and quality - it’s about knowing when each matters most. Build too fast everywhere, and you’ll create a house of cards. Build too carefully everywhere, and you’ll never ship. The magic happens when you can do both: move fast where speed matters, and build solid where quality counts.
The next time someone says “we need to move faster,” ask them what they’re willing to sacrifice. And the next time someone insists on perfection, ask them what they’re willing to delay. The answers to those questions will guide you to the right balance for your team and product.