Aspiring to the perfect ticket
The keys to writing tickets for building software features
The best product feature tickets do not slavishly follow a framework or checklist that makes them great. While they frequently contain common elements, what makes them powerful is how well they are understood by the engineers reading them. Determining what information to include and, perhaps more importantly, what not to include, is messy and imprecise. It’s a judgment call based on the product manager’s assessment of how much each developer needs to see included to execute successfully. Too much detail stifles creativity and innovation, and distracts attention away from value and into the process itself. Too little information leaves engineers spinning their wheels guessing at intent and never knowing when they are done.
Deriving a great methodology for writing a ticket, then, is not about living up to a universal rubric, but rather crafting different levels of fidelity to speak individually to whoever is consuming the content. A great ticket is for the engineer writing the code, and it drives clarity on what needs to be done and what doesn’t. It’s about communicating precisely at the exact level that builds an appropriate bridge in the developer’s mind, which then frees them to do excellent work and their own creative thinking.
Let’s take this to extremes on a mundane example to make the point. Both of these tickets are perfect, depending on who is reading them.
Slim Ticket
Suppose we’ve just had a live whiteboard session in which we have jointly discussed all of these particulars, and the work is commencing right away so there is little chance of forgetting. The developer is experienced, organized, and detail-oriented and took their own notes. Then the ticket above is just fine.
At the other extreme, perhaps the developer is a brand-new engineer straight out of college, the work is being done remotely, and we have not had a chance to discuss expectations for the feature. In this case, the second option below, which is a more thorough treatment, might be right. The truth is that it’s unlikely that most product managers will choose the right level of fidelity for ticket writing out of the gate until rapport is built and everyone has had a chance to ship some features together.
Heavy Ticket
Most of the time, reality lives somewhere between the two extremes presented above. So let’s break down some best practices and why they exist.
We write to avoid confusion
The first question we have to answer is: why do we write tickets at all? Really, no one likes them. Why not just discuss everything live and avoid them altogether? After all, it’s a process burden for the product manager to maintain them and for the developer to update them.
Some very early-stage teams with high trust and great communication can forgo them, but for most teams, the ticket serves as an atomic unit of agreement about what’s to be done, and as that list grows, taking the time to craft good ones keeps everyone on the same sheet of music, makes it easy to re-prioritize and make tradeoffs, assign and track work, capture discussions, and much more.
If we are going to write hundreds or thousands of them for even halfway mature products, then we’d better have some opinions on how to do this that are backed by experience. While some companies can avoid tickets, I don’t recommend it, because that’s how you end up with a great flow but no password reset button, or dramatically overengineering something for an extra $20K in net burn.
What tickets don’t solve
Perhaps more important than the jobs the ticket serves are those they do not. Feature tickets are not designed:
To be a comprehensive recounting of every possible detail about how something should work that replaces live person-to-person dialogue
To replace thoughtful functional and/or technical specifications for a complex feature
To be a list of technical steps required to build the feature (though these can certainly be subtasks)
To be a mechanism for providing executive visibility to “management” about what work is being done
This last point is especially salient. The most common request I see from CEOs or GMs to their CPOs or PMs is for more transparency about what is getting built right now. I’m afraid to report that every single attempt I’ve seen to economize on that request by using the ticketing system for that communication is a failure. I’m sure someone, somewhere has been able to pull this off, but generally, five minutes spent writing a Slack message or an email at the beginning of a sprint in the words the CEO expects is a lot more efficient and well-received.
The alternative, when you consider it from the CEO’s perspective, is to be told to “follow this link, open a new system, and read our jargon-filled descriptions of what’s going on, and hopefully you’ll understand it all without the context we have … oh, and by the way, we work for you, but we expect you to go through this process like it’s a goddamn mystery adventure to find out how we’re spending your money.” Boo! CEOs deserve better, and CPOs owe them more.
Building blocks for great ticket-writing
So what should go into a great feature ticket (or the conversation, if not the ticket itself)? Ultimately, each ticket represents some unit of software development work that helps us achieve our goals. That unit exists only in your head when you start. To get it out clearly, we need to consider doing all of the following:
1. Describe the problem and the current state
What issue are we solving with the code? This doesn’t have to wax poetic like the functional spec. The goal is to remind everyone of why this ticket exists, so that it’s easy to remember when reviewing progress or moving priorities around, and of course to inspire the engineer fixing the problem to come up with even better solutions. These can take the form of a user story or a job story or can simply be a statement:
“When on a business trip, travelers want to be reminded of who lives in the city they just landed in, so they can keep in touch.” (Job Story)
“As an administrator, I want a way to impersonate a user’s account, so I can see what they see and more rapidly debug problems.” (User Story)
“Searches are averaging 20 seconds to return for users, and it’s causing attrition. We need to speed these up.” (Problem Statement)
2. Describe the solution
Many novice product managers get caught up in the problem statement and neglect to acknowledge that the same problem statement or job story could have dozens of different solutions, so putting a little extra energy into this aspect is worth the time and will avoid costly miscommunications and extensive re-work.
“We’re going to take the user’s location from their mobile device, set a radius of 5 miles, and then search their native contacts (iOS only) for any addresses. We’ll also need to geocode each address so we can compare latitudes and longitudes against other latitudes and longitudes. Whichever contacts are within the radius will get sent as in-app notifications to the user showing the name and distance of the contact.”
“Customer support has been complaining that users are reporting errors that are hard to describe when it comes to their search results. When we impersonate users, we need to see the exact same search-results view that they see, so we can identify what looks wrong.”
“To speed up searches, we need to create a secondary index on keywords, test, and tune it. We may also need to rebalance our search indices to reduce latency.”
3. Describe an externally visible and functional unit of value that the solution will provide
That’s a mouthful of a topic header, but each word counts. This is frequently called “acceptance” or “acceptance criteria,” but I don’t love those terms because people get confused about whose perspective we mean, and it also implies a master/servant relationship among peers. After all, a great engineer can build a solution that is superior to what was discussed, and that’s definitely not a “failure of acceptance.” Our goal here, regardless of the jargon, is to describe the result in a way where multiple observers with less context than we have could see the enhancement and all agree that it solved the problem described.
This is also a good place to specify the range of effectiveness of the solution and its observable characteristics. This applies to end-user features and backend work alike. Especially in the backend world, it’s common for engineers to assume there is no visible way to show the resulting work, and this belief is almost 100% correlated with incomplete delivery of results. Take the time to brainstorm this together among product and engineering, and it will pay off immensely.
E-commerce example for shopping cart:
“Add Item: When a user clicks ‘Add to Cart,’ the selected item should appear in the cart with the correct quantity and price.
Remove Item: Users should be able to remove items from the cart.
Update Quantity: Users should be able to update the quantity of an item in the cart.
Calculate Total Price: The cart should automatically update the total price based on items and quantities.”
Ridesharing app driver matching:
“Location Accuracy: The app should accurately determine the user’s current location within a 10-meter radius.
ETA Calculation: The app should provide an estimated time of arrival (ETA) for the driver that is accurate within a 5-minute window.
Driver Availability: The app should only show drivers who are available and within a 5-mile radius of the user.”
Algorithmic search result ranking:
“50% or more of the first page of search results receive Normalized Discounted Cumulative Gain (NDCG) scores above 0.60.”
Backend service to reset a user’s credits:
“A POST request sent to /admin/credits/reset with the json payload { "username": "john_doe", "email": "john.doe@example.com", "credits": 0 } sets the user’s credit balance to 0.”
4. For larger efforts, explain how the pieces relate to the whole
It’s fairly common that the skills required to focus on the trees make the forest hard to see in the moment, and I see a lot of wasted effort going into trying to build the forest, when the ticket requires only a couple of trees. Give your developers that extra bit of context so they know where the bar is and how this feature fits into the larger product vision. The easiest way to accomplish this is with great functional specs that break the work into phases, and then thoughtful decomposition of the work going into the current sprint or release, where each of the related aspects get their own ticket.
For example, a common feature is the ability to share an asset with teammates or the public. This can be a giant epic or even initiative in its own right, but if the tickets are grouped thoughtfully, then it’s easy to see the progression, and developers can focus on one challenge at a time. It also makes clear what aspects aren’t being requested within each ticket, when they are presented in proximity to the others.
Ticket 1 Title: “Share asset with named users in my organization”
Ticket 2 Title: “Share asset with unnamed users in my organization”
Ticket 3 Title: “Share asset with a public link for users outside of my organization”
Ticket 4 Title: “Shared assets respect security and visibility requirements”
Ticket 5 Title: “Ability to select custom preview of shared asset when sharing”
Ticket 6 Title: “Add comments to shared asset when sharing”
Ticket 7 Title: “Email notification of recipient when asset is shared”
5. Provide links to resources that will answer common questions
This one is easy, a no-brainer, yet it’s skipped all the time. Put all the resources into the ticket so it’s easy for the developer to find. This could include any of the following:
A link to a functional spec
A link to a technical spec
A link to a relevant architecture
A link to a design or clickable prototype
A link to research
A link to a customer support request
Screenshots or videos of existing behavior or future states
6. Make it atomic
Finally, and this takes a career’s worth of finesse to perfect (I’m still working on it), try your best to make the work atomic. This means that it (a) stands on its own, (b) clearly doesn’t overlap with other work, and (c) bites off the smallest meaningful slice. It’s far more satisfying for everyone if tickets can be done in a few days (and certainly less than a sprint), rather than remaining open for weeks at a time, and practically this makes it easier to shuffle work when needed, versus everything getting stuck behind some monolithic task.
BAD: “Improve quality of LLM response.” GOOD: “Retrain LLM including this new corpus of documents.”
BAD: “Reduce steps in checkout flow.” GOOD: “Remove the cart preview step from the checkout flow, add to summary page instead.”
BAD: “Improve search relevance.” GOOD: “Improve relevance ranking by taking recency of content into account.”
Putting it all together
In closing, allow me to first caveat that only a small percentage of my tickets live up to these standards all of the time. You don’t have to execute flawlessly here to be great. This post is aspirational more than a must-do-every-item-every-time checklist. Conversations replace much of the need to write a lot of the nuance down, but also be cognizant of the fact that we’re all juggling many things, so if the conversation covers a lot of topics, the right thing to do is to help write it down so it’s easy to reference when your engineering counterpart is in the weeds late at night trying to remember what the heck you both discussed.
And remember, it’s better to start loose with new, innovative products because it will give experienced engineers room to express their creativity, and it’s easy to add more detail later. Once you go down the path of over-specifying, teammates will expect it, and a few months later you’ll notice that your engineering counterparts are less invested and less creative as a result.
Finally, it’s worth noting that many of these rules don’t apply, at all, one level down from the tickets the product manager writes. If a subtask for “Reduce search latency to 1 second or less” is “Deploy Elasticsearch,” that is entirely acceptable and doesn’t need to be micromanaged or overspecified. My personal preference is for product to write the external-facing tickets and then leave the decomposition of engineering tasks to the engineers. Whether you choose to create clarity through tickets or conversations or both, try making your next exchanges focused on these topics and you’ll see velocity, satisfaction among teammates, and product quality rise dramatically.
Hi! If you enjoyed these insights, please subscribe, and if you are interested in tailored support for your venture, please visit our website at First Principles, where we focus on product to help the world’s most ambitious founders make a difference.