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.

feedback

We're running regular surveys in which all employees are asked to rate various aspects of their workplace, and that gets then summarised and condensed and gives me, as a line manager, the opportunity to understand what the people reporting to me think of the company, the team and their environment. My general expectation is to load without surprise, that is, lead in such a way that no action or feedback in itself comes as a surprise. So I was surprised when the results of one of those surveys were actually not great.

And then I thought back to a piece of advice I've read or gotten a while back – one of the most valuable pieces of advice from my perspective: Do not react to feedback in the moment. Probably mostly applicable to feedback that is delivered in a more direct form of interaction, it really got me thinking. On safety, on feedback and on how to get to a no-surprise environment as a leader.

Taking a step back, "managing down" with an approach of no surprise is not a piece of cake either. It takes an honest reflection of the delta between expectations and the reality you find in your team - and with your people, and also requires a level of integrity that makes you deliver necessary feedback and criticism in a direct way. To be candid. (By the way, go and read Radical Cantor by Kim Scott, outstanding read). That's a skill set that can mostly be learned, the important part is to diligently apply it.

Realistically, your reports should neither have to develop that skill set nor have to apply it just to save you from a moment of surprise when receiving feedback the other way around. Rather, it's up to you and us as leaders to make it stupidly easy to give feedback, especially on topics that might be perceived as negative by whomever you're reporting to. And receiving feedback, in a leadership role, consists of three distinct phases – and you can mess each one of those up. Time to take notes.

First, you have to create opportunities. Personally, I like to every once in a while ask for feedback in 1:1s, offering plenty of opportunities to share that. One of the lines that I like to use to emphasise transparent handling of feedback is

Hey XX, I was wondering how I'm doing my job from your perspective - and I'd really like to understand if there's something you think I should be doing differently or better. Feel free to share that now or drop me a mail. It's also perfectly fine if you'd rather not.

There's something there that's relevant for me that's probably described as "feedback without cause". I very actively avoid asking for feedback around "loaded" situations, like conflicts, challenges or interventions. Feedback can wait until the ship is in the harbour, no need to ask during the storm. Create opportunities, but be smart about when you create them.

The second thing that works well for me is to create a precedent – show that it's safe to critique you, and that you will not leash out, single out the person criticising or react negatively in any other way. Make it obviously very safe, also in a group setting, to share challenging feedback. In any healthy team, some people will take over the part of helping you create those moments. But you need to be really mindful of the fact that your folks will likely watch your reaction much more than what you're actually responding. Body language, Tone – that's what matters much more than any messaging.

Probably what matters most is to create results – based on feedback. Just taking in feedback without acting on it is the most silly thing you can do. And unless you're a total psychopath it's really hard to not try to improve, either in your own behaviours or by modifying actions you take as a leader. Those results, the actions you take as a consequence of feedback you've received, are the one thing that ties it all together. Asking for feedback is meaningless if it's just noted, written down and then forgotten. Make sure people feel that what they are sharing actually makes a difference.

Create opportunity, create precedence, and create results. That's what feedback needs to be shared. Safely.

great teams

If you take a group of people and have them walk one kilometre over a flat surface, and compare that group to another group that walks a kilometre over challenging terrain - those groups will be different in the end. One of those groups will have a story to tell, an achievement to celebrate and some thing to remember.

One of the biggest questions on my mind is how to establish positive and healthy teams. There's some pretty basic measures, like not hiring toxic people, establishing solid guardrails on what behaviours are expected - and they'll get you to a certain point. But that can never be significantly more than just a starting point.

Looking back, the great teams I was part of were great not because of the shape of the team itself, but because of what we achieved. We thrived through achievement. Progress. Direction. Movement. A team without a mission will never be great, simply because there's a lack of moments that will force a group of people to actually push through and get something done that is more than any of the individuals could have achieved. That's when a group of people become a team. And they'll have frictions on the way, they discover differences - and shared beliefs. But they need a something to experience all of that.

I'm not writing that to give anyone some justification for just throwing random pieces of too much work on a group of people, expecting magic to happen - that's not how it works. While occasional excursions from the comfort zone are necessary to enable or even push for growth, this is not what this post is about. You don't create 10x team by just pushing them to success, you help to establish great teams by allowing them to be awesome. And that's a striking difference.

I started running many years ago. And I don't recall my initial pace, but it was bad (so bad that my brain actually forgot it). The first two or three runs, that made me feel not great. But then something interesting happened: I got faster every time. The achievement was in progress, much more than in achieving success based on some arbitrary outside measurement. I became intrinsically motivated to just get a little better each time.

Probably not all teams behave in comparable ways, but I believe that a lot more can - if given the opportunity. Small projects, achievable work and manageable increments is what helps good teams to understand how to work together - and how to win together. Once that is established, they'll usually push for more. Building something great is a motivator that far outpaces some of the more traditional incentive for doing a great job, and it's not that hard to create an environment that fosters just that.

At the end of the day, one thing to keep in mind is this: Great teams don't deliver awesome things because they have to, but because they want to.