How I Started the Process of Healing a Dying Software Group

When I stepped into the role of software development manager last year, I knew I was inheriting a challenging situation. The group of 15 developers across 3 teams was struggling with low morale, a lack of direction, and a poor reputation within the company. From an outsider‘s perspective, it seemed baffling how such a talented group of engineers could be languishing in this state.

As I dug deeper in my first few weeks on the job, the picture became clearer. The group was drowning in technical debt, saddled with outdated legacy systems that made even the most basic development tasks a slog. The primary codebase was a tangled mess of spaghetti Java with no unit tests, haphazard error handling, and zero documentation. Database queries were hard-coded with no thought to efficiency. Deployments meant scheduling a 4-hour outage window while the ops team babysat the app.

The impact of this technical debt was staggering. A report by Stripe found that engineering teams spend an average of 33% of their time dealing with technical debt and bad code, costing companies an estimated $85 billion annually. My team was certainly on the high end of that statistic. Basic features that should have taken a week to deliver stretched out for months as developers wrestled with instability and side effects.

Beyond the technical issues, the group dynamics were equally concerning. One disruptive team lead (I‘ll call him "Steve") seemed to shoot down every suggestion and constantly fought with other teams over resources. The development managers before me had fallen into a pattern of saying yes to every incoming request, causing wild context switching and half-finished projects. There was no clear product vision or roadmap, so teams worked on scattered pet projects without a unifying purpose.

I realized my first priority had to be getting to know the developers as individuals. As the famed management consultant Peter Drucker said, "Culture eats strategy for breakfast." No amount of technical or process solutions will succeed if the team is demoralized and dysfunctional.

I scheduled 1-on-1 meetings with every single person, from the most senior architect to the newest hire. We met over coffee or went for walking 1:1s to break the ice. My goal was to understand their background, technical strengths, professional goals, and frustrations, while sharing some of my own leadership philosophies. I made it clear that I valued their candid feedback and wanted to work together to right the ship.

These informal chats helped me quickly identify the team members who had untapped leadership potential. There was Jane, a front-end ace who had great ideas for improving UX but felt stifled on her current project. And Sanjay, a thoughtful mid-level engineer who was the go-to expert on the hairy backend systems but avoided the spotlight. I made a mental note to carve out meaty projects that would help them grow.

With a baseline understanding of the people, I turned my focus to the work itself. I pored over the team‘s Jira boards and wikis, but found mostly stale data. So I gathered the whole group for an offsite workshop where we could reset and define our identity and objectives. What should this software group be uniquely great at? What products and technical capabilities do we want to be known for?

We used a "prouds and sorries" retrospective format to celebrate strengths and honestly acknowledge areas where we had fallen short. There were some tense conversations and tough pills to swallow. But the session ended on an optimistic note, with shared excitement about our new mission to become the go-to experts for data-driven product experiences. With that north star in place, it became much easier to prioritize our backlog and politely decline work that didn‘t align.

Of course, a inspiring mission means little if you don‘t have a high-performing team to execute it. In addition to Jane and Sanjay, a few other standout developers caught my eye during the offsite. I pulled them aside and floated the idea of forming an informal "tech lead council" to help guide our modernization journey. I wanted to give them a platform to step up as leaders while also distributing decision-making more broadly across the team.

One of our first orders of business was defining a technical roadmap to incrementally address the hairball legacy systems. Using the Eisenhower matrix, we plotted out the effort and impact of different initiatives. Migrating from Java 6 to Java 11 was an easy win that unlocked performance and security benefits. Adopting a microservices architecture for greenfield development would help us avoid further monolith sprawl. Beefing up our automated testing was crucial but would be a heavy lift.

We couldn‘t afford a "big bang" migration, but I pushed the team to carve out 20% of their cycles for this infrastructure work. I played the role of "tech whisperer" to help non-technical stakeholders understand why it was so crucial to pay off this debt. To grease the wheels, we pitched some of the modernization efforts as "funded development" that would directly support strategic product bets.

Meanwhile, we scrutinized our development workflow and found easy opportunities for automation. A little Jenkins scripting helped us build a rudimentary CI/CD pipeline to replace the manual deploys. Jira plugins helped manage tech debt and visualize team capacity. Splunk dashboards revealed the performance impact of different code refactors.

Each small win boosted morale and made the next project that much easier. When the first microservice deployed to production without a hitch, the team‘s Slack channel erupted in celebration. When we sunset a crufty legacy API gateway, there were literal tears of joy.

It was particularly gratifying to see Jane and Sanjay grow into their leadership potential. Jane spearheaded a major front-end framework upgrade and wowed the UX team with her thoughtful component library. Sanjay‘s systems diagrams became the go-to reference point for ramping up new hires. Their voices carried serious weight in our architecture discussions and their influence radiated out to other teams.

This momentum served us well when the next fire drill hit. A top customer escalation revealed a critical gap in our data pipelines that threatened a seven-figure contract. In the past, the team would have panicked and pulled a bunch of all-nighters to hard-code a quick fix.

Instead, we huddled up and quickly identified the analytics and ETL enhancements needed for a scalable solution. Rather than taking shortcuts, Sanjay pushed for higher test coverage to harden the pipeline for future changes. Jane worked her UI magic to help the customer success team explain the insights. When the fire was extinguished and the contract saved, it felt less like luck and more like a well-oiled machine clicking into place.

That‘s not to say it was all smooth sailing. There were still plenty of days where I questioned if I had taken on an impossible task. Untangling legacy spaghetti code sometimes felt like playing Jenga blindfolded. Discussions over logging frameworks devolved into unproductive bike-shedding. The agile consultant I brought in to level up our Scrum practices was met with eye rolls and "not-invented-here" objections.

But I consistently beat the drum that this was a marathon, not a sprint. We celebrated small victories and extracted lessons from the setbacks. I made sure the team had air cover to try spikes and experiments, within reasonable guardrails. When the Github Actions YAML grew unwieldy, we had an honest retro and agreed to go back to Jenkins for a while.

Sanjay‘s first crack at a Redux refactor caused more bugs than it solved, but we applauded his initiative and discussed better approaches. I ran interference with stakeholders to explain why some modernization efforts had to stay under the hood, trusting that the results would speak for themselves.

To really turn the corner, we needed a flagship effort to prove our capabilities to stakeholders. I worked with product managers to identify an opportunity that could showcase our revamped tech stack and position us as the experts in data-driven personalization. It was the kind of meaty project that would stretch our architectural muscles while delivering a slick user experience.

By this point, the team‘s confidence and collaboration were light years from where we started. Jane took the lead on product discovery, impressing the entire C-suite with her crisp wireframes and user flows. Sanjay architected a machine learning pipeline that could crunch terabytes of behavioral data in real-time. Our DevOps crew had the whole thing running smoothly on Kubernetes, with a slick Datadog dashboard to prove it.

When we finally unveiled the new product experience at the all-hands meeting, the buzz was palpable. Suddenly this software group was being hailed as an example of agile innovation. Our business partners started lining up to work with us. Most importantly, I could see the pride and confidence radiating from each developer. They had poured their heart and soul into this effort, and now they were hungry to keep raising the bar.

As I reflect on this journey, I‘m struck by how intertwined the technical and human elements were. Yes, paying off the technical debt and modernizing our stack were critical to improving developer velocity and system health. But that work would have floundered without equal investment in mending the team culture, honing communication, and growing leadership.

It‘s fitting that the software industry has largely converged around the term DevOps to represent this fusion of tools, processes, and culture. There‘s a growing recognition that you can‘t treat developers as interchangeable cogs, or expect a product to succeed without empathy for the people building and operating it.

This transformation is still very much a work in progress, and there are always new fires to fight. But I‘m immensely proud of how far this team has come. We still have plenty of tech debt to tackle, and our agile maturity is a constant work in progress. But there‘s a palpable sense of excitement and a recognition that these challenges are opportunities to hone our craft.

The true measure of success is that this software group now has a strong sense of identity and a belief in their own potential. They‘re a shining example of what a world-class engineering team can accomplish with the right balance of autonomy, alignment, and psychological safety. And they‘re paying it forward by mentoring other teams who are embarking on their own modernization quests.

My biggest lessons learned? Technical problems are usually people problems in disguise. Fight for your team and clear away the roadblocks so they can do their best work. Celebrate quick wins but keep your eyes on the long game. Invest in a strong bench of technical leaders, and give them room to stumble occasionally. Most of all, never stop learning and adapting. The best software teams think of the journey as the destination.

Similar Posts