There is one mistake I’ve made in the course of my career that stands out as being the “biggest screw up of my career.” Before this mistake, I felt like an unstoppable programmer – and as such, I had a bit of an ego problem. It was a case in which I should’ve checked myself before I wrecked myself, but in the end, it caused me to grow and become a more humble developer.
Zooming out, my first job as a rails developer was an interesting experience for me. I was young and hungry, eager to make a difference at the company I was working for, and prove myself as a contributing team member. I, like most developers, joined a small team of developers. Through sheer work ethic and long work days, I was able to get responsibility for a small project. This project quickly grew to be an important part of how our company made money.
Despite my inexperience, when people asked for features to be added, changes to be made, or experiments to be run, I would quickly and efficiently implement the code changes that needed to happen. Things happened quickly, and given my limited experience with ruby and the rails framework, I had no idea what the right way to do things was.
The code was a bit of a disaster, but things worked. Being a cowboy coder and hacking things together allowed us to move quickly. We didn’t have any test coverage, and my boss, who was very experienced and knew better, didn’t seem to care. So long as I continued to ship the features my coworkers were asking for, he was happy.
And things were perfect, until I shipped an experimental feature on a Friday evening. Everyone at the company was eager to see early results of the experiment the following Tuesday (Monday was a holiday). Monday morning, I checked my email and I was included on several strange email chains from a few other team members.
I started piecing things together and eventually uncovered that I had broken the application for a certain subset of our users. I rushed into the office as soon as I could despite it being a holiday, and fixed the problem as quickly as I could.
Because the company was very data-driven, we knew precise metrics about how any change impacted the company. I ran the numbers to calculate how big of a deal my mistake actually was. I quickly determined that my mistake had cost our company a little over $10,000.
Needless to say, I was not looking forward to returning to the office the following day to admit the epic failure to my team.
First thing in the morning, I apologized to my boss and accepted full responsibility. The project that I had been leading had a problem that resulted in the company losing $10,000. I asked my boss if I was going to be fired.
Without skipping a beat, my boss responded with a quote from a famous urban myth:
Why would we fire you? We just spent $10,000 teaching you a lesson.
And the rest of the day proceeded as if nothing had happened. In fact, the issue never came up again.
And while I wouldn’t advise making mistakes on purpose, they happen in the real world. And these mistakes have consequences. Mistakes cause companies to lose customers, money, and credibility. But the opposite risk is so much more serious, and that’s the risk of not innovating or improving, and letting competitors move faster than you.
When you’re starting out as a programmer, the cost of breaking things is so much less. If you’re working on a personal project, for which you are the only user, don’t be afraid to break things. You can always fix things later.
Hindsight is 20/20, but in retrospect, I’m pretty sure my boss knew that I would break something eventually. I was young, inexperienced, and had far more responsibility than I was ready for. Operating in such a fast-and-loose manner allowed me to move incredibly quickly, but at the risk of breaking things. Which I ultimately did.
I learned more in the 9 months that I worked for that company than at any other point in my career. The lesson is that there is no harm in trying, and if you use reasonable precautions, adequately test your code (either manually or with automated tests), and try to learn something from every mistake you make, there is no moving backwards.
Rather than looking at mistakes as a failure, look at them as opportunities. Opportunities to learn, grow, and improve. In my biggest screw up, I really learned the lessons that all senior developers learn over time:
- Don’t launch new features on a Friday (especially if it’s a long weekend!)
- Always understand exactly what is at risk of breaking when you launch new features.
- Always audit and verify the code works as expected as soon as the code is launched.
The mistake that I made at my first company wasn’t the last time I broke an application, but it was the last change I made without fully understanding the implications of a mistake.
Even after that point in time, there were countless times I worked at companies where the application wasn’t functioning as expected. This included:
- The application not working at all
- The application having problems that were seriously detrimental to the company’s bottom line
- People at the company physically unable to perform their job
Some of the problems were my fault. Others were caused by other people. But the experience of being under the gun and needing to make fixes fast is an experience that all senior developers have had.
It’s not much of a surprise that Facebook’s mantra for years was to “move fast and break things,” given that it’s the quickest way to learn in small teams. In most professions, errors, problems, and mistakes indicate carelessness.
Source: XKCD
In software though, calculated risks are acceptable. Developers shouldn’t overcompensate and carelessly ship things with a #YOLO mentality. But in most cases, we’re not impacting heart surgeries, rocket trajectories, or life-or-death scenarios. A certain level of risk is generally acceptable. Senior developers have made the mistakes, and they’ve experienced working under pressure when problems need to be fixed fast.
What is the one experience that has taught you the most?
Excellent post. It’s nice to hear somebody be very candid about making mistakes.
My biggest mistake (in recent memory, at least) was a two-factor authentication implementation for a few different scenarios, such as dormant user accounts (i.e. user hadn’t logged in in over 6 months), etc. A big piece of it was device fingerprinting so that a user could “save” their device and therefore not have to be prompted for two-factor again if they log in from the same computer/browser.
Unfortunately, device fingerprints aren’t *really* unique (not the ones I was generating, anyways) – just unique to a particular user, since multiple users could be logging in from a specific version of Chrome, on the same exact model computer, running the same exact OS, etc. In my brain fart, I was searching for a user’s device via `Device.find_by_fingerprint()` instead of `user.devices.find_by_fingerprint()`. As a result, saved devices worked for almost nobody. But the fact that it worked for anybody (by pure happenstance) made debugging the issue extremely confusing.
Fortunately, I don’t think the mistake cost the company any money – just generated alot of support tickets. But it’s probably my most public and most widespread mistake among affected users. And since I was dealing with user logins and authentication, the issue could have easily been alot worse.
Definitely a super-valuable learning experience.
Jeffrey, Never think a mistake don’t costs money. Think in the time of the employees they lose trying to access a those computers and then making those support tickets, then think in those employees replying those support tickets. Costs time. The time is an asset we always forgot. If you see in that way, you can understand better the classic concept about Time = Money.
Exactly.
“Don’t launch new features on a Friday (especially if it’s a long weekend!)” – an eye opener. Thank you very much. A very insightful article on programming