Reading the Data PM

You keep fixing the costume instead of the thing wearing it.

Reading the Data Reading the DataIntermediate

What Support Tickets Taught Me About Prioritization

A backlog of reported issues is not a fix list. The first job is to find out how few problems you actually have.

A support backlog of seventy reported issues looks like seventy decisions. It almost never is. On a SaaS product I worked on, that backlog turned out to be a much smaller number of underlying causes wearing seventy different costumes, and the most important call of the whole effort happened before a single line of fix code was written.

The question on the table was the obvious one: what do we fix first? The less obvious question, the one that actually mattered, was whether fixing tickets one at a time was even the right strategy. If every report was its own independent defect, the scope was seventy fixes and the only decision left was ordering. But if some fraction of those reports shared a root cause, the arithmetic changed completely. You could close a third of the queue with a handful of changes, or you could spend a week triaging symptoms and never touch the thing generating them.

So the first decision was not technical. It was a prioritization decision dressed as an engineering one: map before you fix. Spend the time to trace each report back to a cause, then prioritize the causes, not the complaints. That single choice is the reason the effort produced nine shipped fixes in a day that addressed the source of roughly half the reported volume, instead of three fixes that each soothed one loud customer. The same instinct shows up whenever you read a funnel: the metric you can see is rarely the lever you can pull, which is why AARRR is a diagnostic and not the metric.

The Map Is the Strategy

Most teams treat a support queue as a to-do list. It is closer to a survey. Each ticket is a user telling you where it hurts, but the location of the pain is rarely the location of the cause. One broken response format in a single backend handler can surface as a dozen unrelated-looking complaints: a feature that hangs, a dashboard that crashes, a process stuck partway through. To the user these are three different bugs. In the code they are one character. Seeing that a feature that hangs and a crashing dashboard are the same defect is the same act of reframing the question that the five frames of product sense are built to train.

This is where the prioritization instinct most PMs are trained on quietly fails. We are taught to rank by impact and effort, and to do it on the items in front of us. But the items in front of you are symptoms, and ranking symptoms gives you a confident, well-reasoned order that is still wrong. You will fix the loudest three reports, ship, and watch the queue refill with the same root cause expressed differently. The ranking was rigorous. The unit being ranked was the mistake.

The backlog is not the work. The backlog is the evidence. The work is whatever is generating it, and you cannot prioritize what you have not named.

The discipline, then, is to refuse to prioritize until you have done the mapping. For any queue past about ten reports, the first move is the map, not the fix list. The map tells you the real number of problems you have, which is almost always far smaller than the number of tickets, and it tells you which causes sit under the most pain. That ordering, causes by volume of downstream reports, is the actual prioritization, and it is invisible until you do the unglamorous tracing work first. This is the same elimination move that drives the Double Diamond as an elimination tool: you narrow to the real problem before you let yourself generate solutions.

The Failure That Hides in the Happy Path

The single most instructive pattern in that backlog had nothing to do with a new bug. It was a decision that had been made correctly once and then copied into a context where it was wrong.

The product cached responses from an external billing API. Caching a real, valid result aggressively is the right call: the data is accurate, the cost of an extra API call is real, and reducing load is a legitimate goal. That decision was made carefully, while building the path where everything works. The problem is what happened on the path where things fail. When the API returned nothing (a network blip, a momentary outage), the failure response inherited the exact same cache duration as a success. A transient error got cached for an hour. A user who had just paid for access was locked out for that hour, with no explanation, by a value that was wrong the moment it was stored.

Nobody decided that. That is the point. The success-path cache duration was reasoned through. The failure path felt like a subset of the same logic, so it inherited the same number without anyone asking the one question that separates the two: if this cached value is wrong, what is the user's experience, and for how long? For a successful result, a wrong value means slightly stale data for an hour. For a failure, a wrong value means a paying customer locked out for an hour. Those are not the same decision. They were shipped as if they were.

This is the part a manager might dispute, so let me say it plainly: I think failure states deserve their own explicit review, separate from the feature that contains them, and treating them as an afterthought of the happy path is a recurring product failure, not just an engineering oversight. The pushback I have heard is that this is over-engineering, that you cannot give every error branch a design review and still ship. Fair. But the cost is asymmetric. The happy path fails visibly and gets fixed fast. The error path fails rarely, invisibly, and converts every transient hiccup into a guaranteed, hours-long outage that surfaces weeks later as "the feature randomly stops working." Cheap to get right at design time. Expensive to discover through support volume.

When the Signal Is the Only Detector

A second cluster of those reports came from a class of failure you cannot catch with your own tests: a third-party dependency that changes its internal shape without calling it a breaking change. A plugin the product integrated with shipped a major version that quietly changed a field from a string to an object. Another removed a constant the integration relied on to detect whether it was even present. Neither threw an error a user would see. One produced a crash on a now-common platform combination; the other produced something worse, a feature that returned zero results, no error, no signal, just silence.

You will not find these in advance, because nothing in your codebase changed. The only reliable detector is support volume from a specific segment after a specific external release. When users of one particular integration start reporting empty results in a tight window, that pattern is the alarm. The investigation does not start in your own code. It starts at the seam where you touch someone else's.

The throughline is the same uncomfortable idea. Prioritization is not ordering the things in front of you. It is figuring out, before you are allowed to feel productive, what those things actually are. A backlog ranked by symptom looks like progress and is mostly motion. A backlog mapped to causes is smaller, less satisfying to look at, and the only version worth ranking. The cost of skipping the map is not a worse order. It is a queue that never empties, because you keep fixing the costume instead of the thing wearing it.

Related Articles

Train this · Reps

You inherit a support queue of seventy open tickets and one engineering day. Do you start fixing the highest-volume complaints, or do you spend that day mapping reports to causes before touching code?

Make the call yourself in Reps before you read how it played out.

Make the call
AW

Anmoll Wadhwa

Senior PM · writing The PM Code

Field notes on product judgment: essays, teardowns, and reps for PMs who would rather think than template. A sharper take most days on LinkedIn.

More like this. Once a week.

Tactical essays on the calls that actually matter. In your inbox before they are on the feed.

LEARN·BUILD·COLLABORATE