🎯 Chapter Insight
Copying what worked for another team does not guarantee the same result for yours. Processes, frameworks, tools, and engineering practices succeed within a particular context shaped by people, constraints, products, organisations, and technical environments. A practice that solves one team’s problem perfectly may create unnecessary complexity for another.
It is easy to notice the visible parts of a successful engineering team. They may use a certain branching strategy, run daily stand-ups, deploy several times a day, organise themselves around particular roles, or follow a specific software architecture. From the outside, those practices can look like the reason for their success, but copying the ritual without understanding the reasoning can produce very different results.
Pragmatic teams do not adopt practices simply because they are popular, fashionable, or labelled as best practice. They ask what problem the practice was designed to solve, why it worked in its original environment, and whether those same conditions exist in their own team. The lesson is simple: do not imitate the surface. Understand the system underneath it.
💡 Developer Lens
In everyday software engineering, it is tempting to copy successful teams. We read about organisations with impressive engineering cultures and immediately want to adopt their tools, deployment practices, software architecture, meeting formats, or development workflows. If a successful company uses trunk-based development, microservices, feature flags, Kubernetes, or a particular planning process, it can feel reasonable to assume that adopting the same approach will move our team closer to the same results.
But your team is not their team. You have different developers, different skills, different constraints, different customers, different regulatory requirements, different infrastructure, and a different product. The important question is therefore not, “What do successful teams do?” but, “Why does this practice work for them, and does that reasoning apply to us?”
That shift in perspective can prevent a great deal of unnecessary complexity and help teams make more deliberate software engineering decisions.
Best Practices Always Have Context
The phrase “best practice” sounds universal because it suggests that someone has already solved the problem and discovered the right answer. In reality, most software engineering best practices are highly context dependent.
A workflow that is excellent for a team of twenty developers working on a high-traffic cloud platform may be unnecessary for a team of four maintaining an internal business application. A microservice architecture may help an organisation with dozens of autonomous teams deploy independently, while creating operational overhead for a small team working on one tightly connected product. A strict approval process may be valuable in a regulated environment but become pure friction somewhere else.
Even something as common as a branching strategy depends on team size, deployment frequency, release processes, automation, and confidence in the codebase. The practice itself is not automatically good or bad. Its value depends on the problem it solves and the context in which it is used.
Copy the Reasoning, Not the Ritual
When we observe another team’s success, we usually see the result rather than the history that produced it. We see their current architecture, but not the previous architecture that failed. We see their deployment pipeline, but not the incidents that motivated certain safeguards. We see their meeting structure, but not the communication problems those meetings were originally created to solve.
This makes imitation dangerous because we copy the solution without seeing the constraints that shaped it. A large organisation may run a daily coordination meeting because hundreds of people depend on fast-moving shared infrastructure. A five-person team that copies the same meeting may gain nothing from it because the original coordination problem does not exist.
Pragmatic teams try to understand the causal relationship. What problem existed? What changed after the practice was introduced? What trade-offs did it create? Which conditions made it successful? Only then does it make sense to decide whether the idea belongs in your own environment.
Cargo Cult Engineering
This pattern is often described as cargo cult thinking. A team copies the visible behaviours associated with success while missing the underlying reasons those behaviours worked.
In software engineering, this can happen surprisingly easily. A company adopts microservices because large technology companies use them. A team introduces daily stand-ups because agile teams are supposed to have them. An organisation adds more abstraction layers because a respected architecture book showed a similar pattern. A project introduces Kubernetes even though a simpler deployment model would meet every current need.
The individual choices may all be valid in the right situation. The problem appears when they are adopted without understanding which problem they solve. When that happens, engineering practices stop being intentional and become rituals. People follow the steps because that is the process, not because the process is producing a useful outcome.
Architecture Is Especially Vulnerable
Software architecture trends create particularly strong opportunities for imitation. When a technology or architectural style becomes popular, it can start to feel like the default definition of modern software engineering.
But architecture always comes with trade-offs. Microservices can provide independent deployment and scaling, but they also introduce distributed systems complexity, network failure modes, monitoring requirements, deployment coordination, and operational overhead. Event-driven systems can reduce coupling while making execution flow harder to understand. Serverless architectures can simplify infrastructure management while introducing different limitations around execution, observability, and platform dependence.
A modular monolith may sound less fashionable than a distributed architecture, yet it may be exactly the right choice for a particular team and product. Pragmatic software architecture is not about selecting the most impressive pattern. It is about selecting the architecture that fits the actual problem.
Tools Can Become Rituals Too
The same principle applies to software development tools. Teams accumulate tools over time, including static analysers, linters, code formatters, dependency scanners, project management systems, dashboards, deployment platforms, monitoring products, and communication tools.
These tools can all provide genuine value, but every tool also introduces maintenance, configuration, learning, and integration costs. Sometimes a tool continues to exist long after the problem that justified it has disappeared. Nobody removes it because it has become part of the process, and the team may no longer even remember why it was introduced.
That is a useful signal. If nobody can explain the problem a tool or process is solving, it is worth asking whether the team still needs it. Pragmatic teams periodically examine their software engineering practices rather than allowing them to become permanent by default.
Understand the Trade-Offs
Every engineering decision creates advantages and disadvantages. A practice that solves one problem may create another, and evaluating both sides is part of pragmatic software development.
Code reviews can improve quality and spread knowledge, but an overly complicated review process can slow delivery. Automated testing creates confidence, but maintaining low-value tests can consume time without providing useful protection. Documentation preserves knowledge, but documenting everything in extreme detail can create information nobody maintains or reads. Standards improve consistency, but excessive standardisation can prevent teams from adapting to legitimate differences.
The question is not whether a practice has benefits. Almost every popular engineering practice does. The better question is whether those benefits matter enough in your context to justify the costs and trade-offs.
Adapt Instead of Copying
Learning from successful teams is still extremely valuable. The lesson is not to ignore what other organisations do, but to treat their practices as ideas rather than instructions.
Perhaps another team’s process addresses a problem you also have, but you only need part of their solution. Maybe their deployment workflow includes ten stages because of their scale and compliance requirements, while three stages would solve your problem. Perhaps their software architecture uses several services, but the underlying idea you need is simply clearer module boundaries. Maybe their meeting structure exists to improve cross-team communication, while your smaller team could achieve the same goal asynchronously.
Adaptation preserves the useful reasoning while removing unnecessary complexity. In many cases, this is far more pragmatic than adopting an entire framework exactly as someone else designed it.
Frameworks Are Tools, Not Identities
Teams can become strangely attached to frameworks and methodologies. They stop asking whether a particular practice helps because the practice has become part of how the team defines itself.
“We are Scrum.”
“We do Clean Architecture.”
“We are fully microservices.”
“We follow GitFlow.”
The label starts to become more important than the outcome. Pragmatic teams resist this because frameworks, processes, and methodologies are tools, not identities.
If a framework helps solve your problems, use it. If only part of it helps, use that part. If your context changes and the practice stops providing value, change it. The goal is not to implement a methodology correctly. The goal is to build useful software effectively.
Ask What Problem This Solves
One of the simplest ways to avoid ritualised software engineering is to regularly ask, “What problem is this solving?”
Why do we have this meeting? Why do we require this approval? Why do we use this architecture? Why do we create this document? Why do we maintain this tool? Why does this process contain this step?
If there is a clear answer, the practice may still be valuable. If the answer is only, “Because that is how we do it,” then it deserves another look.
Some practices may remain because the reason is still valid. Others may need to change, and some may be ready to disappear completely. Asking this question regularly keeps engineering culture intentional instead of ritualistic.
Engineering Culture Should Evolve
Engineering teams change over time, and software development practices should change with them. A process that worked when the company had five developers may become ineffective with fifty. A deployment approach that made sense when releases happened monthly may become unnecessary after automation improves. A review policy created because the codebase lacked tests may deserve reconsideration once the test suite becomes reliable.
Good engineering culture cannot remain static. Practices should evolve with the environment, and pragmatic teams do not protect processes simply because they once worked. They protect the outcomes those processes were created to achieve.
If a better approach becomes available, they adapt. Continuous improvement applies to the way teams work just as much as it applies to the software they build.
🧭 Reflection
Look at the software engineering practices your team currently follows. Which ones exist because they solve a clearly understood problem, and which ones were copied from another team, framework, blog post, conference talk, or industry trend?
Are there things you call “best practices” without being able to explain why they are best for your particular environment? If you removed the ritual and looked only at the problem it was originally meant to solve, would you choose the same solution today?
Sometimes the practice will still be exactly right. Sometimes you will discover that it needs to be adapted, and sometimes you may realise that the original problem disappeared long ago while the ritual remained.
⚙️ Practical Tip
Pick one recurring process, tool, or engineering practice your team follows and ask why it exists. Identify the problem it is supposed to solve, then look at how your team actually works and ask whether the practice is still solving that problem.
Consider what originally justified it, whether that problem still exists, what value the practice provides today, what cost or friction it introduces, whether you would choose the same approach if designing the process from scratch, and whether a simpler version could achieve the same result.
Keep what provides value, adapt what does not fit, and remove rituals that have lost their purpose. Do not copy success by imitating its appearance. Understand why something works, then decide whether that reasoning belongs in your own context.
🔢 #50 of 53 | The Pragmatic Programmer Series
This post is part of my 53-week series summarizing The Pragmatic Programmer, one timeless principle each week, translated into modern software practice and reflection.








