3 min read

Keeping Patterns Consistent: Guardrails and Culture

After reading Design Principle: Composable Services someone asked "How do you keep consistency with this approach long-term?", noting that they've seen it tried, but eventually things get out of hand. It's a good question and not something I touched on in either that post, or my post on Platform Engineering. But, the answer is mostly the same. The teams I’ve seen keep up the consistency of ever improving patterns well, tend to accomplish it with a mix of guardrails, golden paths, and culture.

Guardrails

Guardrails are typically handled in the codebase or pipelines. Using linters for line and complexity limits is the goal here. If a service starts growing in logical branches, that's a signal we may need to extract things into smaller, more defined services.

Beyond automated linting, another guardrail is ensuring files, namespaces, modules, and classes are all well named and well organized in the codebase. This helps to reduce future drift by ensuring the right home for a new class is obvious. I believe that the more unnecessary questions that have to be answered (where should this class go?), the more time will be lost and the more chaos will ensue.

Golden Paths & Culture

In addition to your actual codebase, the other way teams are successful at keeping up consistency is through organizational culture. In practice this means having good documentation with real examples. Include "why, what, and how" write-ups with real examples that engineers can copy. If we're talking about composable services, for example, then explain the composition rules, why services should do one unit of work, and why only orchestrators compose them. Point to real examples in the codebase. You want to describe and show the golden paths that engineers should follow.

Now, this doesn't mean new golden paths can't appear later, but when they do, it should be discussed and it should be intentional. I've heard this described as an "architecture menu" by former colleagues and that phrase is something I've always liked. Choose from the menu or explain why you need to do something off-menu and how it'll work to get buy-in.

Engineering teams aren't static, either, so if you want consistency and patterns to endure, this needs to be addressed at onboarding. When new engineers onboard, take the time to go over the architecture and the patterns. Explain why the team does these things, walk through examples, and answer questions. Questions typically mean you can go back and improve documentation.

Code review is where engineers should be reinforcing agreed upon golden paths and that those patterns are being used as intended. Take the ego out of code review (always good advice) and point to agreed upon patterns if something doesn't align. Better yet, ask, don't tell, if you don't think something aligns. When you can point back to things the team is aligned with and is written down then it's not a person constantly picking on someone who doesn't follow what everyone agreed to, it's the team asking that person to conform to the agreed upon consistency.

There will always be a situation in a healthy organization where you have to be pragmatic, you need to cut a corner, and get something shipped now. That's fine. But make sure your organization also values fast follows to cleanup things like this. Ship now, but write up and schedule a ticket for after release, so things can become consistent quickly. The longer inconsistencies linger the more inconsistencies will grow and the more they grow, the harder they are to get back aligned.

Above all, it is incredibly important for the senior engineers on the team to model the pattern, adhere to processes when introducing new patterns, and call out deviations early. This is stewardship and technical leadership and it's one of the many things every organization should expect from their senior engineers.

Linting rules can be overridden, so culture has to carry it in the end. People need to care, and new folks need to understand why they should care.

Making the Case

Engineering teams may run up against pushback from the "business side" on time spent cleaning up or paying down technical debt. While that framing of "business vs engineering" happens in a lot of places, it's not ideal. The goal should be for engineering to be seen as thoughtful and pragmatic partners, not as a separate entity with different priorities. When engineering and the rest of the organization are aligned on investing in consistency, everyone benefits.

The key is showing that consistency and well-defined patterns reduce bugs and actually make the team faster over time. Track metrics like how long it takes to ship a feature built on existing patterns versus a new one, or compare their defect rates. A cut corner might seem harmless, but if you keep cutting them, the square product you thought you were shipping slowly becomes a circle that rolls away from you.