The best team ever
So what was so great about this team? In short - problem, people, power (and fun).
We were three developers - Alex York, Jakob Lind, and me - brought in to do something unheard of - prove that having development in-house, despite being more expensive, enables so much more revenue that it is absolutely worth it. That gave us an attractive, tough challenge in front of us.
From the start, the project was conceived as a hypothesis-based experiment, and had a few months to prove itself. This clear, measurable outcome and limited time gave us laser-sharp focus on what mattered most and pushed us to be constantly finding innovative ways to be able to get there.
We were also solving very real pains that the business had from the inflexibility and glacial speed of development of the existing solution. We knew closely the people we were helping and felt great satisfaction in enabling them to fulfill their "dreams" and removing sources of frustration.
In summary, we had an attractive challenge, clear and measurable goal, and we were helping real people with real problems, and they were actively helping us to help them.
We three developers were all deeply passionate, smart, with very diverse background, experience, and approach, yet we all shared the same core values and mindset. Jakob was very focused on delivering. Alex was a champion of simplicity and provided a great sparring partner that had to be persuaded to bring in any complexity (a library, design). I brought focus on avoiding the traps that plagued the legacy systems that scarred me and on smooth operation in face of chaos (thank you so much, Release It!). Our two wonderful, wise "elders" that made this experiment happen, Ketil Jensen and Magnus Indregard, contributed with deep knowledge of systems and agile thinking and the business (among others). They served as mediators between us and the organization, working magic to get stuff done. We all shared a nimble, agile mindset - a certain minimalism, a willingness to experiment, the desire to deliver value as soon as possible. And we all were "rebels" - looking for the best way forward without allowing to be limited by what others thought possible and by the customary ways of doing things.
Having to persuade two other smart people with different views is frustrating at times. But it forces you to really sharpen your idea and their critique and contribution helps to make something better than any of you could on your own. Diversity, "intelligence" (knowledge + critical thinking + passion for the craft), mutual respect, and a shared goal are the key ingredients here. There is a delicate balance between being neither too similar (to enable a creative conflict) nor too different (the shared core values that bound us together).
(I could only wish that we were also more diverse culturally and biologically and not just three white dudes.)
Our business unit supported us 100% and trusted us fully to find the best way forward ourselves (though the wider organization was more skeptical). And we were lucky enough that the new technical leadership was open to trying new stuff (such as running in the cloud). That made us a truly empowered team, us five had all the skill, knowledge, and authority to make the key technical and product decisions. (And in the worse case we followed the maxim that it is better to ask forgiveness than permission.)
We were also lucky that our dependencies on other teams were minimal. We did not need to constantly synchronize with them and get them to prioritize our needs. (And we actively worked on minimizing and bypassing these dependencies.) Empowerment is useless if others are constantly blocking your progress.
Trust, open-minded and supportive stakeholders, and skills empower teams to make all the important decisions that influence them themselves, which in turn makes the team members happy.
The team had a considerable "fun factor" thanks to an attractive goal and a task at just the right level. The goal motivated us to prove that we can do it. The task was so hard as to be challenging yet not beyond our capabilities (the same conditions that enable, on a smaller scale, flow). We also worked with cool technology - DIY thanks to AWS (no waiting for Operations!), the cool, up and coming React, and Node.js, which was very refreshing after years of Java. (None of us had any mentionable experiences with either React or Node.js yet it became great success - which shows that a lack of familiarity with a technology is easy to overcome if you have a capable team. That thought me that I don’t need to be afraid of introducing new tech, such as Clojure.)
We have constantly experimented with our process. When we were not sure about which solution to a technical or process problem was best, the answer always was "let’s do an experiment!". Instead of a big bang project, we went live after about 6 weeks - with a single page "pasted" onto the existing webshop. You can learn more about our various experiences from our blog posts at engineering.telia - nettbutikk and my 2015 talk Extreme Minimalism (slides).
I have since worked on other, self-directed teams, with many similar conditions yet it was never the same experience. Why?
Eventually, the charm faded out of the team. It has been a while so my memory is unreliable but I blame it primarily on three things: people, maturity, focus.
People: We lost one of the founding members to another project and the team grew to 5-6 people, which diluted the original team spirit. They were not bad people but it just was no more what it used to be.
Maturity: As the product grew and matured, the speed of and need for innovation and experiments in both the development process and technical solution decreased. The code base grew so large that no single person knew well all the parts, limiting everyone’s ability to contribute to design discussions. With the size and scope grew also the amount of maintenance work at the expense of new, big development.
Focus: Due to the growth, there were suddenly always diverse parts of the application that required maintenance (fixes, improvements) and so grew the influx of external demands (from beyond the immediate business unit) to implement support for new, unique products and company-wide initiatives. The team effectively broke down to ± five one-man teams working on unrelated things. Both the developers and business strived to keep some kind of focus and tried to curtail the externally generated work, but with limited success.
This team of three developers, a tester, and a gatekeeper towards the organization took over a large, important self-service portal for business customers. I really enjoyed working with this team, though it wasn’t at the level of the best team experience. Why?
People: The people were great and I really enjoyed working with them. But it hadn’t such a level of the "creative tension". The team had three developers, which is optimal in my experience.
Focus: We faced a similar problem as the late stage of the original project, with a large product and thus maintenance and numerous demands coming from different parts of the organization. We became partly specialized - the frontender, the devopser, the area X and Y specialist - and we regularly worked on unrelated tasks. On the other hand, we managed to maintain a higher level of cooperation with regular pair-programming sessions (thank you, Screen and Tuple!) and made some progress with establishing "focus periods" where we all worked on the same area. So there was more "togetherness" and fun.
Fun: There was lot of maintenance work on this huge, messy, Java & Spring application, so maximum "enterprise," little fun. Finding time to work on improvements was challenging, but the team managed to regularly schedule periods of improvement work (thanks, B!). And we introduced regular "Get Stuff Done" days (thanks, H!), where we ignored the business work and focused on technical debt, experiments, user pains. I always looked forward to these. We had also an attractive vision of the system - simplifying operations with moving from Kubernetes to Fargate, writing new stuff and rewriting some existing in Clojure and as microservices, … . It was a tough job juggling all these business demands, user needs, and improvements, but we were doing quite well. Perhaps as good as you could only wish for, given such a big, complex, legacy application.
A project to re-write the aforementioned self-service portal from scratch, merging it with another application. The good thing was that a lot of research has been done to understand the user base and to create a great UX (while UX in the existing application was often terrible). We also got to start from scratch with all possibilities open - yet it hasn’t managed to capture me. Why?
Scope was too big, both in time and in functionality. More on that below.
Boring technology: Some of the technologies we picked provided an improvement (mostly in frontend), some were boring (read: solid?), some I have an aversion to. At start it was challenging to get a microservice running locally due to runtime dependencies. Focus was on delivering functionality and operational concerns such as logging, request tracing, monitoring, troubleshooting-friendly responses - concerns I am especially interested in - were not prioritized. I got quickly burned out when troubleshooting things that did not work in this troubleshooting-unfriendly environment. In summary: nothing attractive in this domain. (I don’t meant to suggest you need to pick a new technology for each project. There are battle-proven yet not boring technologies.)
Too big team: The team was too large for me (and consisting mostly of consultants). I could certainly express my opinions and influence decisions if I wanted to but there was too much happening, too many people to talk to, it was simply too overwhelming. Thus I felt little ownership of the project. With a team of 3 + few it is much easier to build consensus and to discuss problems (and to keep focus). The people were just fine but not as intellectually stimulating as (the arguments with) Alex and Jakob.
Problem: We had a similar goal as the first project - rewrite an existing application - yet the approach and resulting attractiveness were quite different. The development was dissociated from the existing applications and the plan was to eventually (in a few months? year?) replace them fully, while developing together with a few pilot users. So I suddenly had still the existing application to maintain for many more months and a lot of work on the new one, and most users would not see any benefit for ages and would only be frustrated by our denial to improve anything.
An interesting question: what could be done to make this project more attractive? Here are some ideas that could have perhaps made the project more attractive, though I have no idea what actual effect would any have.
Clojure(Script) If the backend was written in Clojure then it would necessarily be more explicit (no magic configuration by classpath scanning) and simpler. More importantly, I would be much more productive - a crucial component of the "fun" of software development for me - because I could just connect a REPL to the running service, zoom down to the problematic code, run it at will, fix it, iterate. No more lengthy debug-code-compile-restart-retrigger cycles.
Strangler rather than Big Bang approach - choose a sore spot in the existing application, fix it in the new one, make them appear as a single application to the user (as we did in the first project). This is a fun challenge in itself, and it is motivating because we are removing existing users' pain points now, rather then in a year. Obviously it is much more difficult to do, but also more rewarding. I believe this is the main "fix" this project needed for my sake.
Small teams: Curving out an important sub-problem and creating a small, self-organized team (more on that below) around it might help. We have actually tried to split the problem into separate problem areas with separate, smaller teams, which made the situation less chaotic but otherwise did not help all that much.
Technology: An innovative architecture / technology (suitable for the problem) or a top of the class implementation of the technology, instead of an average, mainstream one, would be a great learning opportunity and thus a motivating factor. (I imagine that f.ex. a great implementation of a service mash, and/or a solution with a great observability and operational characteristics, might be interesting.)
Disclaimer: I should make it clear that making technological choices based on how "fun" they are for developers is bad. On the other hand, if there are multiple good options, why not pick a more fun one? Otherwise the developers must move to somewhere where they get enough fun and leave the project to more serious and dedicated workers.
This analysis rises some interesting questions.
In my view, it is a small group of people that have a shared mindset and a problem and work together to discover and build a solution to the problem. Let’s unpack it a little. They work together, interacting multiple times a day through discussions and occasional/regular pair-programming. You ask for help and opinions and provide support, you share your struggles and victories. They discover and build the solution based on the problem, i.e. they are not given an order to build a particular thing. They also have a shared mindset, though their individual values are ideally diverse (producing the aforementioned creative tension). They are also passionate about solving the problem. And ideally, there are people you really enjoy working with. (In my case, I can ask how they stack against Alex / Jakob.)
They most certainly are not a group of more-less independent task deliverers, that interact mostly only at a daily ritual and a periodic planning meeting.
The most important factor to make a great team is people. They need to be deeply knowledgable, passionate about the craft, there must be enough diversity to establish a "creative tension" yet enough shared values, friendship, and mutual respect to prevent any animosity. In my experience, the team size of 3 developers and a few other enablers is optimal.
The team must be empowered to make and execute its decisions by having the trust of the business, by having minimal dependencies on others, and by leadership removing obstacles to the effectiveness of self-directed teams. It is imperative that the team has a good communication with the business and that it has a full control of the technical stack, from coding to operations.
Problem - you want a project that is meaningful, actually helps real people with their problems, that has a clear focus and measurable outcome(s), and preferably one with some kind of a short or medium term deadline. (The deadline may be consensual though I observe that made up deadlines rarely work for me.) In my case it is also important that you deliver value very early. I am an impatient person, and not fond of delayed gratification in this regard. So no big bang projects for me, thank you.
Of course, it helps to work on a greenfield project, where you are free to make things the way you want and aren’t mired in maintenance work.