We're looking for brilliant Software Developers to join our team!
In the past two years, the Smartly.io product development team has grown by 6x, extracted a bunch of microservices from a monolithic code base, scaled infrastructure beyond 400 servers, and contributed to growing monthly revenues by 10x. Meanwhile, we’ve been able to maintain agile and self-organized ways of working in our 50-person engineering team.
How did we do it? Looking back, I can make out the stages of developing from a single team into an Engineering organization and identify some key elements that helped us get it all to come together nicely. We're never done, though, and as we keep growing, we have to keep on improving our ways of working.
Defining teams with clear ownership areas
Back in 2015, we grew beyond the sensible size for a single engineering team. Initially we were able to stretch the size of the team by spinning larger development projects off into “mini teams” that sat together and worked together. It worked well for new development projects, but bugs and feature improvement requests were piling up.
Clear responsibilities between teams help a lot in decentralizing decision making, which in turn allows us to move faster. So, we decided to assign a full stack development team to each of the main value-adding components of our product: the intuitive workflow, the feed-based advertising features, and the automation and optimization functionality.
Since then, we’ve spun off three more teams—one focusing on reporting features and our data processing pipeline, another building internal tools, and most recently one that works on automatically generating creatives, such as images and videos.
Each team owns their components, which means they prioritize between bug fixes, feature requests and architectural work. Since they also own the higher-level goal, they’re encouraged to come up with any product ideas of their own. Our customers are happy to work with our developers, so it’s very easy for the teams to validate ideas and iterate on the implementation. Ideally each team would have skillsets from design to DevOps, so they can build anything end-to-end without depending on other teams.
Now that we’ve been able to extract big chunks of the codebase to microservices, their ownership naturally maps to the teams as well. Anyone is still free to contribute to any area of the codebase, now it’s easy to find someone to review your changes.
Lean software development with a quick feedback loop
Everyone follows a set of basic principles that we’ve outlined in Engineering Working Agreements. Among them we highlight the need to update the working agreements when needed, our focus on customers, and all the different ways we can make our colleagues’ lives better. Having agreed on the basics, we can move faster, since we know what to expect from others.
Our engineering teams have the freedom to organize their day-to-day work as they see fit. Each team uses Kanban with a physical whiteboard and JIRA to track work in progress and visualize their bottlenecks on a daily basis.
When the team completes a user story, they pick the next one from the backlog. The product managers and designers validate each feature idea with our customers to help the engineers to prioritize their backlog and make sure they build the right features for the right customers at the right time. We develop our product in close cooperation with our most advanced customers, which means that all major features are built together with the end users.
When the engineering team starts working on a new feature, product managers put them in direct contact with customers who would benefit from the functionality. Sometimes engineers join customer calls, sometimes they travel to meet them face-to-face. We also invite our most advanced customers to visit our Helsinki office, and during these visits they workshop with our engineering teams to find out what features we should build next, and how we should improve our workflow to take our product to the next level.
All the code we write gets reviewed by at least one person (usually more) with domain and component-specific expertise to help identify any possible issues early-on. All new team members can start reviewing their teammates’ code already in their first week at Smartly.io.
Automatic tests cover each component, and we run some end-to-end tests to make sure things play together nicely. Good test coverage allows us to deploy to production through our chat bot some 10–20 times per day, which is great for a speedy feedback loop. We can safely deploy even half-done features to production, as we use feature gates to enable them to only those customers we’re developing and testing the features with.
Steering clear from siloing
Having self-organizing teams holds a high bar for cross-team transparency to collaborate efficiently and stay on the right course. At Smartly.io, all information is open, and as we’ve grown, we’ve made an extra effort to make it easy for everyone to access, digest, and benefit from. Transparency is an area we have to enforce, since people have a tendency of keeping their meeting notes to themselves, and often take discussions to private chats.
We use Flowdock as the internal company communications channel. By default, all flows are open for everyone to join, read and comment. When you have a meeting, you’re required to post the notes in Flowdock and tag them with #notes. This way, anyone can follow the notes from various planning meetings and retrospectives, give feedback, and ask questions.
We demo our progress to the whole company every Friday afternoon. It’s a great way to get instant feedback from the wider team and celebrate successful projects (while enjoying some microbrews). We also discuss cross-team issues in monthly Engineering all hands meetings, and teach each other at Engineerios.
While we’ve put processes in place to encourage collaboration, we admit that nothing replaces actual human relationships. Since people don’t just automatically get to know each other in a company that’s grown past 150 people, we’ve come up with different ways to support face-to-face contact with people you don’t work with on a daily basis. For example, we have weekly Lottery Lunches, where people across teams, functions and even offices have lunch with randomized pairs.
Keep on improving
When a company is growing this fast, you’re never done. Many of our ways of working will become obsolete in 6 months, but that’s just part of the thrill. Fast change opens up new opportunities all the time, and everyone’s open to suggested improvements.
Right now our most important development areas are improving the measurement of feature adoption, eliminating the remaining Single Points of Failure in the infrastructure, and completing some of the bigger rewrite projects.