Article summary
I’ve made a lot of mistakes throughout my career as a software developer. These have been so memorable and so instrumental that when people asked me how I got to this point in my career I started answering: “I screwed stuff up until I figured it out.” Some of these mistakes have been small, like breaking the build with a merge. Some of them were big, like introducing a bug into production that causes performance issues so bad we need to emergency patch it.
Others have been huge, like working at a company that didn’t advance my career at all for years. One thing I’ll say for certain though is that making all of these mistakes made me the developer I am today. Let’s dive into the anatomy of a mistake and break down the true repercussions.
Small Mistakes
The most minor of mistakes is just a hiccup in the development process. You introduce a small bug, or break the build, or misread requirements and have to re-do some work. This really is just expected as part of developing software. It can be good to practice being more detail-oriented or implement a better development process, but truthfully this will always happen as we’re all imperfect humans. This doesn’t feel particularly good, but rest easy knowing everyone does this occasionally and management knows this is part of the cost.
These are low-value mistakes. They don’t cost your team or your company very much individually, and you don’t get very much benefit out of each one. Once you’ve done them hundreds of times, however, they can add up. You’ll know a lot of common bugs to look out for, and you’ll have trained your brain to scan requirements carefully, etc. The cost definitely adds up over time as well, but that really should just incentivize companies to implement better practices to minimize them. The cost to you personally is minimal, as anybody with any amount of experience understands this process.
Big Mistakes
This is scary territory. You might commit code to production that ends up crashing your server. Or, maybe you commit to something that ends up getting marketed but it turns out you can’t deliver. These are the kinds of mistakes that developers really fear. The costs of this mistake could be substantial to your company monetarily. Your name could end up whispered through the halls of your office. In some cases, you could even lose your job over it.
The truth is, however, these are high-value mistakes. Each one teaches you and your team something very, very important. You might now realize the value of performance testing before a release. Maybe you now know the danger of promising a marketed feature that locks you into a dangerous position. These tend to be very stressful, but, to be honest, I can typically tell the difference between people that have seen a mistake made, and people that haven’t. Someone who has had the value of tests drilled into them might strongly insist on tests being part of a commit. Sometimes though, it’s very awkward and causes rollover, so it can be okay to add them later in a separate story.
Someone who has seen missing tests bring down production tends to have an immovable ironclad stance that NO code ever gets committed without attached tests. The value of gaining this firsthand knowledge can’t be overstated. There are other ways to learn that, but the lesson itself is so valuable that learning it at all makes the whole mistake worth it.
The Cost of Avoiding Mistakes
We talk a lot about the costs of making mistakes. But, something nobody seems to talk about is the cost of avoiding mistakes. Small mistakes are so common that it’s almost impossible to avoid them. If you attempt that feat, you’re just causing yourself a lot of stress. The only actual way to do it would be to avoid doing things yourself entirely. It might be acceptable to have a mentor or pair go over all your choices and code at the beginning of your career, but soon that won’t work. You’re going to have to do things on your own and risk lots of small mistakes. This is fantastic! This will skyrocket the speed of your learning. While it might be stressful, it’s just part of the learning experience at every level of your career. Trying to 100% avoid mistakes just delays your learning.
Now for the big mistakes. The common wisdom is to avoid making these, and I don’t exactly disagree. These can be costly and stressful and can make you look bad, too. However, it’s important to point out that trying too hard to avoid them can have consequences as well.
Gaining a lot of experience could put you in a position to make important decisions, like application architecture. Taking on these responsibilities puts you in the position to make a far-reaching mistake that could have negative consequences later on. Not taking on the responsibility at all deprives you of an amazing opportunity to gain and refine your skills. At some point, you need to put yourself out there to gain more out of your career. When the big mistake comes (and I promise you it’s as reliable as death or taxes), try to remember you’ve learned something that a lot of other people didn’t have the chance to.
The Path Forward
Now, I’m not saying you should run out and eagerly make as many mistakes as you can. That is almost certainly not the fastest or least stressful way to learn if you have the choice. Not to mention if you’re just making mistakes constantly, companies may not look too favorably on you. I’m just suggesting that you treat them with the respect they deserve. They all taught you something very important one way or another! More importantly than that, however, is that working too hard to avoid them will just be worse for your career than if you just made them and learned from them. No matter where you are in your career, don’t be so afraid of messing up that you miss learning valuable lessons.
Thanks for this. No one ever learned anything without making mistakes but a risk averse culture is ok as long as you can afford it. There is a sweet spot between risk averse but making progress and accepting some defects and risk paranoid making little headway with releases while being stuck in endless testing and review and having your product frozen in time.
I see what you’re saying but I’d go so far as to say a risk averse culture is already going too far. Avoiding certain specific expensive business mistakes makes sense, but generically declaring an entire culture risk averse is probably scaring developers away from making important learning mistakes. Maybe companies can afford being generally risk averse, but it’s bad for individual contributors careers!
Risk averse cultures are not “declared” they evolve through management behaviour and responses to impact of defects (mainly large ones). People working in the system need to notice it is happening and challenge it. It’s the easiest thing for a senior manager to declare more testing is needed or “we must have zero defects” and it’s for the realists to explain (as you have) why this isn’t ideal
As we learn from past mistakes, both our own and these of colleagues, customers etc, is it also important to put these insights into question. For example:
1: The purchasing manager of one of our customers had an issue with his ethernet expansion card that did not survive the OS upgrade from Win95 to Win2000. Therefore he insisted, we must not use expansion cards to grab video data in the system we delivered (there was a workaround but it cost his company a lot of time and money)
2: While learning new programming languages, I tend to keep the behaviors I learned previously. This is sometimes helpful (avoiding nil/NULL where possible) but some experiences are only valid in a certain context: Writing heavily recursive code is almost compulsory in elixir; in C# it causes stack overflows.
Having a recovery plan reduces most stress levels, and makes making mistakes somewhat “fun” again. Mistakes are a key element in learning better ways to do things, and lead to new innovations. And mistakes improve creativity in the long run.
I couldn’t agree more! Also talking about recovery plans for mistakes is a great point. Maybe I’ll make a follow up post for this that talks about some strategies for handling mistakes now that I’ve talked about why they’re a good thing.
Well this is the healthy attitude you should have towards mistakes!
I would say for the “big mistakes”, the goal is not to avoid make them, but more to prevent or minimize their impact. Having procedures that catches mistakes (proper testing, code reviews, proper staging evnironments, phased rollouts, remote telemetry/crash reporting etc.), or dealing effectively with them (e.g. rollbacks etc.) is the way to go.
Also one mistake that I see people making (myself included) is that they think acknowledging a mistake helps them improve or learn. I have realized that, the knowledge that leads to growth comes after first finding the root cause of the mistake and then building a habit or actively making changes so that you not repeat it in the future.