I’ve had the pleasure of working on a lot of different products, in different teams of different sizes, with different values and practices and a variety of processes over my career. I’ve always been a very product-focused engineer and am particularly attracted to products where I can see myself as the customer. This, for me, has really helped me emphasise and make a valuable contribution to what the product becomes.
My roles have given me the opportunity to build products both as a contributing member and also to lead teams and in several cases define the product strategy.
Slowly I’ve evolved a toolset that I found works for me and allows me to adapt and align a team with the needs of the business I’m working with and build great customer experiences. I’ve received positive feedback on these practices from others I work with and I wanted to share some examples of this process. This I hope is of some help to you but also allows me to capture something in writing as a resource that I’ve only ever had in an active implementation.
Nothing below is particularly novel, I’m not sure it would be particularly helpful if it were, but rather is a mix-and-match of various processes I’ve read about, experimented with first hand or have adopted from teams I’ve worked within. I don’t really subscribe to ridged project management patterns instead I prefer to take elements from Scrum, Kanban and break the rules where it feels right to do so.
Disclaimer #1: A lot of what I talk about here are things I’ve not mastered yet but they represent the intention and I’ve included a section towards the bottom that talks about the process of identifying and improving the process itself. It’s not perfect, but always evolving and improving.
Disclaimer #2: I’ve no formal engineering manager training, although I have found myself in that seat a few times. I’ve not had any formal training like being a scrum-master so the ideas below might use some technically incorrect terms, might be practices that have a name that I’m not aware of or might be outright wrong for many teams. This is just my experience of what has worked well for me, nothing else.
Who is this for?
Anybody who works building digital products. I come from an engineering background with a strong love for product. This led me to be a decision-maker in many cases beyond just the technical approach. From this, I’ve evolved a framework that works well for me through experimenting, recycling and evolving over time. What works for me might not work for you, your team, business or your product but I encourage you to read on anyway and steal the bits that do.
Goals
Let’s start with what we are trying to achieve when building our framework.
-
Everybody should know what they are doing today and next at all times
-
At minimum, a clear theme for the future should exist and be visible to everybody even if it is still being developed
-
Communication should happen in public by default
-
Nothing gets lost. Backlog items are addressed. This allows the team to focus on the important work of now with the security that there is time secured for tackling the backlog.
-
Engineers are able to focus on the task at hand without fire-fighting
-
Continuous reflection on the process where feedback leads to actionable changes
-
Meetings should be a valuable use of time for everyone involved
-
The team have a strong trust in each other and transparency is paramount to uphold this
The importance of feature flags
I’ve put this near the top for a very good reason. Feature flags are so much more than a tool for access management and releasing changes. Using feature flags allows problems to be broken down into small releasable chunks of work.
It’s my opinion that any given task should represent no more than a couple of days of work. When it does it should be broken down into smaller components under one shared story.
Feature flags are imperative in making this practical allowing you to break up your task into dozens or hundreds of simple and releasable units. Everything I describe in the practice I use depends on the team workload “flowing” to create accurate estimates and predictable public releases.
Structure
I could talk about how I achieve the above conceptually, instead, I feel it’s best demonstrated by example. Below you’ll find how I organise tasks into a few distinct categories.
👉 All paths lead to Rome “Now and Next”
No matter if work is a bug, a job, a project task all paths lead to “Now and Next” this is a single place that allows anybody to see what they are working on immediately and what they need to do next.
Now and Next is a Kanban-style board with the following columns:
- Next
- In Progress
- Blocked
- Ready for review
- Ready for testing
- Released
As you’ll read below tasks are well defined, kept small and are always releasable. If all is going smoothly tasks should freely move through “Now and Next” quickly in a matter of hours or sometimes a couple of days but never more than a week.
🐛 Bugs
Let’s start with the obvious. Bugs should be tracked separately from other engineering tasks and should be triaged by a member of the team who properly understands customer needs.
- Bugs are created by anyone and placed in the inbox.
- A software tester validates the bug report, ensures it has clear steps to reproduce and liaises with the reporting team member or customer if more information is needed.
- The bug is then triaged daily into Urgent, High, Medium, Low (or in some cases closed)
💼 Jobs
Instead of using the term backlog, I prefer to use the term jobs. In many teams I’ve worked there has always been a wishlist of tasks that are rarely addressed.
Jobs is a place to track these tasks but instead of going into the void of a backlog getting them done is scheduled in just like any other project work. The idea is that you and the team will often have ad-hoc requirements, dependency upgrades, refactoring or other unplanned work that comes up during other work.
Instead of allowing this stuff to distract you and your team from your planned work, we set it aside and factor in frequent windows to focus on these jobs.
Jobs should:
- Be specific, actionable and releasable
- Represent no more than two days of work
- Self-contained - don’t split a job in two, if it’s too big it should be a project.
📕 Projects
Projects represent bigger bits of work and consist of a proposal, specification, epics, stories and tasks.
🦸♀️ Epics
Epics represent a milestone of a release of a given project. Any new feature might have more than one epic, it’s not uncommon for us to version these into what we wish to achieve in the epic like “Performance 1.3”. Typically, I prefer to release throughout the progress of an epic but where that’s not possible there should always be a distinct release by the end of any given epic.
Proposal
Epics begin their life as a proposal, this should provide a short summary of:
- What the change is
- Evidence why it is needed
- Who the owner and stakeholders are
- How we plan to tackle it
- What the expected outcome is
These proposals should be lightweight to communicate an idea effectively but not preclude others from inputting into the planning and further refine it into a spec. Once complete this should be presented to the stakeholders and for feedback and a decision made if further work to turn it into a spec is appropriate.
Spec
If a proposal is selected to be scheduled a formal spec is created, this is far more detailed and outlines the mechanics of the problem be it a feature, refactor, redesign or something else.
At this point, if any design work is needed this is started. Rarely does anything communicate a feature better than an interactive prototype. Lowering the barrier to entry is a really important step to enable everybody to contribute to the discussion and ensure that everybody is aligned in understanding the mechanics. In my experience identifying and resolving issues early at this point is far more efficient than doing it later during implementation.
Stories and Tasks
With a clear spec and supporting designs, a tech lead should pair with the engineer who will be implementing the work along with a product and QA stakeholder to come up with a series of tasks often grouped by a story where appropriate.
An example story might be:
- As an integration partner, I want to be able to see debug information about Webhook requests so that I can diagnose issues efficiently
This could have several associated tasks:
- Create a new model
Webhook::Request
with an association to aWebhook::Event
- When a Webhook is triggered capture the response
status
andbody
in a Webhook::Request - If a webhook does not produce a response mark the
Webhook::Request
as unreachable
Not all tasks need stories, not everybody agrees with this but sometimes it feels forced to ask a story. Here are some examples of tasks that I would likely create without stories unless they had any sibling requirements:
- Bump version number to 1.0.0
- Enable project feature flag for beta testers
- Migrate copy to i18n files
Communication
Daily standup
Standup meetings are a daily chance to communicate what everybody is working on now and next. Often these fall into a trap of becoming a bit pointless when not run with proper structure.
The most important thing in a standup is to identify problems early on before they get out of control. Because of this, I like to promote these things specifically:
Blockers - Any issues that are preventing you from proceeding or are waiting on others to progress. The golden rule is that all blockers should be assigned to somebody within this meeting. It’s not enough to just raise the issue somebody should volunteer (or be volunteered) to help unblock things.
Help Wanted - This is something new that I’ve started to encourage to catch issues before they become blockers or somebody gets too deep into a domain they are unfamiliar with. Help wanted is used as a request to get some knowledge transfer. Maybe you’re about to touch an area of the code for the first time and just need somebody who is already familiar with it to give you the tour before you do so.
Furthermore, there should also be your more typical status updates but in my opinion, these aren’t nearly as important as blockers and help wanted are.
Walk the board
Larger teams are often supporting one another and need clear context on what each other are working on now and next to help them with upcoming questions, dependencies, blockers, possible conflicts and to help with the peer review process.
To enable this it’s helpful to do a weekly walkthrough of the sprint board. Unlike daily standup this involves doing a deep dive into each card on the board by status. In doing so the ticket owner explains the status along with what each ticket is and the context behind it. This is a great way to celebrate the work that has been shipped, to identify any blockers and to ensure that everybody is aligned on the work that is happening.
Tech Retros
After each sprint the team run a retro. This is a safe environment for everybody to look back on the last two weeks and discuss what went well, what didn’t go well and what we can do to improve.
I’ve always tried to instil one point more than any within the teams I’ve led:
We’re not always going to get everything right and that’s OK. It’s far more important that we are taking the time to reflect on, improve our practices and avoid making the same mistakes. We’ll be better tomorrow than we are today.
For this to be a reality a blameless culture is absolutely essential. If somebody broke production in the sprint it’s very rarely actually their fault. It’s the fault of the process that allowed it to happen and we all take a collective responsibility for that.
Wiggle Week
This is one process I adopted from a team I contracted with and I’ve found to be essential at maintaining team morale whilst keeping engineers focused on the work they have been assigned.
Throughout the development process important upgrades, refactors or quality-of-life improvements are often identified. In most teams I’ve worked with these are either often picked up ad-hoc which disrupts the sprint plan or are lost to a backlog that is never addressed.
Wiggle week is a week that is scheduled every 6 weeks where the team is given the freedom to work on these jobs. This is a great way to keep the team happy and motivated whilst ensuring that the backlog is well maintained. Unlike sprints the tickets are self-selected by the team members and is an opportunity to try something outside of your usual skillset or to address something that has been bugging you for a while.
Knowledge Sharing
Within any team knowledge sharing is super important to make other people feel enabled but is also key to improving the quality of feedback in discussions and peer reviews.
Typically I do knowledge sharing in a few different ways:
-
Help wanted - I mentioned this above but as part of daily standup the team are encouraged to raise anything they are about to work on that others might have better domain knowledge of. This is a great way to get a quick overview of a problem before you start working on it.
-
Engineering Forum - A fortnightly meeting where engineers can bring any topic to the table for feedback. We often also use these as an opportunity to share knowledge on a topic that might be of interest to the team. This is a great way to get a deep dive into a topic that you might not have had the chance to work on yet.
-
Knowledge Silo - It’s not uncommon for a member to the team to be the only person who knows how a particular part of the system works. This is a dangerous place to be in and can create risks for the business and make the team feel as though they are unable to contribute to parts of the code or certain conversations. To avoid this I encourage the team to document thoroughly and present how a system works to the rest of the team before this becomes a problem.
Always be improving
These processes are far from perfect, full of compromises and are always evolving. They also don’t work for all teams that I’ve worked in and I’ve often had to suspend my ideals when working in this way doesn’t allow us to meet a demand of the business. However, I do think the values you’ll find within these processes can be upheld in many different forms and adapted to help you solve many different problems.
My final takeaway advice is that people come first, always. If you’re genuine about creating a great environment for your team to do their best work in and you’re open to feedback and change then even when you make mistakes or don’t get things quite right they’ll be there right alongside you.