So you’re starting a new development team…

Sandy Cash
14 min readNov 21, 2021

--

I recommend skipping number 4 on the list.

You are sitting there at your desk, happily coding away. Your manager pings you, maybe in Slack or some other messaging tool, and asks to meet. What’s up, you ask? Your manager says, well, we’re starting a new project, and I need someone to lead the development team…I was thinking this would be a good opportunity for you.

I’ve started and led a fair number of development teams in my career, and I still get a bit nervous when I get the call to do so again. Because, no matter how many times you go through this, every development team is different. They have different members, different personalities, cultures, the projects are different, and so on. And I learn something new (and, I hope, get a bit better at it) with every iteration.

But despite the variation, there are still some good general guidelines I like to follow, and in this article, I’m going to discuss some of these — with the hope that, if you get the call to start and lead a new development team, you can find it just a little bit less stressful. There is no one-size-fits-all cookbook, but there are some practices you can follow that should help get your team off to a more successful start.

Take a breath and try to relax

Maybe you’re a seasoned pro, maybe this is your first chance at leading a team. Maybe you don’t even like leading teams (you just want to code). Either way, it can be stressful, because someone, somewhere, has a budget, and that person is a key stakeholder in your project. That person has decided, I’m going to allocate funds to support this particular effort, and one of the individuals with the greatest power to affect the relative success or failure of the project is…you.

Start off by thinking, “I am in this position because someone (your manager, for example) believes in me.” So you should believe in you. You’re going to make mistakes, no matter how long you’ve been in this business, for the simple reason that you’re human. Accept that and move on, just learn from them as you go (this is what you already do as a developer, I hope).

There really is no perfect playbook

Almost every shop these days says, “we do Agile,” but I think that, in far too many cases, that means copying (far too uncritically) what some widely-seen-as-successful company is doing. The next step is codifying that as a top-down mandate on how to run development teams, but without actually evaluating how well those practices will work for the target organization. Or an organization will invest in training managers and executives on a particular “style” of Agile and treat that as the gospel — this manifests itself as declarations of, “we do Scrum/Extreme Programming/RUP, and that means we do X, Y, and Z.”

If you have never read it, take a moment to go read the actual Agile Manifesto. The Manifesto describes not so much a process or group of practices as it does a particular philosophy. And personally, I would sum it up as, “people are the most important ingredient.” And since people change (individuals evolve, and the cast of individuals changes over time), so then must the processes, tools, and practices we use. So don’t expect that you can just follow a book or tutorial on Scrum or Extreme Programming and be successful. Maybe you can, maybe you can’t, but you should never assume that’s the case.

Personally, I have made the mistake in the past of trying to be far too doctrinaire about following a particular methodology — because I had decided, “this method looks better than what we are doing now, and to be successful, we need to follow the new method to the letter.” I don’t need to tell the more experienced hands out there that this did not work out that well, and I had to take my fair share of lumps to learn better.

Be willing to adapt, too — as I said before, you’re going to get some things wrong — not because you aren’t good at your job, but because you start off with imperfect information. Maybe you know everyone on the team, they all know each other — if so, great (assuming they get along well and are not at others’ throats from day one). But maybe you get handed a team of new developers, folks with whom you have never worked before. It will take time to get to know their personalities, strengths, and weaknesses, but you will have to have them working from the start. So recognize that “the way we do things today” may not be “the way we will be doing things tomorrow.” You will know more tomorrow, and maybe you (and the team) will make different decisions as a result.

Do not penalize experimentation

At some point, presented with alternative solutions, you have to choose one and roll with it. Maybe it’s the right one, maybe there is a better one, but you have to pick one and implement it as part of your product. But especially early on, you should be encouraging your team members to experiment — part of this goes hand-in-hand with uncovering complexity as early as possible. But part of it is also about building a penalty-free culture — which is to say, no one should free afraid to try a technical approach because they might screw up. We have all done it, we all do it, and if we don’t try things, we never really learn what the right/wrong approaches are.

When I bring new (to my team) developers on board, I tell them, you will have to work at this for a long time, and you will have to put out real effort, if you are ever going to screw up worse than I have ever done. I have some specific stories (none of which I’m going to recount there, I still have some pride) I share with them to illustrate that, no matter how bad you think you’ve screwed up, I’ve probably done worse, so don’t stress out.

This is not to say we should be bulls in china shops— but if you are not willing to try out avenues not previously explored, you are not going to learn or grow very much, and you are not going to help the team do so, either. Mistakes happen, and all I ask is that you be honest about them when they do. That way, I or another team member can help clean up, if necessary. Not to mention, that is the only we can harvest the oh-so-valuable lessons to be learned.

Make team members accountable to one another

In a top-down culture, team members do things because they are told to. But in a team-driven culture, team members do things because they help the team move forward — they understand the why of e.g. good testing, they are not just doing it because you have a coverage metric they need to meet. So help them to understand why they should be testing before committing — because if they don’t, it’s going to result in buggy builds and blocked pipelines, which will result in their teammates not being able to contribute, and vice versa.

Some technology choices matter, some not as much

There are some technology choices on which the team will need to come to agreement — the choice of programming language(s), for example. Another example is the CI/CD framework. In some cases these will be dictated to you (your parent organization may have standardized on using a particular SCCM system, such as GitHub), in others you may have some leeway. Where you can, allow team members to make choices that will work best for them.

A good example of where you can often give team members some freedom is the choice of editor. I have a colleague who has the most tricked-out vim configuration I’ve ever seen — he can just about make it brew a cup of coffee (and maybe he even has that working by now). Other developers gravitate towards editors like VSCode, Sublime, Atom, or Eclipse. Other developers (of which I am one) will sometimes vary the editor used based on the language. If I were to do a Java project again, I’m pretty sure I’d get Eclipse fired up, even though I use Atom most commonly nowadays. And for a long time I used RubyMine whenever I did any Ruby work.

My point is, the choice of editor is unlikely to be a big factor in your team’s success or failure, so why worry about it? Let your team members use the tools that make them comfortable and productive whenever possible.

Get your CI flow working early

This is actually an easy one to get wrong. I’ve seen teams deal with manual builds for months before investing in a solid CI flow, and the cost can be pretty large. As soon as you have even a trivial build of a single component, get the automation working. Incorporate testing and deployment as well. Relying e.g. on good faith manual test execution is a recipe for eventual disaster, because someone will forget the step and blow up your build. So invest early on in good automation, the returns far outweigh the costs.

Get to know your team members…

You need to know your team members — personally, yes, but also you need to know who has what strengths and weaknesses. Not everyone will have the same skill levels. Identify early on who the stronger team members are, and try to ensure that they work with the less-skilled members. You do not want to let a new, relatively less-skilled developer languish — so knowing who can work with them, if needed, is key. This will also help towards building a collaborative team culture.

…and give everyone a chance to lead.

Leading a development team is tricky. It is not an easy job. And you only make it harder if you try to do it alone. “Leading” does not mean the same thing for everyone. There are decisions that need to be made by you — democracy can have its limits. But your team members need to know that their opinions matter.

Remember earlier, when I was discussing the perils of doctrinaire adherence to some documented development methodology just “because it’s what we do?” Your team is a group of individuals unique from every other team, even from the one just over the next partition. What works for a peer team may or may not work for you — so solicit input from your team on what they believe does or does not work. The kind of input you get will vary across team members, and it will change as the team matures. Be sure you are not simply asking pro forma questions — if you ask the team, “what should we do here,” and they express a clear preference and have solid reasons for why that’s the route to follow — then consider doing what they suggest. If you ask for recommendations but repeatedly disregard them, it will not take long for the team to see you as insincere. I should not need to tell you that you do not want that.

Another practice in which I firmly believe is helping the team members to grow. It is highly likely that team members will be at varying points in their careers. Some are just starting out, others are experienced pros. They’ll have different ambitions, too. Some just want to crank out code all day, others have an eye towards moving into architecture or possibly management. For a system of nontrivial complexity, I like to delegate portions of the architecture to some of the more senior team members. I do this for a couple of reasons. One, I want them to feel invested in our product — and giving them a say in how it is designed can help with that. Two, it makes for a better product. I’m one person, and I am realistic about not being capable of making every single design or architecture decision with the depth of consideration it deserves. So I sound out the more senior team members to see who might be interested in particular areas, and then I delegate one or more areas to those team members who express interest.

“Leadership” opportunities exist for the less experienced team members as well. One example is running a daily scrum. Or, as they gain skills, identify specific technical problems that need to be explored — tricky spike stories offer great chances to pair up junior and senior developers and send them off to hunt big game. Giving the pair some autonomy as a mini-team is another good way to encourage a feeling of investment in the product, and, again — you need team members to be SMEs, because you cannot be the one person who has all the answers (as in, it’s usually literally impossible, not to mention incredibly unhealthy).

You can probably put off performance testing for a bit

Almost as soon as you have even a minimal prototype working, you will be asked by someone, “but how well does it perform?” The honest answer is, you don’t know yet and don’t actually need to know. Maybe it appears blindingly fast (it can handle bajillion requests per second, it can shove terabytes of data around the world in a flash, whatever), but it’s just…a minimal prototype. At this early stage, it’s fine to run a sniff test, but the kind of performance testing I’m talking about is rigorous and regular performance testing — which you will almost absolutely want at some point. But not just yet.

Let me give you an example where I nearly got this wrong. I was leading a team working on some components doing large-scale data transfers. I was keenly aware of a specific throughput target. So I prioritized backlog items to build out a performance test bed with automated execution and reporting so that we could measure our performance against this target and identify potential regressions.

A development manager friend of mine pulled me aside and said, but we haven’t even added in this key (and mandatory) integration, and we know it carries a nonzero performance cost. And we have several other key components we need to integrate as well. Is it worth investing in a robust performance framework just yet?

The honest answer was (and is), no, it wasn’t worth it. Because while we could have established a baseline, it would have been a meaningless one at some level, because we knew throughput would necessarily be affected by integrations we had no choice but to implement, but which we had not yet added to the build. Say you build a sports car prototype, but you only have the engine from an old hatchback to put into it. You demonstrate your car, but…it’s slow. Of course it’s slow, you are powering it with an old, crappy engine for now. It’ll be faster with the new engine. How much faster? Don’t know, don’t need to know, because it’s a meaningless comparison. You will never go to market with the hatchback engine as an option.

This isn’t to say that investing in the performance testing framework was a bad idea — but, like most development teams, we had finite resources, and not everything can be a priority. At that point, we did not have enough function implemented yet for any performance evaluation to carry meaning, so it was a better use of our time to flesh out the system and get something approaching an MVP working than it was to demonstrate that a skeletal solution that did almost nothing was “fast.”

The backlog is a shared resource…

Some descriptions of Agile methodologies will advocate for the role of Product Manager — this role usually manages the contents and priority of the backlog. In essence, the Product Manager decides what work the team will tackle next. In this capacity, the Product Manager might also be on point for engaging with requirements stakeholders and ensuring that requirements are captured as work items in the backlog.

This can sometimes encourage a view of the backlog as the private domain of the Product Manager (or a similar role). I think that the backlog is the domain of the entire team. Team members are the ones on the ground doing the work, and they’re usually the first ones to identify and recognize key work items that may not derive directly from external requirements. Work on infrastructure, code hygiene, and tooling is all part of the development scope, and your developers will be the ones who usually advocate most loudly for these work items, because they are the ones who will suffer if the work is not done.

Urge your team members to create work items and raise them at iteration planning meetings. Note that I am not advocating for chaos — changing the priority of items in the backlog is an authority that does generally need to be concentrated on an individual or a limited group of individuals (in larger projects). But I am advocating for empowering team members to contribute to the work scope with items that they identify in the course of doing their jobs. Do not try to funnel those by saying, “only X can create work items, so talk to X.” If they add a work item you don’t think needs to be done right now, deprioritize it, whether you do that yourself or in consultation with stakeholders. If the scope of the work item is not clear, work with the team member to get the scope defined more clearly, and use this as a teaching moment so that they get better at defining work items moving forward.

…and the backlog is sacrosanct

Protect your team from “requirements” flying in from the side. Maybe there’s a particularly aggressive stakeholder who has a habit of reaching out to individual developers and pushing for some addition because “it’s really simple, I could even implement it myself, I’ve got a big deal that won’t close without this, etc.”

My mantra is, if the work item is not in the backlog, it does not exist. By that I mean, empower team members to respond to sideways requests with, “feel free to talk to our Product Manager and get a work item created for that.” Team members should never feel pressured to put down what they’re working on and do something else “as a special favor.”

This goes back to the culture of team accountability — to the world outside of the development, there are no individual commitments, there are only team commitments. But for the team to make a commitment as a unit requires that the individual team members make commitments to one another. For example, you pick up a work item for the current sprint — you are committing that you will contribute to team velocity by working on that work item, and the ability of the team to commit to fulfilling a broad requirement may well depend on you delivering that work item. But what happens if you agree to one of these “special requests?” By saying yes to the request, you effectively say no to the team and break your commitment. Set expectations both internally and externally that this is not the way your team will work, and hold the line. If the request is actually that important, the requestor can take the time to get a work item opened for it. And if it is truly time-critical, then make sure you discuss the reprioritization with stakeholders so that they understand (and, hopefully, consent to) the impact on the team’s other commitments.

Into the breach!

I have tried here to share some of the…I don’t want to call them “principles” as such, because these aren’t a set of moral standards or carved into stone, not even for me. But they’re guidelines which, at least at this point in my career, seem to be serving me well. I hope that, at least for those of you starting out at the helm of (one of) your first development team(s), there are some nuggets of wisdom and/or insight which give you a leg up. If you’ve got your favorite war stories which illustrate some of the practices that work for you, I’d love to hear them (if you’re willing to share). I’m also keenly interested in opposing viewpoints. If there’s one point to take away from all of this, it’s that no one gets this perfect every time, and I certainly learn new things with every team and project. And to be honest…that’s part of what makes the job enjoyable!

About the Author

I am a longtime developer and IT professional who has been lucky enough to work on projects and with teams from all over the globe. I am also a (human) language nerd — I speak several languages, I’ve studied a bunch of other (mostly dead) ones, and at one point I had dreams of becoming an academic linguist. I spend my free time as an avid (formerly competitive, hope springs eternal) cyclist, cooking/mixing drinks, and out enjoying nature.

--

--

Sandy Cash

Software engineer, birder, cyclist, language nerd, maybe just a nerd. Never stop learning. A friendly smile costs you nothing.