In a recent blog post, Johanna Rothman wrote about paying it forward in our careers and in life. (Read it here.) Through paying it forward, she says, we offer people lucky breaks. When others pay it forward, sometimes we get the lucky breaks.
I add this: sometimes when you pay it forward, it goes full circle and creates lucky breaks for you. Here’s a story of a time that happened for me.
In my first management role, more than 20 years ago, I got to build a small team from the ground up. I wrote that story here — that team and the work we did remain one of the brightest memories of my career.
I wanted to build the kind of team I’d want to work in — one of transparency and autonomy, where we could do very good work yet go home to our families at a good hour each night.
I hired Mary Ellen first. She lacked the technical skills I was looking for, but was otherwise qualified — and whip smart and deeply resourceful. So I took a gamble and hired her.
She was a home run hire. She picked up every needed technical skill quickly. Her work was nuanced and of impeccable quality. She even helped define team processes that let us run more efficiently and effectively. We couldn’t have done it without her.
The team was quite sad after a few years when I was promoted to a different role and was no longer their manager. It was a great compliment when they told me that our time together had been the best at-work experience of their careers.
That company didn’t make it through the dot-com bust and we all went our separate ways. I wasn’t very good at keeping up with my network then and lost touch with Mary Ellen. Seven years later, I got an email from her. “There’s a leadership role open where I work now, and it looks perfect for you. If you’re interested, I’ll put in a good word with the VP, because I’d love to work with you again.”
I was ready for a change so I interviewed, and I got the job. It was a fabulous role for me and I was very successful in it. The company itself was successful enough that the founders took an exit. I was a late enough hire that my cashed-in stock options didn’t change my life. But the founders and all the VPs ended up being movers and shakers in the startup scene in my area. Those contacts have helped me immeasurably as I’ve continued my career, offering coaching, introductions, and even job offers.
The moral of the story is to treat well the people who work for you! Treat everybody well. You never know when it will come full circle.
I’ll never forget the revelation it was when I figured out how to write computer programs. You mean, I thought, I can make this machine do what I want it to?
It was a watershed moment in my life.
I was a teen then, shy and introverted. People often frightened me, at least a little. I struggled to interact with people I didn’t know well, and to assert myself with people I did know well.
And then here was this machine that I could order around. It had limits, but within those limits, it was all about what my mind could imagine and then code. I wrote games that my dad and my brother played. I wrote programs that illustrated concepts of geometry, which I demonstrated to math classes in school. I wrote a payroll application for my aunt’s small business. I even wrote a very rudimentary operating system once – it was terrible, but I learned a lot.
So I went off to college to learn more about how to make software. When I graduated the job market was terrible, so I took the only software job I could find, which was writing user guides for a software company. Later in my career I moved into testing, and into management. I’ve delivered a lot of software since I started 29 years ago.
Here’s the crazy thing I’ve learned: The hardest thing about making software is not the technical stuff. The hardest thing is getting people aligned and pointing the same way!
I’ve often said that it’s a modern miracle when a software project succeeds. Any software development project that involves more than about two people will have coordination challenges, differences of opinion, and all the other normal issues of working together. My experience has been that the programmers and the testers can do whatever you need them to, short of, say, developing a telepathic user interface. They will work hard at it and they may struggle to get it right. But those struggles can pale in comparison to how hard it is to get everyone to agree on what to build, how to build it, and what it means to be done. Here’s how code is better than people:
Once coded, code stays coded and reliably does the same thing over and over.
You think you have people all organized and then they go off and do whatever they want anyway.
You will sometimes struggle and work hard to make your code do what it needs to, but you can almost always get the job done.
Sometimes you simply can’t influence people. Drat their free will.
Change your code, it doesn’t mind. It knows no fear.
People hate change! When change is thrust upon them, they often resist it or even run away, screaming.
By the way, the WordPress editor doesn’t offer a way to create tables, so I wrote some quick HTML to generate one. Fear my mad, l33t sk1llz.
Unfortunately, even if you have the best coders in the world, if you can’t get them to work together their projects will fail. Fortunately, I understand geeks, for I am one. I know what makes us tick. I’ve learned how to influence us and get us all reasonably pointing the same way. And I’ve built on these skills to learn how to influence non-geeks such as upper management, salespeople, and customer service folks to get them all working together. It’s not easy, and it’s impossible to ever get it perfect, but I’ve had pretty good success over the years and it’s contributed strongly to any number of successful software releases. And it’s helped me come out of my nerdly introverted shell.
I can’t remember the time I last wrote any serious code. I don’t miss it. To my astonishment, I’m having much more fun and success on the people side now.
Yet I’ve noticed that I’ve continued in my career that I work increasingly with people much younger than me. Today I lead a team of software engineers mostly in their 20s. I know of only one fellow on the team who’s older than 30. It was much the same in my previous job, and in the job before that.
I’ve long assumed that engineers my age all still worked in .NET shops. .NET was new, hip, and cool when I was in my early 30s. Where I live (central Indiana), companies adopted it readily and so most then-young engineers built their careers on it. I worked for several .NET shops in a row. Some of those companies still exist, and their products are still built on .NET.
So I searched LinkedIn for names of people I worked with years ago. Some of them are still writing code. A few of them are in some level of management. But the rest aren’t on LinkedIn or have left the industry.
I don’t know why. Do you? Especially if you’re older than 35: where have all the older engineers gone?
Today I begin my 29th year in the software industry. Actually, today’s a day off where I work. But it wasn’t at the company where I began my career, also on Monday, July 3. It’s why I remember the date: my second day was a paid holiday!
In 28 years I’ve worked for nine different software shops, small and large, serving many different industries and kinds of customers.
What surprises me is how little correlation there was to how good my co-workers were and success of the companies. I worked with some brilliant and visionary people at companies that struggled, and with some average people at companies that did well.
Does that surprise you? As I look back, it certainly surprises me.
Here’s what did correlate to the successful companies in my career:
A product vision and company direction that did not change wildly, but did evolve to meet the evolving market
An executive team in unity on that vision and direction
Good communication to everyone about that vision and direction
Reasonable planning to execute that vision and direction
Good execution in engineering and in sales
A work environment where people felt safe and valued
Transparency into company financials
Notice how none of the adjectives I used above are superlatives? No excellents or flawlesses or bests or outstandings. Everywhere I’ve worked, when people are aligned to a vision and direction, “good” and “reasonable” have been enough.
These things give brilliant engineers and visionary product people a solid platform to do pioneering work. But even the best people haven’t been able to overcome the lack of these things.
I think there’s a miss in how startups recruit. They hype the interesting problems they have to solve and their cool company culture. But those are only two of the three things they need to hype. The last one is that together, you get to build a great business.
If that doesn’t sound very interesting or exciting to you, well, it should. Seeing your work lead to a company’s overall success is enormously rewarding. And given a startup’s size and scale, you have an outsize ability to affect that.
Does the company you work for share financial results and business plans with you? The one I work for does, once a quarter. We all get to see how much money we’re making and how much is left. And we are updated on our strategy to get to our planned next business phase. All of this tells us where we are on our corporate journey. Are you clear on what your company’s journey is?
(Sidebar: It is interesting to me that in my career, the companies where I’ve been the happiest are also the ones that shared financials and strategies. Not all companies do it. I think companies that do it get how it brings the company together as one.)
When you understand that journey, you understand the larger context your work lives in. It helps you make better decisions in the moment, ones that let you deliver the right balance of speed, quality, and scope.
If you don’t see now how building your business is an exciting journey, you will when your company meets its goals. Especially in a startup, it will be impossible to miss how your work made it real.
I’m sure it’s happened to you, maybe even where you work now: you wonder why in the heck you’re building a particular feature. It seems to you, and maybe to others you work with, that the company’s time and money would more profitably be spent building a different feature.
You might be right. I hope your company gives good avenues for providing that kind of feedback. But if it doesn’t, or if it does but your appeals failed, then get on with making your assigned features real.
That’s where strong execution begins — when the dust settles, even if you don’t fully agree, you get busy working the plan.
It’s obviously best when your company has brilliant ideas that you then execute strongly. But if you bring strong execution to even mediocre ideas, success usually follows. It’s a great overlooked secret: there is no substitute for everyone pulling the cart hard in the same direction.
Companies with brilliant ideas but poor execution fail. Or so, at least, it has gone at the companies for which I have worked. I was once in a startup with an idea that I thought was brilliant. But there was so much infighting inside that company that neither sales nor engineering could build a strong execution rhythm. That company is still limping along but to my mind its product never reached its potential.
If your company uses agile processes, you’ve hopefully broken your work down into small enough chunks that even if you choose a wrong feature to build, you won’t pull the cart in the wrong direction for too long. You’ll deliver a little software, see how the market responds, adjust your direction as needed, and repeat (and repeat, and repeat). Ideally, this system self-corrects.
By all means, if you disagree with the features you’re assigned to build, provide that feedback using whatever mechanisms your company offers. But after the plan is set, execute it as strongly as you can.
Did you know that a fly doesn’t scale? If you shot a growth ray at a fly until it was the size of your car, that fly would crush under its own weight. Its exoskeleton can handle only so much mass.
It’s a good thing flies stay as small as they are. But if you’re at a small, startuppy company, of course you hope your company grows. It’s what we all want, right? But meanwhile, there can be so much goodness, so much energy in a young company. You can wear so many hats! You can shoot from the hip! The hierarchy can be so flat! Everybody fits into one room! Communication is so easy! Everything and anything feels possible!
But much like the fly and its exoskeleton, your company’s light, informal structure will keep it from scaling. One day everybody won’t fit into one room anymore. You won’t be able to know everything that’s happening just by being in the room and on Slack. Stuff that used to happen organically just doesn’t happen well or at all.
That’s when meetings may creep in where there had been none. When the first process steps may start to be added. When software tools may augment or even replace simple face-to-face communication. When company-wide fun events may start to drop off because it’s too hard and expensive to include everyone.
The place starts to feel …corporate.
People sometimes fetishize startup smallness. It feels so good! But clinging to it will limit your growth trajectory. Like the overgrown fly, lack of process will crush your company. You need to change your ways of working to fit the company’s size. But this doesn’t have to be terrible. It totally can be terrible, if you do it wrong. Even if you do it right, it will change and even get rid of some of your company’s original goodness. But it enables new levels of goodness that you can’t imagine yet.
The tax of size simply must be paid. But don’t pay one penny more than you need to. At every step, add just the minimum process to keep things running smoothly. If you’re an individual contributor and thus probably not making the process decisions, perhaps you can (kindly, respectfully) ask if you can offer feedback, and if so, suggest changes to size the process to where you are now.
This is a bumpy road, and there’s no map. You have to feel your way through. But here are some questions you can ask that might help you.
What’s the least possible amount of process we can add to solve our current problems?
How can we break our organization into smaller units to keep the goodness of small?
How can we put light communication, visibility, and accountability systems in place that help the small units stay connected and deliver strongly for each other and for the business?
To the extent you’re able to successfully evolve your company’s exoskeleton of process and culture, you’ll smoothly adapt to the pressures that come with growth.
Programming is the number one quality assurance activity.
Or maybe it’s design. Or maybe it’s writing good user stories. Or maybe it’s having good ideas for things to build in the first place. Or maybe it’s paying down technical debt.
But it sure as hell isn’t testing.
When I talk to engineering leaders at small software development shops and they find out I make my living in testing, many of them admit that they don’t have any testers yet. They’re sheepish about it. It’s as if I’ll be offended!
I tell them to rock on, and to delay hiring that first tester for as long as they can.
And then I ask them about the quality challenges they have. Too many bugs? Won’t scale? Bogs down under load? Don’t fall prey to the gut reaction “oh my god we need to test,” as if testers are a magic filter through which perfect software passes.
Because if you respond by hiring testers, you’re likely to end up with testing theater. Your testers will do testery things and find bugs, sometimes even good ones, bugs that let you sleep better at night.
But they can’t fix your quality problems. Only your developers can do that. Instead of letting your developers do whatever it is they do and hope a tester can find everything that’s wrong, challenge your developers to get better.
I ask them these questions:
Do your developers have the skills needed to build the software you’re asking of them? If not, help them build those skills or, gulp, replace them with developers who have them.
Are you following good development practices? Test-driven development, pairing, and code reviews. Not only do they promote solid code, they help create a culture of quality among your developers.
Is your team writing lots of automated unit tests and and acceptance tests? (By acceptance tests, I mean thin functional tests at the API or controller level.) Do they run on every commit? This traps basic problems as soon as they’re introduced.
Do you have a well-functioning delivery methodology, at the right scale for your organization? If you’re two developers, that might be a kanban board drawn on a whiteboard. If you’re ten developers, you might use a tool like Pivotal Tracker and have a couple defined but light rules and ceremonies. If you’re 100 developers, it might be some scaled agile methodology like SAFe, backed up with a tool like JIRA, guided by a program management office. Whatever it is, are you following it and is work flowing smoothly through the delivery pipeline?
Are you giving your developers the time they need to do thoughtful work? To design resilient software that performs? To architect it for long-term growth?
Do all of these things before you hire your first tester. Your developers will give you a level of quality that makes it hard for testers to find low-level bugs. Testers will then have time to find more interesting and valuable bugs because basic stuff is seldom broken. This makes testing a lot less expensive, by the way. You need way fewer testers when you deliver software to them where core functionality works.
And then your testers, instead of feverishly testing the basics, can contribute at a higher level. Testers bring a different mindset to your teams, one of critical thinking about how the software is deployed and used. When you harness that mindset, you can improve your designs and your architecture before you write that first line of code.
A woman named Verna built the house I live in. She landscaped it nicely; a sprawling flowerbed stretches in front of my front door and picture windows. Every spring, I eagerly await Verna’s spring color: yellow daffodils, purple hyacinths, red tulips, and finally the giant pink peonies.
I’ve added a few things: lilies, mums, lavender, coreopsis, phlox. I love phlox! But my eagerness to keep adding color petered out pretty quickly because it turns out I hate digging in the dirt.
I don’t much enjoy any of the other routine garden maintenance, either. Mulching. Deadheading. Dividing overgrown plants. Weeding – oh god, the weeding. Does it make me lazy that I just spray my weeds with Roundup and move on?
I just want to enjoy the flowers. But this ninth spring I’ve lived in my home, a few of my plants didn’t come back as strong. A couple didn’t come back at all.
So I asked my mom. She’s the gardener in our family. “When was the last time you fertilized?” she said. “Um, never,” I said. “Ah,” she said.
It turns out that you can’t just ignore the soil, or the plants themselves for that matter. Things growing in it year after year uses up all the nutrients, and crowded plants compete with each other for what little is there. “I’m surprised your flowers didn’t stop coming back a few years ago,” Mom said.
I did some serious fertilizing this season. I also separated some overgrown hostas and moved some of Verna’s plants so they had some elbow room. Not fun, but necessary.
♦ ♦ ♦
I once worked for a software company whose flagship product sold briskly. Version 1.0 was five years in the past, and since then we’d added lots of new features so the product could continue to lead the market. And now here came the head of Product Management asking for more new features
Dan, a quiet fellow, graying at the temples, led Development. “Well, yes, we can add all those features,” Dan said, adjusting his glasses. “This one will take six months. That one will take four. This other one, well, I think that’ll take a year.”
The Product Manager was dumbfounded. “Features of similar scope took far less time in the past, and you had fewer developers then. What gives?”
Dan looked up at the Product Manager kindly, and drew a breath. “Well, we’ve been under such pressure to quickly add features to this product that we’ve not focused enough on its overall design. We’ve also made no time to keep our underlying architecture up to date. These are things I’ve been pointing out all along the way. But we’ve just bolted features on wherever we thought we could get away with it. Now, to add any one of the features you’ve requested, we basically have to unbolt three or four other features, and blend the code all together. And we have to write complicated bridge code to do modern things with our aging architecture, and when that doesn’t work we will have to upgrade some parts of it and test the product well to make sure everything still works. It’s a slow process. And it’s just going to get slower and slower the longer we keep going like this.”
That the product’s design had become cancerous and the underlying architecture had gone out of date were not considered a crisis –- but not being able to rapidly add new features sure was. It focused the company’s entire attention. Their response was to code up a “next generation” product from scratch, which was a disastrous idea for a whole bunch of reasons beyond the point of this story. When the dot-com bubble burst in 2001-2002, they had not yet successfully launched the next-generation product, and they still couldn’t add features to the old product fast enough. Revenue fell precipitously. Quarterly layoffs began, but it was not enough to keep the wolves from the door. That once-promising company was sold; the company that bought it outsourced development to China.
More recently I went to work for another promising software company. They had been in business for about a decade and had sold their software to a number of very large companies. But in the couple years before I’d been hired, the pace of new feature delivery had slowed to a crawl. Adding new features had become increasingly difficult and always broke existing features. As a result, it took longer and longer to test the product, but even then, major bugs were still being delivered to customers. Meanwhile, younger, more nimble competitors were stealing business away from us. As the rate of new revenue decreased, support costs skyrocketed. It was unsustainable, and that company, too, had to sell itself to another company to avoid collapse.
It was much the same story: the company had focused entirely on rapid new-feature delivery and not enough on ongoing design and architecture. After a decade, their soil had gone infertile and the code had become tangled. Nothing new would grow.
♦ ♦ ♦
Software as a garden: to be able to grow more software, to be able to grow revenue with it, you have to keep the soil fertile and give the roots room. The problem is, gardening projects are a hard sell. These are things like refactoring older parts of the code that no longer serve efficiently, or upgrading or replacing outdated parts of the architecture, or redesigning subsystems that work fine today but can’t adapt to things the company wants to do in the future. When you tell executives you need to do these things, what they hear is that they can’t have new features while you do it. New features fuel growing companies.
But if you don’t tend your garden, sooner or later it will stop producing.
But it has the consequence of blocking support techs from moving up into more interesting — and more lucrative — roles in the company. It makes support a total dead end job. But more importantly to the company, it takes away a key element that can make the software better.
Support jobs aren’t always an automatic growth opportunity. The supply of support techs usually dwarfs demand for roles they can move up into.
But it’s no wonder support techs want to move up — support is hard. For less money than other technical roles in the company, you have to listen to unhappy users all day and try to help them get the promised value from your company’s products. It’s emotionally draining. I’ve heard support techs joke more than once that support years are like dog years: every year you work feels like seven.
Still, support really can be a good place to grow talent for other teams because techs know the products and, more importantly, how users actually work with and experience them. Support techs spread this invaluable perspective anywhere they go in the company. This is why I love to hire support techs into my testing teams.
But another reason it’s good to keep support in the same building is that it makes the software better.
Here in the Midwest, where cost of living is generally low, the startup, small, and medium-sized companies where I’ve worked don’t outsource customer service. Those workers are already plentiful and inexpensive. And so support is always down the hall or on the next floor. Developers and testers become friends with many of the support techs.
To developers and testers, users can be an abstract concept. It’s a shame, but since we don’t know them and don’t experience our products as they do, we feel freer to make choices that are expedient for us but potentially unpleasant for them.
But we always get an earful from support when things don’t work well! And we don’t want to create difficulties for our friends there. It makes us work hard to deliver software that doesn’t make the phones blow up.
Successful software delivery is a team sport. Don’t cut off a key part of the team just to save a dollar.