As I approach the milestone of 15 years in the software development industry, I want to take a moment to reflect on my journey and share some lessons I’ve gathered along the way.

As you gain experience from different companies, sectors, people, and tech stacks, your perspective and approach to software development, keeps evolving over time.

You realize that some things you once believed or cared about are not as important as you thought, and you begin to see things differently.

Here are five important things I have learned during this journey.

Pick your battles wisely

Language and framework wars, dogmatic beliefs about architecture, design patterns, best practices, etc.

There are many things in software development that I learned are not worth fighting for, especially when they are outside your control.

Be selective and pragmatic about your battles and know when to push for something and when to let go.

Trying to convince people about something when they are clearly not open to challenging their beliefs is a waste of time and energy.

Your time is precious. Focus on what really matters and where you can make a difference.

Engage in meaningful discussions, keep delivering value, solve real problems, and let go of the small stuff.

Everything is about trade-offs. Context is key

There is no silver bullet in software development. Every technology, framework, and tool has its pros and cons. The key is to understand the trade-offs and choose the best tool for the job based on the specific context and requirements.

What works for one person, team or company, might not work for another.

A technology that is perfect for a small startup might not be the best choice for a large enterprise.

Cloud computing might be great for a startup with unpredictable traffic and growth, but a large established enterprise might be better served with a hybrid or on-premise solution.

Microservices and Distributed systems are essential for a company with a large and complex system that serves millions of users to scale, but a small team with a simple application will probably be better off with a monolithic architecture.

The Spotify model might work great for a company with a strong engineering culture and a high degree of autonomy, but it might not be the best fit for a company with a more traditional hierarchical structure.

There are countless examples like this. Think about your own context and adapt accordingly.

Choose “Boring” technology over hype-driven development

The software industry today is very different from when I started 15 years ago. Everything moves so fast in tech that it can be daunting to keep up.

From the early days of Web 2.0, where everything was about the LAMP stack, to the age of the interactive web with concepts like Single Page Applications and countless new JavaScript frameworks, the revolution of Mobile Development, to the current trend of AI.

I have seen PHP declared dead multiple times, the rise and fall of Ruby on Rails, endless debates between JavaScript frameworks, and nowadays people are discussing which LLM is the best.

While it’s undeniable that what you can build with current technology is far more advanced than what we could dream of 15 years ago, and that the software development industry is much more mature and democratized, if you zoom out you will see that some of the basic principles and concepts didn’t change that much.

It’s kind of funny to see how some of the new trends are just old concepts with a new name and a modern twist. For example, Server Side Rendering is a hot topic in modern web frameworks, but it’s not that different from what we used to do with PHP, JSP, ASP, etc.

The mantra, “What is old is new again” seems to be increasingly true in our industry.

This doesn’t mean that you should stop learning new things. One of my principles is to always be learning, and I think that mindset is crucial in our industry, but that doesn’t mean you should jump into every new trend and rebuild all your production systems from scratch. Let it mature first. Build proof of concepts to see if it really solves a problem you have that cannot be solved with your current tech stack.

Boring technology doesn’t mean outdated or legacy. Boring technology is stable, well-known, used in production systems for a while, and has a big community behind it. This post by Dan McKinley is a great read on this topic.

Be curious and experiment with new tech, learn which problems it is trying to solve, take inspiration, but think twice before adopting something new in production systems.

Do you really want to be rebuilding your production systems every couple of years? It´s costly, time-consuming and your customers won’t care about your tech stack, they care about the product and the experience you deliver.

Prioritize Simplicity and Clarity Over Complexity and Magic

I have seen a lot of code written by many engineers with different levels of experience and background and I have learned to appreciate the simplicity of technical solutions.

This might be one of the reasons that Golang really resonates with me, as it is a simple and pragmatic language with a small set of features, but can be powerful enough to build complex systems.

Abstractions and design patterns have their place, but they should be used wisely and only when they add value, not for the sake of using them.

Perfect code does not exist. Do not overthink or try to predict every possible future use case. The key is to build an architecture that is adaptable and can evolve over time as requirements change. Separate concerns, define clear interfaces for inputs and outputs, and keep things simple. Simplicity does not mean lack of structure or organization. It means you have a minimalistic approach that focuses on the essentials.

Think about the people who will read and maintain your code in the future, including yourself.

People matter more than the technology

You might have the best written code, the best architecture, the best tools, and the best processes, but if your users don’t understand how to use your software, or it doesn’t solve a real problem for them, it’s useless.

At the end of the day, software is built by people for people. The technology and tools we use are important, but they are not the most important factor in the success of a project.

Building great software requires collaboration, communication, and empathy.

Focusing on building strong relationships with your team, stakeholders, and users is crucial for delivering successful projects.

Dealing with people is hard. In many cases, it’s harder than the technology itself. But it is also the most rewarding part of our job. Without people, there is no software.