In this longer-than-anticipated blog post, I’d like to share the journey towards creating a cohesive squad, as well as the lessons and learnings we drew from the experience.
At the beginning of October, I was just about to set out on another adventure at a new company, meet more fellow shisha lovers, and be actively involved in revamping my new team. I was pretty lucky that three engineers from my former firm were starting at the same time. Moreover, one of the guys was going to be our manager and technical lead, so I was pretty excited to be surrounded by like-minded people with a similar background. When we joined, I experienced a bit of a culture shock — my new colleagues had quite a different working philosophy. They were holding meetings, facilitating discussions, and organizing their processes in ways I wasn’t accustomed to. Ways that I consider very sub-optimal. However, as a new addition to a team, you have to walk a fine line between suggesting potential improvements and becoming overbearing. I was definitely steering toward the latter (still am at times). I find it difficult to keep quiet when people are going on tangents or lack a clear agenda in meetings, not to mention rejecting industry-standard practices such as writing tests, trunk-based development and continuous deployment.
We were definitely at that stage of team formation between forming and storming and were having a lot of passionate discussions to put it elegantly. To be honest, I rarely reflect on the fact that people with completely different work histories and personal preferences need to find a way to work together for 8 hours a day without driving each other mad. Whoops. However, I would definitely give props to my teammates for the willingness to try stuff out. Little experiments — trying out having sprint goals instead of just a bunch of tickets in the “sprint”, having a dedicated backlog for improving the health of our systems, and maintaining high-quality documentation to name but a few. These minor tweaks made for a more streamlined approach when it comes to work, enabled everyone to be on the same page and improved our wellbeing. The difference in performance was quite noticeable — in the last quarter of 2020, we had missed a lot of our goals and were struggling as a tea. By the end of Q1 of 2021, we had managed to achieve all of our deadlines except 1 (which was only a week overdue).
However, for me, that wasn’t the biggest benefit of the overhaul. The thing that really brought it home was how much more empowered we were as a team. Previously, taking initiative wasn’t a common practice and people were often working alone, doing their own thing. We made great strides in this area — we are now much closer to the point where anyone can take any chunk of work and feel reasonably comfortable with tackling it. We collaborate frequently and try to help whenever someone requires assistance. Now, we are by no means perfect and still have a long way to go before we reach our potential. But that blog post will come once we get there. For now, though, let me share a couple of lessons we learned in the process:
Better tools make for better engineers
In my opinion, the tools we as engineers use daily — to test our code, deploy it to production, and monitor the behavior of services, to many a few — can either greatly improve or hinder our productivity. In a sense, they either make us better or worse at our jobs. One painful example I’m trying to forget — in order to deploy one of our systems to production, you needed at least a couple of hours (if you had a thorough README to follow, otherwise you could be spending days), had to navigate through a maze of Jenkins instances, and manually test your feature on two test environments (since at the time our test coverage was practically non-existent). Fast forward to right now — you merge to master and, bam, your changes are on the test environment. Another click and your changes are on prod. Tests are executed as part of the pipeline. We have some alarms in place in case things start going south. How much easier it is to work like that, instead of the former, error-prone way?
Of course, there is so much to improve here — better test coverage, blue-green deploys, metric checks — the list is endless. I’m sure all of these things will benefit us and we will look into them when the time comes, but there is always a balance to be struck between this work and actually delivering value by pushing out new functionality.
Share the knowledge and get people involved
There were some amazing engineers when I first joined my new squad. Like super-good, ultra-quick, know
sedinside out — you get the picture. Unfortunately, at the time we didn’t have an established way of spreading all that knowledge — both in regards to the domain, as well as the engineering craft. This was super sad since there is so much to learn from more senior developers — not only what is the best color scheme for IntelliJ or how to copy, paste, order food, and go to the gym with this simple terminal command — but their way of thinking, their way of approaching vague, complex tasks, breaking them down and tackling them a bit at a time.
To remedy this, we started having regular knowledge-sharing sessions about new technologies we were going to use often, as well as quick post-standup tutorials about cool tools and frameworks. Things like Go training sessions and tutorials on how to work with Prometheus and Grafana. For me, this is awesome not only because the skill set of the whole team grows collectively. It also shows people being actively engaged with their work and excited to share their findings with fellow peers.
Experiment around and see what sticks
Initially, we knew that we weren’t working in the best possible way but we couldn’t quite put our finger on why. Probably, there were many contributing factors, not least of which was that we were all remote and didn’t see each other for 8 hours a day. Growing an adequate relationship has proved rather tricky in the era of Zoom and UberEats (not sponsored, yet?).
In the beginning, we were having these “sprints” which didn’t have any particular goal or outcome to be achieved. They were just a collection of chunks of work to be completed at some point. What happened if they didn’t? They fell through to the next sprint. Ad infinitum.
A colleague suggested having a goal we wanted to achieve as a benchmark for how each sprint went. Not everyone thought it was a great idea, but we tried it anyway. We got some accountability from doing that and, moreover, could more easily prioritize our work — “Is this part of the goal?” If so, focus on it. If not, we’ll try to tackle it towards the end of the sprint. Some things worked better than others, but overall the willingness to try things out helped us find the right processes for our team.
Disagree and commit
Ahh, such a hard one. You know you’re right and others are just wrong, but for some reason, they can’t see it. How dare they!? However, it might be useful to learn how to disagree with a given proposal and then, if you are in the minority, carry on anyway and implement the proposed solution, as if you were the one presenting it. In my mind, there is a fine balance between this mindset and defending your thoughts when you have a strong opinion on a subject. However, let’s not forget that we work with other people and that without trust in the capabilities of your teammates delivering outstanding results will prove rather difficult. Give them the benefit of the doubt and more often than not, you will be pleasantly surprised with the result.
And there you have it — some lessons from our journey towards a cohesive team seen through the eyes of yours truly. What has been your experience with team dynamics and formation — I’d love to hear all about it below.