On burnout

I recently got burnt out from doing software development, so let's talk about it!

I am already on vacation to decompress and decided that now is a pretty good time to do some introspection and explore what causes stress in my daily work life working with software. While mental health and some of the topics around it can be complex, I do think that there are a few concrete factors here, talking about which could be a good idea!

How did I end up here?

I don't think that there's a single moment in time, that I could point my finger at and claim that it's the culprit, the straw that broke the camel's back. Rather, it was the buildup of various stressors over time, which does seem to occur to me every now and then, though until now weekends have generally been enough for me to take my mind off of things and get some rest.

camel

(the metaphorical camel, just a cool image from the Internet though I might have to dig up one from my trip to Egypt sometime)

That did change when I moved in with my parents during the COVID epidemic in my country, when spending lots of time in an apartment felt like a worse idea than hanging around with my pets in the countryside. However, that actually came with the caveat that due to how my parents are, now I also don't get enough privacy or free time (given that they have ambitions about building up the country estate, yet they're also aging, hence I get involved) to spend on my own accord, so I'll probably need to review that.

We all experience stress in our daily lives and I'd say that it's pretty important to be able to manage it, the means of doing which might vary from person to person. What's pretty bad, is when you find yourself in circumstances where you're unable to do so efficiently.

For me, that's having other people that believe that they own my time and whose response to me telling them that I'd prefer not to be disturbed and just relax for a while with video games or watching Twitch streams is: "Nonsense, work and sports are the best ways of resting! You should go build something out of logs in the forest and listen to me chat on about politics and life advice."

Also, consider that anything would be worse when it's 27C degrees indoors and even more outdoors, which is enough to put anyone's body under strain and overall just be a not very pleasant experience. Indeed, consider the additional factor of me living in Europe, a location that historically hasn't seen much popularity in AC units being setup either. If not an outright health risk, that is definitely enough to make everyone feel a bit cranky.

As far as the preferred ways of actually resting go, for someone else it might be going out on the weekends and hanging out with some friends in a club or another venue, for someone else yet, it might be visiting an art gallery or enjoying a concert, watching some YouTube videos, or doing some DIY crafts.

Try to recognize whatever it is that you need to relax and deal with stress and seek out the more healthy ways of doing this, optimize your free time for finding fulfilling activities, though a bit of variety can also definitely be nice - yes, including working out and chatting with others; just when you want that yourself.

So what caused the burnout?

The causes for the burnout itself are relatively simple: at work, I've somehow become the "go to person" for all sorts of help, consultations and development work. Need help with some infrastructure setup and configuration? Want help with adding a new feature to your application, but don't have enough developers? Perhaps you need help with some debugging of your app in the clients' infrastructure? Or maybe someone to join a meeting about how a system could be altered to better match some new businesses goals and add new functionality?

I get called in for all of those cases. Not only that, but this happens across multiple projects. Even outside of work, I'm also usually responsible for the full scope of every change that a certain software package might need - be it whilst freelancing (which admittedly I haven't done a while because of lots of bad pre-existing codebases), or helping someone I know out with some software development.

Once another person on the team was asked to restart a service and adjust its configuration and they responded with: "That's not in my job description." I scoffed at that attitude in private back then, but I now recognize that when everything is in your job description, it's not exactly the best set of circumstances either.

That might not be much of an issue in of itself, but consider that the actual power I have is limited. I'm other words, the circumstances I find myself are hardly ever optimal and rarely set me up for success. I want to solve problems and help other people with my expertise, yet it often ends up feeling like an uphill battle and a total slog.

rock

Let me actually give you a few examples.

Note: it's been pointed out that the below gets pretty wild. Well, rather than refer to a single project, I've listed factors and circumstances that I've encountered both while working on projects that some other company developed and that we now need to fix, things I've seen while freelancing and also while helping an acquaintance with a few sites that they manage, or with situations where there are requirements that you cannot do anything about.

An example: infrastructure setup and configuration

Suppose I get called in to help with some project. Instead of Debian or Ubuntu, I have to deal with an enterprise RPM distro that's a bit lesser known. Now, that wouldn't be a problem in of itself, if the solutions for running containers that are popular in the industry (Docker) wouldn't get treated as a second class citizen instead of their own vendor specific solution - Podman. Which again wouldn't be bad if it would actually be compatible with the tools and other software that the rest of the industry uses. And no, you don't always have enough capacity to setup and manage OpenShift for this one project because it's too large.

Oh, you still want to use Kubernetes for the dev environment? And Helm charts? And Istio? And you're already kind of close to being late with deadlines? And developers will reach out to me asking me to setup random pieces of software without articulating what configuration they'd like for it? Oh, and all this on a single node with 8 GB of RAM while the lightweight Kubernetes distros will refuse to run properly because of the latest OS version messing around with cgroups (and MicroShift still isn't out)? And me trying to replace the Traefik ingress with an Nginx one so I can get an internal wildcard certificate working due to the former being undocumented, not only not working but also making the entire cluster hang?

Of course I'll help you with that. Because I don't want to deal with others somehow mistaking me calling out bad circumstances for personal laziness due to reasoning in bad faith. Things need to be fixed and I will get everything working, though at an expense to my own personal wellbeing.

Another example: application development

Suppose I get called in to help develop some new set of functionality within an existing application. What is it that you think I see?

Is there a complete onboarding guide, that contains information about what the system is supposed to be, how all of the components fit together, what software platforms are used and where to get the necessary access credentials for them? Are there instructions and versioned IDE run profiles for every single service that you'll need to use? Maybe even contribution guidelines and automated CI processes in place to reject bad diffs ahead of time, so the code quality remains decent?

If I've worked on the project in the past, then yes, that's how it will look, because unless there are some serious deadlines ahead of us, making sure that the onboarding is properly implemented has been worth it in the vast majority of cases. Otherwise you have a system that nobody really understands how it works and changing it is like navigating a minefield.

And yet, that's exactly how working on others' projects is like a lot of the time. Even when I can only help them out briefly and jot down some basic instructions for how to get things running, or automate DB migrations which didn't even work properly previously, then next time I come back most of these docs are usually out of date and nothing works. Other times, there are no docs to be had in the first place and you're expected to figure everything out on your own.

FauxPilot

(example of FauxPilot GitHub README)

Worse yet, "self documenting code" is oftentimes a lie and there's no historical context for why certain features were implemented a certain way. There is no information about any of the business needs (outside of Jira/Redmine issues that have limited relevance to the technical details) and the concept of architecture decision records (ADRs) never really took off here. And any merge/pull request descriptions? Empty and devoid of details. Honestly, I've only ever seen mine contain descriptions, details, examples, screenshots/GIFs or graphs of what the changes are, so that coming back to them 2 months later wouldn't be like trying to decipher some WW2 cryptography.

This leads at best to needing to talk to people synchronously and waste everyone's time due to limited communication abilities or availability issues, or at worst needing to piece everything together from just the code itself, given that the person might no longer work there.

This might not be so problematic when you're trying to piece together a few functions within the boundaries of a system, but might be a bit more of an issue when you have questions and concerns about the entire architecture as well as some other base assumptions that will get harder to change as time progresses.

The systems themselves are the problem, as are the ways of thinking

There was once a system that was developed in some sort of an echo chamber with patterns that not only ensured that it was a "singleton app", meaning that only a single instance could ever run, which was pretty bad from a scalability perspective, but downright horrible from a resiliency perspective. This actually describes more software out there than you'd think.

Similarly, in many systems out there you might find situations where the system does hard deletes of data, without any actual requirements to do so, but rather because someone thought that it was a good idea to do so. You might also find systems where touching the DB will make you sweat because nobody setup proper local DBs and migrations/data seeding around that, usually with excuses like: "But generating quality data is difficult." Regardless of how true that is, suddenly breaking stuff in a shared DB will turn into a blocker for many people and so everyone will be anxious about introducing any changes at all.

Worse yet, you will occasionally run into people who will adamantly defend their sub-optimal positions, even when they will cause glaring issues a month later and of course I'll need to be up until 2 AM fixing them for a production business event to be able to take place. Maybe they only know how to implement architectures in ways that were passable 10 years ago but are no longer so, or only work with small systems. Maybe they make the mistake of intertwining their ego to the system design, or just love to engage in bike shedding - arguing about less important details because that is easier.

It feels like a lot of people don't want to explore new options and approaches but instead prefer to do just what they know, even when these things come from a time when there were simply no better approaches, or the weaknesses of theirs weren't yet obvious and recognized. For whatever reason, people become set in their ways sooner or later (e.g. my reluctance against using Kubernetes, outside of situations where the conditions are just right for it) and then everything feels like a nail to them, especially when they're used to developing singleton applications.

nail

Make no mistake: I've built lots of bad software in the past, though I constantly make the effort to improve, especially when the risks of such refactoring or improvements breaking something is minimal or non-existent (glaring security concerns might force my hand, though). But I try to recognize these bad choices, bad practices, bad mindsets and improve upon them, if the end result would be software that would make people hate the software that they have to maintain less and, more importantly, allow the software to work better in production and other environments.

What to do about it all?

The truth, however, is more complex. You can't always strive towards the best solutions at any given time, sometimes due to business having other priorities, sometimes people being adversarial and implementing improvements in such an environment not being feasible, or any other set of circumstances.

But at the end of the day, if you don't enjoy getting up for work and writing code, architecting new features or any other processes feel like pulling teeth, then very clearly there is something wrong with your environment. In our industry, it is actually not too hard to fix - I've actually considered just handing in my resignation countless times and finding a new company to work for, new projects and a change of scenery, so I don't feel like trash. But what do I do when it's an industry wide problem that's been present in most codebases that I've seen?

dumpster

But here's where the complexity of it all comes in - I don't dislike the colleagues/developers in the industry themselves, just the bad choices that might have been made due to their impact. I want myself to succeed and I want others to also have their lives be easier, as well as any communities/employers to benefit from the solutions.

Software is developed together, in teams (at least in most cases) and if I ever suggest that N+1 will cripple the performance some time down the line but everyone adamantly wants to go for it, then sure, go ahead, maybe you'll learn something along the way, for your future pursuits. In the mean time, maybe I'll look up an encouraging blog post about why N+1 issues matter, to share, as well as suggestions for how to solve the eventual issues.

If the team is happy and some threshold for my tolerance of the circumstances that I'm in won't be exceeded, then I'll just find things that I can work on that'll benefit everyone regardless. In other words, I'll pick my battles and make impactful changes wherever possible.

So, recognizing that I don't live in a perfect world, here's what I can do:

  • identify the most important issues and work on the ones that can be feasibly fixed
  • be okay with the fact that fixing everything is not in the cards, don't waste time on fools' gold
  • do not form emotional attachment to my work, curb my ego, be professional even if I disagree
  • prioritize the viability of long term collaboration and a non-toxic workplace outside of critical security/performance circumstances
  • remember to take breaks when things get a bit much, have my CV ready regardless

A lot of what we do depends on our mindset.

If you keep a positive attitude and remember that a lot of code and choices are written with limited amounts of time and other resources, and that a lot of people don't necessarily have the knowledge how to build certain types of systems (which is a widespread problem, with CV driven development in our industry), you should be able to "let go" of certain personal gripes.

Offer suggestions, sure, even better if you can have benchmarks and graphs comparing various approaches to make choosing the best approach a no brainer, but if that's not in the cards, then don't end up arguing with your colleagues and spoiling your relationships over menial discussions of whether the type systems of Java or .NET are better. Business will just see a few nerds arguing and wasting time.

As for me, for now the occasional breaks are enough, as well as setting a career trajectory that is geared towards success and colleagues that are easy to collaborate with.