concept

Over-Engineering

Building capability the requirements do not justify, paying its complexity cost continuously in exchange for flexibility that is rarely used.

pragmatismcomplexitycost

Over-engineering is harder to spot than under-engineering because it looks like professionalism. The system is more capable than it needs to be, and every additional capability is defensible in isolation.

The recognisable forms: microservices for a system one team runs and deploys together; multi-region active-active for an internal tool with a four-hour recovery tolerance; a message broker between two components that could call each other; an abstraction layer over a database nobody will change; a Kubernetes cluster for three services; event sourcing where a table would do; and configurability for requirements nobody has asked for.

The cost is not the build. It is the permanent operational surface: more components to run, patch, monitor and understand; slower onboarding; harder debugging; and a larger blast radius. That cost is paid every week by people who did not make the decision.

The diagnostic questions that work in review. What requirement makes this necessary, stated with a number? What would the simplest thing that could work look like, and specifically why is it insufficient? What is the cost of starting simple and changing later — and if that cost is low, the argument for building it now is weak.

The counterweight to state fairly: some things genuinely must be right early because they are one-way doors, and the judgement is knowing which. Data models, security boundaries and public contracts deserve foresight. Deployment topology usually does not.