I was the 3rd engineer when I started at thredUP. Scrum consisted of two co-founders and two engineers. We all did full-stack development, design work, CS tickets, bugs, QA, and maintained the servers. We weren't qualified to do most of that, but our resources were so limited that we were forced to wear a lot of hats and do the best with what we had. We were worked hard, moved fast, had fun, learned an incredible amount, and got to know each other really well.
During this time, we began to put little processes in place to help us work more efficiently. We chose our git branching strategy, our staging server process, and we started to choose services (GitHub, Campfire, Dropbox, etc.) to help us communicate and collaborate better. Our gatherings at lunch to watch an engineer teach a technical topic turned into routine 'Technical Lunch & Learns'. Whether we were aware of it or not, we were creating our engineering team culture.
'Engineering team culture' isn't defined in Merriam-Webster and when you think about it, it's pretty hard to define off the top of your head. Here's my best stab at it:
Engineering team culture is the standard to which a team holds themselves accountable for the way they work, interact with one another, and perform.
We established our engineering team culture and it became part of our team's DNA. We cherished and protected our culture, but change is inevitable as a team grows. We went from 1 team (3 engineers, 1 designer) to 3 different engineering teams (web, ops, mobile) and 1 design team. As much as we liked how we worked when we were small, we had to evolve as the team grew larger. Processes that worked for 4 engineers developing across 1 application fell apart when we grew to 15 engineers working across multiple applications. Little inside jokes we would say all the time made others who weren't in on the joke feel left out. There seemed to be a separate culture for those who were there from the beginning and those that were new to the team. If we wanted to live up to what we believed our team culture was, we needed to make changes to our culture to make it scale.
The Way We Work
When we realized that we needed to start making some process changes, we were faced with a decision: try to re-factor our current, proven development processes to accommodate for the bigger team or try to inject the team with new processes. We eventually settled on a mixture of both. We constantly experiment with ways to improve our current processes while keeping an open mind to new processes. Finding that balance involved a lot of trial and error, but in the end we developed an always evolving mental framework to approach team culture-related issues.
We make process changes as a team through an open forum that is conducive to discussions where engineers can speak freely. Since we are an agile company, we use our sprint retrospective every two weeks to reflect on our recent projects, our processes, and hold an open discussion to surface issues engineers are encountering.
When new people are added to the team, it's only a matter of time before someone utters the following words "at my last company we used to...". From my experience, it's essential to stay humble and open-minded during this time. When someone makes a new suggestion, the natural reaction is to be defensive. "The current process has worked great for the past couple of years so there's no reason to throw it out window now".....is the wrong way to approach this. First, people will stop participating in these types of discussions if you shoot down new suggestions. Second (and more importantly), your culture should evolve over time and people on the team should be a part of that evolution. Your culture has failed if people who care about the team are no longer being heard.
To keep an open mind, we do a lot of experimenting. If someone has an idea they would like to try out (ex: extreme pair programming, point planning poker, etc.), we try it for two weeks and then we reflect on it at the next retrospective. If it worked well, we integrate it into our culture. If it didn't work, we identify the issue we were trying to solve with the process change and then we discuss alternate solutions. Much to the credit of our team, there hasn't been a process obstacle we weren't able to resolve through this methodology.
As we grew, the small, close-knit engineering team that always went out for drinks together that we preached about during the interview process wasn't really there anymore. We wanted it to be true, but it wasn't. Similar to the need of having processes that scale, the way in which we interacted with one another needed to scale as well if we wanted to keep our team close.
Happy hours at small bars, going out to lunch together, and developing a rapport with one another (inside jokes, nicknames, etc.) became harder and harder as the team grew. You can't fit 15 engineers in a booth at a bar. Even if you could, it's hard to find a bar 15 people all like to go to. Every hire isn't going to be single in their 20s. People are going to have different preferences and new personalities that will change the team's dynamic. As a result, it's possible that some people are going to be 'left out' when the team grows and some companies are okay with that; we are not.
The relationships we forge with our fellow engineers are extremely important to us. We are a team that is building something special and we want to be a real team through and through. A real team cares about each other, they help each other out, they unselfishly share their knowledge, and they ship great features through collaboration. Ideally, they enjoy doing it as well. We want people to look forward to coming into work. If someone doesn't enjoy coming into work, then part of our culture is failing or we didn't adhere to the standard we hold engineers to during the hiring process.
For us, the changes we made to help us scale our team interaction ended up being simple. Instead of going out to lunch together in small groups, the company caters lunch to the office and we eat together. This allows us to eat lunch next to someone different every time.
While we still go out to the bars together, we also brought the bar to us to encourage more impromptu happy hours. We have a dedicated 'beer fridge' and 'liquor freezer' that is stocked at all times (just watch out for the unsuspecting Smirnoff Ice). We also do things like bring in card dealers and bartenders for 'casino night'. My personal favorite get together is the weekly 'board game night' that a large number of us attend. No one is required to attend the happy hours or the board game nights - we show up because of how much fun we have. This is something I hope we never lose.
One team interaction that did scale from beginning was Campfire, our engineering chat room. We have every commit message piped into the chat room via GitHub hooks and our CI server runs after push so everyone is always aware of the status of the test suite. When we're not talking about our current projects or answering each other's coding questions, we're having fun:
Campfire allows us to work asynchronously. It boosts collaboration and cross-team interaction. Don't underestimate the power of the chat room.
Efficient processes and solid team interaction help streamline our work, but our view in regards to performance is the final piece of our culture's foundation.
At the end of the day, we're paid to perform and if we're not shipping code, then we're under-performing. When we were a small company, we moved almost uncomfortably fast. We released early and often, then we collected data, iterated, and moved forward. It becomes hard to keep that pace with a bigger team though, but its our collective responsibility to figure out how to move fast while keeping the website stable and the code base in good shape. Until we're the incredibly successful and profitable company we want to be, we need to keep pushing ourselves to perform at a high level. If we fail at this, we will fail as a company.
Moving fast has it's consequences though. When you move fast, you will accrue technical debt. A lot of technical debt will slow the team down. Website performance will suffer from feature creep, the test suite will slow down, and your dependencies & technical stack complexity will rise. These all impact the team's performance.
The first step in keeping technical debt at bay is admitting you have it. We acknowledge we have some shitty code in our code base. Every retrospective, we surface and discuss potential technical debt. Then we make technical debt stories and put two (and sometimes more) of these stories in our upcoming sprint. It's essential to get your product team on-board with allocating developer bandwidth each week to pay down this debt. The less technical debt we have, the faster we'll be able to chew through the backlog, which is why we're always paying down our technical debt. Also, the better, cleaner and faster your codebase is, the more you'll want to work in it. Nothing makes an engineer's life more miserable than trying to work with an app that is full of fragile, spaghetti code drenched in technical debt. Just like a credit card, you better pay the debt down before the debt becomes insurmountable.
A lot of thought has gone into our engineering team's culture and we sincerely care about staying true to it. If you like what we're doing and want to be a part of it, don't hesitate in reaching out as we have plenty of openings. Come help us improve our culture and be a part of something special.