This past sprint, my team did what most teams fail to do. We were able to fully clear our sprint board for the first time as a new team. Most of my experiences working in agile teams have led me to believe that carryover was a natural part of the process.
While having minor amounts of carryover from sprint to sprint is somewhat acceptable, most teams that have consistently large amounts (say above 10% of overall velocity) are often an indicator of an issue with the team’s process.
Let’s dive deeper into some of the most common issues I’ve observed that cause teams to carry over stories at the end of their sprint.
The Team Is Not Communicating Enough
Raise your hand if stand up is the only time your team communicates with each other about the current status of everyone’s work. If you’re “waving your hand in the air like you just don’t care”, then this could be an area of improvement. To start gelling as a team to consistently meet sprint goals, you’ll need to communicate frequently. If your team is currently remote, I would argue that overcommunicating is better than under-communicating.
You don’t need another standup meeting to update folks on what is going on. A quick Slack message is more than enough to get the collaborative juices flowing.
Some of the things your team can send quick update messages for include:
When a ticket is starting to be worked on
A pull request was posted that needs review/another look
Some comments were left on a pull request
A ticket is ready for testing/approval
When a ticket is ready for release/has been deployed
If you read my post last week, you probably noticed that this type of frequent communication is a great way to encourage the team to work from "right to left".
By keeping the team updated, there is no confusion about the exact state of any unit of work, which will help to move tickets across swim lanes faster. It will also help to remove situations where the team may be duplicating effort around sprint processes (e.g. 3 people reviewing a pull request when only 2 approvals are necessary or two people testing the same ticket). This will free up the rest of the team to do other work to help complete the sprint.
Your Ticket Estimates Are Inaccurate
There are two difficult things in software development:
Inverting a binary tree on a whiteboard while an interviewer stares at you
Accurately estimating tickets.
For the latter, every team is different in this regard and may have its own definition for what a 1 pointer looks like vs. a 5 point ticket.
If your team consistently finds themselves with carryover at the end of the sprint, you may be underestimating your stories. Try coming together as a group and roughly define what a 1, 2, 3, and 5 point ticket should look like from past experiences as a team. This will give you a good frame of reference every time you estimate work.
I usually estimate with the following frame of reference in mind:
1 point: A simple change to a single thing needs to be made. This could be an easy style change, adding some new copy, removing a button, adding a column to a database table, etc. These kinds of changes should be straightforward with minimal complexity.
2 points: Usually good for small new features to be added with a little bit of complexity. Perhaps you are adding a new form, refactoring a reusable component on the front end, or maybe you’re creating a new database script to support adding a few new tables.
3 points: At this level of effort, you probably have a few moving parts related to the work being done. Maybe you have some front-end and back-end work that can’t easily be split up that will also need to be tested end to end. Perhaps you’re standing up a brand new API endpoint that has some complexity to it and will have a fancy new metrics dashboard created along with it.
5 points: If you’re estimating something as a 5, you’re likely committing to the story taking the majority of the sprint. There are a lot of moving parts related to the task at hand and will likely be pretty complex. You may even have some aspects that are unknown or high risk that will require some iteration through the life of the ticket. Integrating a new 3rd party system component into your system or refactoring some seriously old legacy code could be a solid example of this level of effort. This usually assumes the work can not easily be split up into smaller tasks.
Some other common things I’ve seen teams forget about when estimating tickets include:
Ensuring time for proper unit and service tests to be written
Time for manual testing
Work that is related to releasing the change
Unknown risk or dependencies
Learning curves/new technologies
Creating any relevant documentation based on the changes
Setting up logging/tracking/metrics/dashboards/alerts
You’re probably also wondering why I didn’t include anything larger than a 5 point effort. Read on to the next section to find out.
Your Tickets Are Too Large
Based on the previous section, when tickets are estimated as a 5 or higher, it should be an immediate red flag moment for the team to assess whether or not they can reasonably break the ticket down further.
Most tickets that are estimated as a 5 or higher often don’t get completed in a sprint without some heroics from the team. If there’s a front-end and back-end component to the ticket, can they be split into two tickets (maybe a 2 and a 3) and be done in parallel until they are ready to be hooked up?
A large estimate on a ticket could also indicate that the team thinks there are a bunch of unknowns (like a dependency on a ticket being worked on by another team) or potential risks (e.g. working with a new technology or a compatibility issue with a certain version of a library). It might be worth identifying those unknowns or trying to address some of those risks before bringing the ticket into the sprint. This could be with some further grooming of the ticket in the current sprint by an engineer or a dedicated investigation ticket to de-risk the proposed work.
Next time your team estimates the ticket as a 5, take some time to ask the team why they’ve estimated it as such. More than likely it’ll be because the ticket seems “like there’s a lot to do” or “it seems really complicated”. Dive deeper in these moments to probe out more specifics or your team may have a potential carry-over nightmare on its hands. Really make sure that the ticket is not actually two 5 point tickets in disguise.
Your Tickets Need More Details
If the acceptance criteria on a ticket are unclear or your team is left trying to decode technical details in a ticket like a jigsaw puzzle, that’s time wasted during the sprint. Make sure requirements are clear, links to relevant resources or code examples are present, and test cases/details are defined for clarity.
The amount of detail needed is a delicate balancing act. Try not to provide so many details on the ticket that it becomes hard to decipher or becomes a copy & paste task instead. The ticket ideally should not have written code in it so that the engineer can come up with that on their own. This helps engineers get the proper experience they need as well with crafting solutions. Spelling everything out for them in black & white won’t teach them anything.
Keep in mind that you’re grooming tickets, not trying to do the work outside of the sprint!
Good ticket formatting also goes a long way. Strive to break large lists of bullet points into relevant groupings. For instance, if you have a front-end, back-end, and database portion of your ticket, then separating the ticket into sections about each can make the scope of the work much clearer to follow.
Remember that anyone on the team should be able to pick up a ticket and begin working on it. If only some members can work on a ticket, it’s likely that you either have a skill/knowledge gap that needs to be filled, or your ticket needs more details!
The Team’s Sprint Goals and Velocities Are Not Realistic
Do you have a team of 5 engineers and commit to 50 points of velocity every sprint?
You’re likely overcommitting or pointing incorrectly. If everyone is completely heads-down for the entire day and has to deal with meetings, it’s unlikely that they’ll be able to accomplish everything in the sprint without pushing themselves to the limit and likely burning themselves out in the long run.
Give your team a little bit of room to breathe and think through their work and help each other succeed. You’ll likely see a difference in the way your team works right away.
The Team is Not Mitigating Similar Issues Via Retrospectives
A retrospective is a powerful tool in a team’s arsenal. It’s a time to celebrate the team’s wins, but also a time to reflect and improve on unexpected issues that came up during the sprint. Take the time to talk about any pain points in your team’s current sprint process and how it can be improved. You can also pick a few tickets that didn’t go as expected and break down what went wrong with each of them.
Once the issues are identified, look to see if any patterns emerge. Can you change something in your sprint process to address the issues that have been revealed? If so, work towards doing so in the next sprint or two and experiment to see if those changes help with completing your sprints.
Teams that fail to adjust and address consistently clear problems are doomed to have history repeat itself.
Your Team May Have Too Many Meetings
There’s no worse productivity killer for a team of engineers than a slew of meetings throughout the sprint. In my experience, most meetings tend to devolve into thirty-minute “status updates” in disguise. When you find your team running into that kind of scenario, suggest facilitating that information in a more asynchronous manner (like an email or Slack in a team channel).
Having meetings that are spread out throughout the day in awkward intervals can also be problematic for engineers to settle into a task with deep focus. If you take a look at your calendar and see random 15-30 minute gaps in between meetings, suggest that your team re-evaluates these meetings wherever possible to try to condense them into subsequent blocks of time instead. In the past, I’ve seen teams create success by pushing meetings to the first part of the day or toward the end of the day to create large blocks of working time.
What if your team has already tried finagling with meeting times and cutting out unnecessary meetings? Take to the extreme and suggest a “no meeting” day once or twice during the week. Work with your team to hash out what the rules are for such days (e.g. are slack messages still ok?) and then really try to commit to that consistently. You’ll be surprised how forgoing meetings you thought you may have needed doesn’t cause the team to succumb to disaster.
Bonus Miscellaneous Optimizations
There are a couple of other potential gotchas that a team can try to optimize that I wanted to share, but didn’t really fit well in any of the above sections.
Identifying Dependencies and Prioritizing That Work at the Beginning of a Sprint.
If you know that you’ll need another team to spin up a new database for you and that usually takes a few days, then by doing it early in the sprint, that resource should be ready for you when you need it. This is a much better approach than potentially waiting until the end of the sprint to do the same task and risking carryover that could have been avoided.
Avoiding Complex Back-and-Forth Conversations on Pull Requests
I’ve seen pull requests that take 10x longer to get approvals because the developer is relying on the slow back and forth feedback conversations. There’s nothing worse than waiting 4 hours for a reply to something that you then misinterpret and end up having to redo later on. In these situations, it’s often better to discuss pull request comments in a quick Zoom call to be able to move things forward quickly.
Refrain from Injecting Tickets
Sprint teams always have to face the dreaded dilemma of adding more tickets after a sprint starts. If something in production breaks or a new high-priority task emerges, it's usually a good enough reason to do so. Otherwise, try to avoid bringing in additional tickets into a sprint (though it's ok to have stretch goal tickets you can work on outside of the sprint if the board is cleared with time leftover).
If you are going to bring a ticket into the sprint, the best way to avoid carryover is to swap it with a lower priority ticket.
Not all of these sprint process changes will apply or work for your specific team. Pick and choose the ones that do and that should hopefully lead to your team completing more full sprints with minimal to no carryover.
Does your team commit any of these sprint faux pas? Have some other sprint optimizations I didn’t mention? Feel free to share them with me in the comments or tweet them at me.
Until next time, may your sprints run with optimal velocity and be carryover-free!