👷♀️ Making Stuff: Cake Slices, Tracer Bullets, and Cannonballs. It'll all make sense.
Imagine you've got a wedding coming up and are in need of a cake. You head to the bakery to sample some of the various confections, your mouth watering with excitement. The baker comes out and presents you with a tray of dozens of samples, but something seems...off. Rather than tiny slices of delectable goodness, it's just, like, the bottom layer of each one. How in the hell are you supposed to make an educated decision with this pile of boring cake-bottoms? It doesn't give you a sense of how the whole thing could shape up at all!
Software development is pretty much the same way. Many times, we tend to release features in isolation to "learn from the market" while expecting users to jump for joy. You're not going to learn, and your customers will not be jumping for joy...
In the amazing book Shape Up, they really hammer home the importance of getting just one slice done. All the way. Front to back. Top to bottom. It's in that single slice that value exists, no matter how small. *By building small pieces of full functionality every few days, you're building momentum, and momentum is everything* for a team.
On the opposite end of the spectrum from the world of only-cake-bottoms is the land of ship-when-everything-is-perfect. Both are dystopian hellscapes that you should try to avoid. This foolish pursuit of perfection is covered in The Pragmatic Programmer, a book I wish I'd read much earlier in my career. The authors use the mental model of tracer bullets to encapsulate the spirit of how you should think about shipping product. Wouldn't it seem silly to take all of your gunpowder and put it behind a single cannonball, hoping to hit the target on the first and only try? Or would a better solution be to use tracer rounds to take a few shots and see where they're landing, inching closer to the target bit-by-kinetic-bit? You're going to waste a lot less energy zeroing in on your target with smaller munitions instead of loading up another heavy cannonball and wasting all your powder.
The first shots might not do a lot of damage, but you know if you're getting closer to the target with each round sent downrange. Iterate, iterate, iterate. Start small, then bring out the howitzer and the A-10 when you know exactly where the enemy is entrenched.
📅 Scheduling Work: What "The Shining" Taught Me About Building Software
The latest cutting-edge science from the year 1659 gave us the following principle: "All work and no play makes Jack a dull boy." Later on, Jack Nicholson used this mantra to chase his wildest dreams in a hotel somewhere, and I hear it worked out really well for him!
Now, if you find yourself in a position to be able to help shape the work that a team will be tasked with, please ensure that they don't end up over-subscribed, full-throttle, and without a bit of flexible time (that includes meetings, too!). Regularly take some time to ask the team if there's any maintenance, innovation, or learning that they'd like to get taken care of and do your damndest to get that included in a future work cycle...or every work cycle.
Engineers love to learn. By continually learning, we find new technologies that can simplify our lives, make us more efficient, and do things we once thought impossible. In unhealthy organizations we're never given the space and time to tinker, so this usually has to happen at night or on weekends, which can lead to burnout if not checked correctly.
Many developers starting in their careers have all sorts of time to do this extra-curricular learning and hacking. I miss those days. Not that I don't still hack around at night, but there are only so many hours in the day. As I've grown older, with kids, a wife, health, and other obligations, the time (or energy) just aren't there after I've finished working all day, made (and cleaned up) dinner for the family, and finally wrestled the kids into their beds at around 9, only to repeat the next morning again at 5. I know I'm not alone here.
Family or not, having a life outside of programming makes you a super-interesting person, and most importantly, it gives your brain a break. Even if programming is all you or your engineers care about, there is still tremendous benefit from learning other skills to complement your l33t hacker ninja coding abilities.
Try hack days, "20% time", no-meeting days...whatever it takes. Just do what you can as an organization to give your engineers (and yourself) time to learn new skills and re-invest in themselves.
The dividends outweigh any negatives tenfold:
- Increased developer satisfaction and retention
- More time to think equals more innovation
- Improved and optimized workflows
- Team bonding
- Knowledge distribution
Another way engineers can learn, grow, and take greater pride in the work they've created or (often) inherited is by allowing room for refactoring and smashing annoying bugs.
Engineering can sometimes be a thankless job, where pager alerts go off at 2am to fix some system that is down, and you're then expected to wake from your slumber and diagnose some arcane technology. That, coupled with a healthy sense of pride, means that your engineers are going to spot things in the codebase that are suboptimal, and they're going to want to fix them...badly. Unfortunately, in many organizations, that's not a new feature, and it sure as hell isn't sexy, so it's not going to get any priority.
On the flip-side, some developers get quite
refactor-happy, and while changing out the text on a button, they'll
decide that they should rewrite the whole damned commerce system...you know...because they were in there. That's equally
as bad, if not worse.
Learning to find the balance between proactive bug-fixing and delusional dives into the digital abyss isn't always the easiest (even as a developer). Still, you can often ask a few questions to figure out what's motivating the desire to refactor:
- What effects does this have on the team?
- Does it slow you down?
- Does it have the potential to cause serious damage in the future if left un-changed?
- What future event would cause us to need to rewrite this again?
- Have you consulted the Eisenhower Urgent-Important Matrix to see where this refactoring might fit in the mix?
At the end of the day, these are just conversation starters, and you need to really trust what your team or your gut is telling you. Engineers pride ourselves in the work we produce because we know that if it's not us that has to look at the code 9 months from now, it'll be some other soul who may have even less context. Taking a few moments to make a system better makes their job easier, as quality (or dysfunction) is something you inherit.
Software with bugs and horrible developer ergonomics is often compared to a building with a broken window. If you allow your neighborhood to have even one broken window, you'll soon see more buildings with broken windows because it's been informally codified as acceptable. Don't let your software projects keep broken windows very long, and watch the quality rise in tandem with overall developer satisfaction.
🧠 Learn More:
> Developer Burnout
> Google's 20% Rule
😣 Mo Developers, Mo Problems.
It can be really tempting to look at a backlog of work and determine that if only you had more bodies to throw at the work, it would magically get done faster. For certain problems at certain scales, this can be true, given that the work is broad enough that it could be divvied up amongst several teams who are in tight communication and coordination with each other. From personal experience, I've found that smaller, focused teams are more efficient for a number of reasons.
Let's say that you have a high-performing team of 6-8, working on a product for years that suddenly requires a boatload of new features. It's too much work for the team of 6 to accomplish by next quarter, so it's decided that they should get some more additional resources to help them out. Soon, 6 more contractors land on the team's previously undiscovered shores, ready and willing to do whatever bidding is required to get the features out faster.
At this point, the team is totally different than it was before. The chemistry has been fundamentally altered, and as such, there will be a period of adjustment, re-calibration, and inefficiency. Any time you double the size of a team, the previous processes and agreements should be discarded or revisited, as the processes (formal or informal) that worked for a smaller team will not always work for its larger incarnation.
Since the team has been "blessed with more resources" than they asked for, an unfortunately-predictable scenario often unfolds, which I've seen happen far too many times:
- The existing team spends a decent amount of time training the new recruits.
- The communication channels begin to grow exponentially. There are simply more nodes in the network, and each node has questions and comments. Everything begins to feel more chaotic. Daily standups take longer. Retros take longer. Everything just takes longer.
- The culture the team had cultivated over time is shattered instantly, as opposed to gradually. This will often shock the existing members into a state of grieving for "the good ol' days."
- The new recruits eventually get up to speed and begin producing code. Lots of code. So. Much. Code.
- As the bits and bytes are rolling in, someone has to review them to maintain strict quality standards, so the original team members find themselves no longer able to find the focus in the day to write good code. They're too busy reviewing PR's non-stop, and good PR reviews take time.
- The original team becomes increasingly dissatisfied because the thing they used to be working on is now in relative newcomers' hands.
- Both the quality of the application and the happiness quotient of the team suffer.
In this scenario, the end result is a net-negative. To support additional developers, the team must absorb a myriad of activities to ensure the success of the new teammates. It's a lose-lose situation, and there are a few science-backed reasons for this.
Network Graphs: Nodes & Edges
Adding people to a team is essentially adding another node to a network graph. Take a 6 person team, for example. That's 15 links (edges) that represent communication pathways and other potential interdependencies. Go to a team of 12, and suddenly you're at 66. Add just 3 people to that team for a total of 15 people, and you're at an exponentially depressing 105 communication pathways. Each of these additions to the network creates further opportunities for communication and management woes. Who said math wasn't fun?
Anthropologist Robin Dunbar did some pretty nifty research that found that the most evolved part of the human brain can only handle a maximum of around 150 solid connections to other people. We are tribal creatures, after all, evolving together in small groups aimed at ensuring survival and the overall wellbeing of the collective. While most engineering teams don't reach the 150 number, if your team is so big that there's not ample opportunity to "shoot the shit™," you start to witness the beginnings of this loss of social cohesion.
If you want a high-performing team of humans, it's critically important to allow the team to build rapport. Learning birthdays, favorite foods, and sharing silly stories is how we've bonded for millennia, and that's probably not going to stop anytime soon. Keeping team sizes somewhere around that 7±2 number will only help to improve communication, spread knowledge, and minimize relational loss.
In Frederick Brooks Jr's book The Mythical Man-Month, he states, “Adding manpower to a late software project makes it later.” Software engineering is hard, often wrought with unknown unknowns that can surprise you when you least expect it, so simply viewing the problem as a matter of raw output and production is a flawed state of reference. Yet another law, Hofstadter's Law states that "It always takes longer than you expect, even when you take into account Hofstadter's Law." Nerd humor is funny.
Many times (mainly from my dear friend Kirps), I've heard the refrain "9 women put together in a room cannot make a baby in 1 month," and I gotta say it makes sense. Some things just take time, and in many cases, throwing more bodies at the problem is akin to buying multiple copies of a book so you can read it faster.
In conclusion, when you're thinking to yourself, "why the hell is this taking so long?" Don't immediately reach for the lamp and ask the genie for more developers. Take a few things into consideration:
- Think of what the team truly might need more or less of. Does the team need more people or just more clarity? More time? More space? Fewer interruptions? Fewer meetings? Generally, start by seeing if you can remove things before you add them. Especially meetings.
- Are there too many cooks in the kitchen? Does this team need less people? I've been surprised at how efficient teams I've been on have become when a problematic member of the team is reassigned or leaves. (See: Addiction, Subtraction, Multiplication, and Division)
- Can the scope be cut? Are you trying to ship too much?
- If you must, and if the team is in agreeance, increase team capacity slowly and deliberately. We're trying to make software for the long-term here, not storming the beaches of Normandy.
- If there's enough work to warrant multiple teams, take a page from the fantastic book An Elegant Puzzle: Systems of Engineering Management and (temporarily) grow an existing team to eight or ten and then bud them off into two teams of four or five.
Every situation is unique, and there's simply not one single panacea for your team's situation, yet I've worked with and led enough teams to recognize repeating patterns over and over. Ignoring human tendencies, flaws, and features at the very core of what has enabled our species to survive and thrive will only serve to frustrate you and the teams you are around. Software engineering is a very human, personal, blue-collar job filled with people passionate about doing the job well with teams of people they respect in an environment that allows them to achieve their true potential. Don't treat engineering resources simply as units of output. We're all complex systems of our own right, and whether we're all remote or in a terrible open-concept office, groups of humans only tend to make things even more complex.
They say that "music is the space between notes," so if you want your teams to present an inspired and beautifully moving symphony, do what you can to ensure there's space:
...Unless this is your sort of thing, then, by all means, go for the high score with those blast beats, but don't be surprised when people get a little tired after a lil' bit:
🧠 Learn More About Team Sizing and Dynamics:
> Atlassian: Research on Scaling Engineering
> Sizing Teams
> An Elegant Puzzle: Systems of Engineering Management
👋 Communication: The End?
In the words of world-famous ping-pong player and purveyor of fine shrimp, Forrest Gump, "I'm pretty tired, I think I'll go home now." We've covered a lot here, and we both know we're just scratching the surface here. There's a lot more iceberg below the waterline, but what makes you so awesome is that you've taken the time to dig in here, learn how to talk the talk, and effectively communicate and empathize with the technical folks you might find yourself surrounded by.
Without doubt, team dysfunction metastasizes when communication and empathy are in short supply, so fight with everything you have to learn the lingo, understand the humans you're with, and provide the space for real relationships to beget amazing software.
🏆 Now, print this out and impress your co-workers. Flaunt it, even. You earned it...
More in this series
🎉 That's it!
- Level 0: The Intro
- Level 2: Frontend Frameworks - Building blocks for your wildest dreams
- Level 3: APIs, REST, and GraphQL, Oh My!
- Level 4: Server-Side Languages - With great power comes great responsibility
- Level 5: Server-Side Frameworks - Trust me, you don't wanna write this crap from scratch.
- Level 6: Databases - Your Excel sheet in the sky.
- Level 7: How to internet - Domains & DNS, Hosting, The Cloud™, & Serverless
- Level 8: Authentication and Authorization - House keys vs. giving your neighbors a temporary combination to your garage.
- Level 9: Content Management Systems - A fill-in-the-blank adventure!
- Level 10: Working With Engineers: Happiness, Agile, and Git
- Level 11: Working With Engineers: Time, Team Chemistry and Van Halen
- Level 12: 👈 YOU ARE HERE