Trust is the highest form of motivation. It brings out the very best in people. — Stephen R. Covey, The 7 Habits of Highly Effective People
It’s basically a sacred project management mantra by now: divide your work into tasks that are as small as possible. Estimate them with your team. Then drop them into the all-knowing product backlog. But no one seems to be looking very critically at how this practice has affected the software engineering profession. Back in the ’90s, when I started programming, things were different. Dare I say, it was a bit more professional.
Back then, your boss had a dozen or more things they were responsible for, and when you got hired, they breathed a deep sigh of relief.
“Finally, now that Vincent is here, I can make him do A and B; and with Ted doing C, D, and E and Jan doing F, G, and H, I can finally get to I, J, K, L, and M.”
Most importantly, A and B were big things, like whole products or large system libraries. Building and maintaining them consumed all of your time. They were your delegated responsibilities, not mere tasks. It wasn’t that hard to manage people this way either. If you weren’t doing a good job, the boss would let you know.
“Hey, Vincent, A isn’t turning out quite like I was imagining. Can you do a little more of this — and definitely more cowbell.”
Then you went back to your private office (I sure miss private offices, but that is a topic for another day) and fixed a few things. Later, in a weekly status meeting, you would tell people how it went — yep, that’s right, no daily stand-ups where you look mournfully at your shoes and admit that you didn’t make any notable progress yet.
No backlog grooming meetings or burn-down charts either. Your manager simply looked at how your products were coming along. A little trust, some accountability, and a healthy portion of “give me some space to do my work.”
The way we work now is different. Sadly, it’s less motivating, less efficient, and profoundly less respectful of individual abilities.
Whose Vision is it Again?
As I see it, little tasks subtly suggest that all product vision belongs to management—keep away, don’t touch.
While larger tasks send a completely different message. Here, management is giving you bigger pieces to chew on, inviting you to mix some of your own creativity with the end product. You get to do some design work, think about what the customer needs, and take pride in what comes out the other end. Sure, the organization has an overarching strategy, but they still want people to take on responsibilities, not just errands. They trust you to align with the overall vision, and because you feel like you are part of the “club,” you actually want to.
Too Much Love for the Metrics
Small tasks have gained traction because they align perfectly with the age-old assembly-line mentality. Sadly, armies of managers still cling to that dogma, where it's all about picking metrics and optimizing them—management by chart and graph.
Unfortunately, little tasks in Jira (or any of the dozens of other issue tracking systems out there) bring the promise of a whole host of tasty new charts and graphs: burn-down, burn-up, velocity, lead-time, cycle time, task age, throughput, failed deployment, flow and control. It’s as irresistible as candy to a baby.
But assigning responsibilities instead of tasks takes away an assembly-line manager’s favorite tools. Because they are larger, responsibilities can’t be so easily measured and tracked. So metrics-managers will fight both tooth and nail to keep your work divided and cataloged in tiny, traceable instructions.
When Will I Get Some Design Experience?
Sadly, as developers, we do it to ourselves as well. Once someone gives us a better title, we are right on board with the program. When a regular developer might have had a chance to do some research or design, we immediately snatch it away for ourselves.
As technical management, we standardize our frameworks, languages, deployment operating systems, and cloud service providers. We write wrappers around networking, logging, and monitoring libraries and demand they always be used. Then, after we have taken the task of designing and researching the CI/CD tools and pipeline, we write coding standards for our coding standards.
Worse yet, we design every product’s architecture and expect any deviation to be approved by us first. All that is left are tiny morsels. Grunt work for the foot soldiers once the fun has been stripped away.
Poor front-line programmers are left wide-eyed with empty bowls, asking, “please sir, can I have some more? I just wanted to design one little service. I know I am not worthy, but can I please just write my own SQL queries without using that awful ORM? PLEASE?”
Sadly, when those poor programmers finally seek promotion, hoping for their first real shot at higher-level engagement, they are rebuffed: “You don’t really have any design experience I’m afraid. We are looking for someone who has designed large systems.”
To their managers, they could rightfully reply, “that was your doing, not mine!”
Estimation is Never Free
There is a grave misconception circulating that if you just sit down, in a comfy conference room chair, and split a project into tiny tasks, small enough to be individually estimated, then when you add them up, Voilà! You’ll have an accurate estimate for the entire project—easy peasy.
There are two problems with this delusion. First, no task, even a small one, is easy to estimate. I have seen many “tiny,” one-day tasks blow up into week-long campaigns. All because of hidden complexity that comes popping out like Pandora’s box once you start coding on it.
Second, when you divide work into little tasks, before actually working on any of them, you are making untested assumptions. Many of them. The more tasks you define, the more facets of a hypothetical design you must assume (implicitly of course, since no one ever writes design assumptions in task descriptions). Soon, you’ve created a long chain of design choices, all depending on previous ones, sitting on sticky notes on the wall.
The problem is, as soon as you start working on one of them, you will realize that your implicit design decisions are wrong. Now, you will spend MUCH more time than was previously estimated for this task, and all other tasks that depend on its faulty design are invalid. The whole house of cards comes tumbling down. Time for another all-day backlog grooming session? What a waste!
Conclusion
Back in the day, before everyone realized that software companies were positioned to make lots of money, we had some elbow room. We had a lot of responsibility and the ability to make a lot of decisions. But now, many more have piled onto the island, slowly chipping away at the domain of the software engineer. One by one, descending from their vessels, they planted their flags:
“I am Amerigo, the product guy. Heretofore, no developer will make product decisions, for they are mine.”
“And I am Ferdinand, process guy. Heretofore, no developer will make process decisions, for they are mine.”
“I Bartolomeu will enforce compliance.”
“I Vasco used to be pretty good at Microsoft Access, I guess I’ll be the database guy.”
One by one, until every responsibility that wasn’t actual open-up-emacs-and-start-typing-stuff programming was taken away, forbidden even. And then, the remaining, purely technical tasks were carved up by architecture/standard hoarding engineers, hungry for something of substance. Only dry, broken carcasses were left scattered on the ground.
Of course, there is a solution to this predicament — delegate responsibilities to everyone, all the way down to the bottom of the hierarchy. Or better yet, flatten or abolish the hierarchy altogether. But until that happens, you’ll just have to content yourself with measly for-loops and if-statements — following the coding standard, of course.
I've long worked at companies that have tried this small-task, assembly-line approach, and though in some circumstances it does get the job done, I've never really felt it to be particularly satisfactory, nor does it reflect the reality of how software actually gets built.
Recently I've been pushing a much more "holistic" approach, where we empower developers to own a particular area of the product, or a particular feature, and to be responsible for delivering it. How exactly they achieve that is largely left up to them, but the reframing of the task from "build this thing" to "make sure this thing gets delivered" has been so far successful. Developers are free to review requirements, pose questions, identify risks and break down the work as they see fit. If the task is large, then maybe that just gets raised and we can make decisions based off that, but by and large, trusting people to make the appropriate calls has worked out well, and the sense of investment and satisfaction does seem to have skyrocketed (though it's not like I have any hard numbers proving that!).
The only real hard production-level requirement is to either get it done in x number of weeks, or, if they don't believe that's possible, to give some idea of what *is* possible in that time, as early as possible.
Overall, good communication is the key. As long as people keep talking, moving things forward and raising any alarms as they're identified, things have gone well. It's been a very welcome break from top-down lists of tasks, in my view!