on leadership

IT is probably fun to work in because you're working with a bunch of folk that are pretty much successful because they're good at finding patterns in stuff, and then finding solutions that address problems that look just like that.

And that works really well for writing software.

And only works so well for running teams. Truth be told, it works really well for the aspect of actually managing a team. But not for leading one. Let's go.

Managing and Leading are two different things. Two almost entirely different things. This here is my definition, but since it's my blog, I do make the rules.

Management is the easy one. You're given a set of objectives (deliver those two projects), some resources, like a team or money, and you go. To a large extent, managing a software team comes down to understanding what has to be done, finding good ways to doing the work from a technological point of view, and then executing on it. It's here where frameworks like Scrum come in handy, as they formalize a lot of helpful practices to running a healthy team - like plannings, retros and creating transparency about upcoming work. Valuable things.

Leadership is different. Where Management refers to the act of distributing work, managing resources and observing KPIs, Leadership is inventive in its nature.

I was lucky enough to have worked with some really outstanding leaders, and the one dominating trait was that they come up with ideas all the time. And they have the skill required to shape those ideas into things that can be delivered or built by their organization.

And those ideas are the direction. How well the organization executes is the speed, but you can have a thousand horse powers, that's not helping you if you're clueless in regards to the direction of travel.

Those skill sets are complementary. Having great ideas is useless without the right skill to execute, and being great at executing is useless without executing on the right things.

To tie the loop back to the beginning - there's no process, no algorithm and no step-by-step guide that can replace competent leadership at the right position. You can't refine, groom or discuss your way out of a void of ideas, of a surrounding that doesn't dare to think big, and then even bigger.

What stands out to me is that, looking back, the most challenging times were those when we built something that felt almost impossible. Crazy ideas turned to reality. Those were also the most rewarding ones. That required, of course, an engineering team building something, but even more than that: bold leadership.

ideas are momentum

Post-Vacation Check In

I've been on a vacation for a few days and gave myself a somewhat needed break from writing posts at a high frequency. I realized that even with only 500 words, the posts get a little diluted over time. That's ok, and it's mostly an observation that doesn't surprise me. What makes me happy is that there's some major themes I discovered in my thinking that I wasn't that clear on before I embarked on that little writing journey. Getting myself to sit down on plenty of evenings to write something down on those topics really helped to shape and evolve quite some trains of thought.

Another thing I discovered is that plenty of topics that I spent a lot of time thinking about have not only one, but many interesting facets worth exploring. You'll discover plenty of overlap in the posts itself, and so did I when writing them.

When I'm reflecting on how I write most of my stuff, it's usually a process consisting of three steps. The first one is usually just a "punchline", some tacky one-liner that I use to file the idea initially in my brain - the next post I'm working on has the line "leadership is antimechanical", and it's not more than that, other than some loose ideas and thoughts. I like to think of an idea in simple terms.

The next step is arguably the hardest - it's squeezing that one line and exploring where it goes. I usually do that while writing, and this can be rather exhausting. What helps me is to only look forward. I write a sentence, and then I write the next one. That sometimes leads to sentences that are just not good, but it also leads to a text that is usually above average. You win some, you loose some, but you can't win if you don't do.

The third step happens for some, but by far not all of my posts: A state of flow. Sometimes I just stop thinking and start writing. Interestingly, I feel the same when running, but also only sometimes. A state of flow where the activity itself becomes both very rewarding and feels rather effortless. It's those posts where I'm just crashing through my 500-word barrier as if it doesn't exist. Certainly those moments are the ones that make this whole experiment, this hobby, most fun.

I always enjoyed writing. For myself, in professional contexts, as long as there was a notion of long form and the opportunity to use the medium of written text to explore a topic, I was in. It helps me think. But that state of flow is something that I never felt before when writing plain language - it certainly happened while coding. Every language is a programming language if you try hard enough probably.

And one closing note: WordPress really works very well. Hasn't troubled me one bit since I set it up, and it really lets me focus on writing what I want to write.

So, off to the next posts then.

maybe it was never hard.

A key part of my strategy of leading engineering teams is removing complexity and shaping focus, to ensure the important things are clear and can actually be built. I've been doing this a lot, and I'm stuck wondering why we're building so many things that absolutely no one needs.

What do I mean by "so many things"? Everything you're building needs to connect to a problem. Big picture wise, the only reason you're getting paid for writing code is that the code you're writing helps in addressing some form of business problem. Pragmatically, you want to spend as much time as possible to actually solve that valuable problem, and as little time as feasible on anything else. And this is the part where I'm a bit baffled by what we, as an industry, actually do.

Let's just look at AWS. Yes, AWS offers incredible services at a considerable price point, yet it has become commonplace to rely on a single cloud provider for, partially, ridiculous offerings. Take Lambda as an example - yes, there's use cases where invoking a single function that's deployed independently of everything else makes perfect sense, but what are those cases? Like, if you were not already invested in the idea of going cloud-based or serverless, what would the actual, tangible benefit of having an independently deployed and invokable function be?

There's a sweet spot where (almost) seamless scalability from 0 to a really large number of invocations come in handy, but most application I've worked one - and we had some that had to scale really, really substantially - never ran into that problem. What they had in common that a narrative developed around them - making it necessary to go either serverless, rely on a NoSQL Database or give into the latest trend at that time. But that's because some teams wanted to solve a certain problem, not because a problem really existed. I've written about the tempting energy of excitement before, and maybe it's one of the many facets of getting too excited.

The antithesis to this has always been something like Ruby on Rails. Many folks have a huge aha-moment once they start working with Rails for the first time - and kind of a anti-aha-moment once you switch to a lot of other ecosystems. Rails has made an art of not getting in the way of you solving your actual problems - at least to a certain scale. Whatever else you need - Persistence, Background Jobs, Migrations, Bundling, i18n - it's all there and taken care of. You would expect major mainstream adoption of a framework that so universally makes life easier, but for some reason, outside of a rather small group of dedicated fans, Rails is rarely considered as an option, at least in the orgs that I've worked in. (Google Trends tends to agree with me on the overall popularity trends, comparing it with some other Web Technologies).

Why?

I have a theory, and that is that Rails (and other battery-include frameworks) make it just too easy. If it doesn't look hard, if there's nothing tricky to solve every day, then what's the point? A framework that's so good at solving all the things folk usually worry about is its own worst enemy - how can you pretend that you're doing some super complicated work when you're just not? There's a truth in there that might be upsetting - most of software development shouldn't be hard in 2024. Rails makes that obvious. But it's much more fun when it's hard. And so we take our Lambdas, our crazy distributed applications, our scalable somethings that will never scale instead of just writing boring software. Everything but admitting that it was, actually, never that hard.

things to learn as a software engineer

Today, enjoying a day off and browsing around Twitter to get upset about nothing, I found something to get slightly excited about. I don't have the patience to find the tweet now, but it was very much along the lines that being able to do most things as a software developer without touching your mouse is an important goal. So, the act of navigating your development environment, going about daily tasks, without using your mouse. That's something to get excited about, for sure.

First of all, no, go use your mouse, or trackpad, or whatever pointing device you're computer has attached. Or don't. Or use IntelliJ or VS Code or Emacs or VI or whatever really does it for you. Or use notepad. Or nano. Don't do what slows you down, do what makes you fast. You, not anyone else. Don't listen to random folks on the internet that try to establish a connection between a nuanced mastery of some skill and eventual success in your trade. Correlation does not equal causation.

But to bring the bigger point home - being able to write code fast is useful, it's a good skill to have. Not having to try to find the right keys on the keyboard, not making too many typing mistakes definitely speeds up the act of "code creation", but with all the advances in AI and LLMs, the question is also for how long that's actually going to be relevant. But if you're a software engineer, only a fraction of your time is actually spent coding. Reading code, investigating bugs, documenting things, discussions, understanding problems and defining solutions, all of those are highly relevant activities. And true, some of them can be completed in your development environment, for the most part: Good luck solving them not touching the mouse.

Your job as a software engineer - or software developer, if that's the first line on your CV, is in fact not to write code, it's to make problems go away. Writing code is one of the many ways in which this can be accomplished, but it's really only one. I've seen people do crazy things when developing, from typing speed to mastery of a single environment, and yet they've never really grown beyond being keyboard cowboys - there's no extra points for being incredibly good at one thing and ignorant of all the rest. And a person being average at all the things that define a well-rounded software engineer will blow someone being incredibly good at one thing out of the water any day.

So, before learning to ignore a key input device for internet points, learn something that's actually relevant in your career - do a course on rhetoric, learn how to write well or join a discussion club. All of that will make a much more significant difference in how you'll progress as an engineer than your mastery of an IDE.

information symmetry

I'm a manager, and I'm spending a substantial part of my time writing things down, and hopefully creating clarity in doing so.

The reason why I'm doing this is because I want to be the antithesis to a go to person. While I generally appreciate when people come to me for advise, for chatting or for working on something, there's a specific thing that shouldn't require personal interaction: Understanding stuff. And there's a huge precedent for the point I'm trying to make here.

Take most well-maintained open source projects, something like React. How many calls with the maintainers does it take for you to get familiar with the core concepts? Exactly, none. Not only because you probably don't even have to chance to get one of the core folks on the phone, but also because there's just a huge body of available, free and up to date documentation on the concepts, how to use it and what changed in recent versions. That provides a ton of clarity, without needing to hop on a call with anyone. So far, that's a logistical concern, but there's something deeper.

By not transparently documenting things, sharing knowledge, you're actively preventing a deep and meaningful discourse. In order to be able to disagree with something, folks need to be able to understand what they could possibly agree or disagree with first. Not having that thing, in a fixed, written form in front of you, is just making that discussion entirely impossible. Because there is information asymmetry, and even the economists know that that's a bad thing.

Monopolising knowledge is preventing information symmetry. And that prevents discourse. And that leads - or can lead - to poorer decisions. So it's not about me not wanting to go on a call to explain something complicated, it's about all the folks that didn't want to speak to me, couldn't be bothered or didn't even know that something existed - discoverability is something to consider.

There's so many in ways in which you can be special - very helpful, very smart, very pragmatic, very witty, very fun to work with.

Just don't be special by hoarding information and only sharing it on demand.

five things to notice

I've got a bit of Monday advise. Mostly for me, to prepare myself for an interesting week to come (and a short one at that, with Wednesday being a bank holiday here). Since I've gotten myself a journal - a red one, just in case - I figured that there has to be something meaningful to write in there. Next week, I'll try to write down only when one of the five things below is happening. I'm hoping for plenty of entries.

Things we ship. I'll note every little thing my team is moving to production. Doesn't matter how small, every little thing.

Things we break. Observing every little thing we make worse with our actions. Might be trust, might be an app.

Decisions we make. Again registering when important decisions are being made, and also how they're being made.

Disagreements. There's plenty, but I'm speaking about the ones that require something like active resolution - a discussion, a meeting. Most disagreements dissolve before any active step is required, so I'm trying to focus on the more meaningful ones.

Misunderstandings. Mind you, I thought about calling this one "confusion" first, but for some reason, confusion always sounds like someone hit their head a little and is now wondering in what city they find themselves in. So Misunderstandings: When communication didn't go well and now the discussion is not even about the content of the message, but rather the message and its interpretation.

A lot of focus on the potentials to improve, but also on the things to make us proud.

Gotta sharpen my pencils now, see you in the new week.

default to really fast

In negotiations, there's a term called anchoring. It refers to the concept that whatever first number is dropped in a conversation, is the number that will be the mental anchor for the rest of the negotiation. It's why you should avoid saying the first number in any negotiation - if you're too low, you've anchored yourself needlessly on the wrong thing.

Engineering Teams do the same thing, at least I've seen it happen a few times. But that's not anchoring on price levels (probably also, but that's for another post), I'm talking about performance anchoring. When you're joining a team, and someone tells you that retrieving one entity from the Database takes 5 seconds, what's your reaction? It's a bit excessive for 2024, isn't it? Of course, you're diving a bit deeper into the context and the explanations and the history on how it came to be and, well, it's still excessive. But after a while, that edge wears off and it becomes a little more normal, day by day, hour by hour. And instead of driving a realization that some things might not be great, it's rather a journey to normalizing what should not be normalized.

And that's performance anchoring. Normalizing things that behave wildly different from reasonable assumptions. And it's something that drives me mad, because bad performance compounds. It's like a lasagne made up of only bad decisions and spineless management.

It's fair to characterize performance anchoring as just another face of the broken window theory, and it's really not far from the original statement, but there's value in being specific on the topic of performance. Performance is an interesting challenge in most teams - whether it's backend, frontend, mobile or even foundational teams that are not running their own stuff. And performance is highly subjective - is 2 seconds a good load time for a page? It depends. But it's also a truism that Google got to where they are today not only by having great results, but also by delivering a ridiculously fast site, back in the days. Performance in itself is a feature, and if it's overlooked, you won't be able to fix that with some half-assed measures. That's why you have to avoid any form of poor performance creeping into your system - and if it's already creeped in, you need to aggressively remove that.

Happy to write something that I can use to quote myself - and here's that: It's 2024. Most things we're doing can, and should be, fast. If your website is slow, it's not because you're doing some computations that no one has ever done before, no. It's because you dropped the ball on modelling the system correctly, figuring out the right architecture or deploying it to where it should be deployed. All of those things can be fixed, poor performance isn't just a fact of life - it's a result of specific actions. So yeah, go care about performance and make things fast.

estimations

Whenever we talk about actual work, there's a tendency of trying to understand how long something will take - or any other proxy metric that means the same thing, but in a more indirect way, such as complexity. This can serve a helpful purpose, but I think it's mostly a distraction. Let's talk about estimations!

For context, imagine a random software engineering team, building things. You have a big thing in front of you, like building a new service or system. As you get more acquainted with the requirements, you start drafting an overall design and soon enough, find yourself in a position where you can actually start implementing things. So you create some smaller units that can be shipped sequentially. Like setting up the service, create the first endpoints, you get the idea. But before you jump into action, someone asks the team to estimate the tasks. As in, put some T-Shirt Size, Fibonacci Number or time unit on them.

Now, there's some really valid reasons for wanting to do that - understanding how much effort building something is is in itself a valuable and helpful data point to decide if something should be done. It's also good to understand, roughly, how long something will take - "it's done when it's done" is not good enough in a lot of business contexts, for better or worse. For me personally, I like to estimate things because I need to understand what I'm building before being able to put a fancy number on it. And I think it can drive constructive conversations on how to build something - kind of like the output of a refinement session.

So a few things that provide value - high level, comparative values used to understand the overall complexity. Use this to understand if you want to build something, but it probably doesn't need a detailed concept, just some folks with relevant background doing a high-level guesstimation. More detailed estimations might be useful to help provide business some timelines on when to expect deliverables, that's also something that can be done on a high level with some accuracy, but depending on the context, a closer look might be warranted. And the third case (that I can come up with) is to actually use it to facilitate a discussion in the team - to lead a refinement and to have a constructive discussion on how to build something. If you know how to build something, you're anyway done with the hardest part of building software: figuring out what to do. Estimating is then relatively easy.

One thing estimations can not do, and should not do, is to enable some form of overly detailed capacity planning for a time unit - mostly a sprint. I've seen this time and time again - folks trying to sequence estimated tasks in smart ways to ensure "capacity is filled". This is about as useless as it gets, and here's why. If you're working on something impactful, that whole thing should be front and center for the team - if it's not, why even bother. If something is anyway in focus, it doesn't matter how long the individual tasks take, since the folks working on it would anyway just pick up the next one once they're done with their current one. There's a natural flow state where the next logical task is being picked up. And once all are done, new work is discovered and found, and that new work can then be picked up. The goal is to build a product, not to follow a too narrow plan that has any free minute planned out already.

What I'm trying to say: Use estimations for high level planning and for creating an understanding of the work. Do not use it to steer or control the actual execution of the work.

you need a kitchen

Remember house parties in your twenties? I do, and one of the highlights - and one of the common thing between most parties - was that the kitchen would be the focal point of most gatherings. Since a lot of partying revolved around drinking various kinds of beverages, the kitchen offered itself as an ideal spot, but people would hang out there, even if for no other reason than the fact that everyone else was already there.

There's an analogy here to team communication in a professional environment. In my first job, you didn't need a kitchen. I was sitting with a bunch of folks (4-6 if memory serves me) in the same physical room and we were building software together. You didn't need messaging, or e-mails, or Jira or anything else. You'd literally just talk about the thing, since physical arrangements and team size allowed for that form of collaboration. But that was also 15 years ago, and building software was a bit simpler. But then again the software was. Maybe.

The world has changed crazy much since then, and, accelerated by the occasional pandemic, we've gotten used to working models that are flexibly finding themselves somewhere on the spectrum between completely on-site and completely remote. It's probably rare to find jobs that still expect folks to come in 5 days a week, but I'm sure they exist. It's also increasingly rare to find jobs that allow for full-remote. In my part of the world (Germany/EU), most arrangements these days look for some kind of Hybrid, with one or more days spent in the office, and the rest working from anywhere else. The problem is: Anything on the spectrum that's not clearly remote or clearly on-site is really hard. Unless, of course, you know where your kitchen is.

The really great teams I've been part of had a kitchen. They knew exactly what the right place was to share anything, to think out loud, to comment on ideas, to gossip and to share memes. They knew their kitchen. It all comes down to communication, and communication first of all needs a defined upon place and way in which it happens. There's nothing more chaotic than more than one channel for any given message, and it gets even worse when you multiply that by the number of people in a team or group. And make no mistake, communication isn't always only involving a sender and a recipient, or a sender and multiple recipients - in healthy teams, communication can also just be observed, to gather some context, to find if there's value in inserting oneself in a conversation and so on. That's why the kitchen metaphor is, in my opinion, so striking - transparency is in establishing a central place where communication doesn't only take place, but where it can also be observed, and rewinded. A transparent, persistent and rewindable record of the thoughts of a team.

So, whatever you're working on, make sure everyone knows where to find the kitchen. It's lovely there.

no is such a boring word

To get something out of the way - yes, I do say no quite often. But even if "no" is in itself a complete sentence (true!), I still think it's a really boring sentence. Make better sentences.

If conversations are two-way streets, no is like a stop sign. There's no opportunity in no, no next steps, no learning, just an end to moving ideas around. No is for people who know it all.

I don't think this word has a place in groups that want to achieve a joint goal in the best way possible. No, I actually don't believe it has a place. And I can even explain why that is.

Great teams are places to share ideas, and to jointly find and give opportunities to improve. So if someone shares a shit idea with you, sure, go ahead and say no. But there's no teachable moment in shutting people up. There might be a moment of feeling smart – very ephemeral. Reality is that most folks don't come around presenting shit ideas, there's a deeper reason for that. And understanding that reasoning, understanding why and how people make decisions, their reasoning, that's a good point to speak about. But you will not if you shut people up, if you're a human-faced stop sign. So don't be.

What's better? The first thing is to assume positive intent. To be fair, up to a certain point - there's always douchebags. But assume that the overwhelming majority of people communicate with good intentions - intentions of being constructive, helpful or just sharing a great idea.

Since I'm usually assuming that the people I'm working with are neither dumb nor evil, what feels like a not awesome thought for me in the beginning might just be plain ignorance. So you go and ask until you truly understand not only what someone is sharing with you, but also the context around it. And that might be anything from individual experience (I built something like that before), environmental particularities (time pressure) or implicit assumptions that no one really knows about - unless it's shared. Active listening and putting in real effort to trace a thought that lead to an idea is what will actually make you smarter.

Chances are you'll still disagree with some things, and oppose others. That's fine, otherwise communication would serve no final purpose. But rejection can be opportunity, and this is why communication needs to be a two way street, not some boulevard of stop signs. There's an opportunity to explain your side of things, your reasons, motivations – your experience, environmental particularities or implicit assumptions. And even biases, if identified as such. But there's just such a striking difference between saying no – an unhelpful rejection and explaining opposition to an idea. There's learning in explanation, even if it's to understand someone else's opinion better.

Maybe no is not a boring word, maybe it's just super not helpful. No, don't use it.