Pull to refresh

When It's Important to Stop Your Team's Engineers from Writing Code

Reading time5 min
Views813

Launching a startup often means navigating through stringent constraints, particularly in the early stages where resources are limited. For technical founders, who usually possess deep expertise in certain technical domains, the inclination might be to hire a team of senior engineers—considering you often end up with only one expert in each domain, it might be risky to delegate entire segments to junior specialists.

This situation typically leads to a small team where each member is more skilled than the founder in their respective field. This raises an important question for the technical lead: what role should you play in this team? 

While the apparent answer might be task setting and quality control, prompting engineers to do what they love (coding), a less obvious but crucial role emerges. As a leader, your primary responsibility could be to prevent your team from engaging in unnecessary or potentially detrimental tasks, a concept known as "overengineering."

In this article, I will explore the critical role of a technical lead in steering a team away from overengineering and ensuring that their efforts align effectively with the startup's goals and resources.

First Off, Why is Overengineering a Problem?

Overengineering is a significant issue often overlooked in both startups and corporations. Despite senior engineers being viewed as experienced and self-organized, overengineering remains a common problem in practice. 

For example, in startups, it can lead to critical issues like running out of funds, a leading cause of startup failure according to CBInsights. Unnecessary or inefficient work not only wastes resources but can also hinder further development.

Corporations are not immune either. While larger budgets might mask the problem, they can also lead to greater inefficiencies over time. Overengineering inflates development costs by choosing complex over simple solutions, slowing down iteration. 

Additionally, it raises maintenance costs, as complex code is harder to program, test, and modify, compared to simpler alternatives. Ultimately, overengineering can kill products and hinder achieving product-market fit, proving more detrimental than the absence of cutting-edge technologies and techniques.

Why Does Overengineering Occur?

Understanding why overengineering occurs is crucial in addressing its impact on project efficiency and success. This phenomenon can stem from a blend of internal dynamics and individual inclinations within development teams. Generally, overengineering can occur due to several factors:

  • Lack of responsibility

Engineers who write code are often not responsible for running or supporting the entire system. They may also be isolated from product or business decisions, leading to a disconnect between their work and the broader goals of the project. 

Here’s an example from my practice: The engineers on our startup team proposed developing a new microservice for image processing, aimed at producing optimal images for our platform. This could potentially enhance both performance and user experience. However, none of these was critical for the product at that time. Additionally, it would incur costs for development and ongoing maintenance of the new microservice, not to mention adding complexity for the tech lead.

  • Engineers' passion for complexity

Many engineers have a natural inclination to build complex technical systems. This enthusiasm, while valuable, can sometimes lead to overly complicated solutions when simpler ones would suffice. A classic example is an engineer redesigning a website's backend to use the latest technologies and frameworks, even though the current system is adequate. This pursuit of complexity, driven by personal interest, can lead to unnecessary complications.

For instance, at Yandex Educational Services, our development team was working on several products, and new products and business directions emerged frequently. We had a natural desire to unify the development of these products and reuse as much code as possible. I think it's a classic situation in which engineers start building 'frameworks'. In this case, there is a very fine line between useful actions and building unnecessary and harmful things. 

Unfortunately, several times we also made this mistake of  'complex general solutions'—in our case, it was both reusable microservices and components/libs like Django apps. As it turned out, these general solutions often slowed us down and created more obstacles than help. This was because they couldn't account for the differences in future business and product priorities, as well as team processes for different products.

  • Big company environments

In large corporations with nearly unlimited budgets, development teams can be isolated from real-world problems and constraints. This isolation can lead to a lack of understanding of practical needs and result in overengineering. And even though being a large enterprise doesn’t automatically lead to over-engineering, such environment might aggravate the above mentioned reasons.

For example, a development team might create a feature-rich application with numerous advanced options and settings, driven by the abundance of resources. This can lead to a product that is overbuilt for its intended use, ignoring the simplicity and ease of use that might better serve the end-user.

Possible Solutions

First, I'd recommend every engineer and technical leader to get acquainted and deeply absorb two principles which I think are cornerstones in software development (and any engineering work):

This principle advocates for simplicity in design. Engineers and technical leaders should focus on creating solutions that are as simple as possible, avoiding unnecessary complexities. Simple designs are easier to maintain, understand, and integrate, reducing the likelihood of overengineering.

This principle emphasizes avoiding the implementation of features or functionalities until they are truly necessary. It encourages developers to focus on current requirements without overcomplicating the project with speculative features, thereby preventing overengineering and ensuring that the development process remains agile and efficient.

In essence, the philosophy is "simple is better than complex." This concept is universally beneficial across various professions and aligns with one of Steve Jobs' well-known sayings: 

 

Maybe it is the real reason why overengineering happens—it's just harder to make things simple!

Secondly, fostering a sense of responsibility is key. Engineers experiencing the direct impact of overengineering are more likely to appreciate simplicity. Practices such as engineers running and supporting their own code (including DevOps,) and cross-functional teams accountable for both product and business outcomes, are beneficial. The industry fortunately seems to be moving in this direction.

Thirdly, for those managing engineering teams, prioritize maintaining simplicity in your systems. This often outweighs the benefits of cutting-edge technologies, highly optimized performance, or other deep technical aspects. Complexity often arises from business requirements, so keeping a system straightforward can be more crucial than technical intricacies.

In conclusion

The issue of over-complexity in engineering, often underestimated even by seasoned professionals, is challenging to address as it typically requires substantial experience to recognize its detrimental impacts. However, there are definite strategies that can be implemented in both engineering and management roles to tackle this issue effectively. 

Adopting these approaches is crucial, as they can significantly influence the success and efficiency of projects in both the fast-paced startup environment and the structured corporate world. These measures involve not only technical skill development but also a shift in mindset towards valuing simplicity and practicality in problem-solving.

Tags:
Hubs:
Rating0
Comments1

Articles