"Original Sins" of a System

It’s Okay, We All Make Mistakes

Yossef Mendelssohn
By Yossef Mendelssohn
March 22, 2023

Sometimes when you’re working on a system, you find something standing in the way of progress that is so baked-in, so foundational, so fundamental that it’s hard to do anything about it. Or it’s even hard to even see at first.

I like to call things like these the “original sins” of a system. This carries a couple of meanings for me: 

  1. It’s a foundational thing, at the origin of the system.
  2. It’s something all systems have. Something is going to be chosen “wrongly” at the start.

That second point is an important one to keep in mind. This was bound to happen, so don’t beat yourself up about it. It’s very likely that you didn’t have the foresight to predict where the system would go and what you’d have to deal with. But even with perfect knowledge, sometimes you have to make decisions at the start to get something moving. Call it what you like — an MVP, or avoiding “boiling the ocean”, or whatever — you need to start somewhere and not cover everything if you want to get moving.

Here’s an example of “original sin”: things belong to a user. Later on, you want to have things belonging to a group of people instead of a single person, so you come up with the idea of an organization. Since things already belong to a user, an easy thing to do is to make something like “team” a subtype of user. And users can belong to teams (which sometimes, confusingly, makes it look like users belong to users).

This isn’t even a very original (in another sense of the word) sin. In fact, it’s distressingly common, to the point that Bullet Train does what it can to keep you out of this particular trap, by starting off with the concept of a Team, and things that you would expect to belong to a person (or User) instead belong to a Team. They have a blog post on this that goes into more detail.

Another example has to do with privacy, with keeping customer data separated. You could have a multi-tenant database and make sure to always include the customer ID in your operations, but that requires a lot of care and slip-ups can be dangerous. And if someone gains access to your database, they can see everything. So instead you decide on a single-tenant solution, where each customer has their own database. Great. But now you’re in the situation where you have to have another system living on top that will know what database to connect to. And that’s not even covering the headaches that come if you want to merge two customers, or when you want to run some operation over a whole swath of customers.

This example, though, covers an important point: sometimes you can’t help but choose between a set of imperfect decisions. There are tradeoffs everywhere.

So what do you do about these “original sins”? Is this just a philosophical nattering exercise? Or is there something helpful here? It may not surprise you that I recommend ADRs. They can help with all sins, original or otherwise. They can help with sins of the past, the present, and the future.

Go over past decisions and make ADRs for them, as best you can. You may not really understand the context or even the decision, but the consequences might be clear to you. Do what you can.

With current or recent decisions, maybe ones heavily informed by significant past ones, you know more of the context and the decision. Make ADRs for these now, and you’ll feel less regret later.

The ideal, where I’d like us all to be, is understanding that the decisions you make are significant and should be thought through and clearly recorded. We’re likely to fall short of this ideal, and then later have to make some ADRs through the fog of memory and/or guesswork. So it goes. Don’t beat yourself up. Just try to do better next time. It’s all we can really hope for.

If you’re looking for a team to help you discover the right thing to build and help you build it, get in touch.