Every feature is a permanent tax: how we decide what not to build
Every product team talks about its roadmap. The decisions that shaped our product most are the other ones: the features we looked at seriously and decided not to build. That list is shorter than the roadmap, and it explains the product better.
Requests reach us from every kind of user. We logged 3,603 of them in the last 20 months, around 540 a quarter, and the split is not what most people guess: 74% come from the people who run the service, 17% from passengers, 9% from drivers. Almost every one is reasonable in isolation. The problem is that one user's convenience might be another's discomfort.
A bus is a shared vehicle. Our active routes carry a median of 5 passenger stops, and the planned gap between two consecutive stops is a median of 4.5 minutes. Anything we add for one passenger is paid for in minutes by everyone already on board.
Every yes also takes permanent screen real estate. On a weekday our passengers open the app 2.2 times and spend a median of 68 seconds in it per session, two and a half minutes a day. Nobody explores the app and nobody reads a release note, so every extra element on that screen is a tax on a two minute habit.
Then there is maintenance. A feature is written once and paid for in every release after that: regression tests, support articles, an ops team to train, a driver flow that has to keep working on a phone mounted in a moving vehicle.
A 'no' costs nothing once. A 'yes' is a bill we keep paying. So the reason for a no matters as much as the no itself, and we say it out loud instead of parking a request on a roadmap forever.

The five questions a request has to pass
We do not score requests on a matrix. We ask five questions in order, and the first no ends it.
Who pays the cost? Every passenger facing feature puts a cost somewhere: on the driver, on the other passengers, or on ops. When the cost lands outside the person asking, the request needs a stronger case than "several people asked for it".
Is this the request or the symptom? People ask in the language of solutions. A request for a chat button is usually a request to know where the bus is right now.
Does it survive a full route? A feature that works for one passenger has to still work on a route with 10 stops, where our routes sit at the ninetieth percentile, and on our longest route, which has 23.
Does it earn permanent space? If it goes on the main screen, something else gets less attention. We ask what we would remove in exchange, and if the answer is nothing, that is usually a no.
What breaks if we ship it and we are wrong? Some mistakes are a cheap revert. Others change what passengers expect from the service permanently, and you do not get those back.

Three requests that did not make it
These three failed at three different questions, and they arrived from three different places: a passenger, the people who pay us, and our own engineering team.
In app chat with the driver. Passengers asked to message the driver when they were running late. We went through 615 passenger app tickets from the last 20 months: 4.7% are about not seeing where the bus is, 1.3% about reaching the driver at all. The request was about position, not conversation, and we were not going to ask a driver to read messages while driving. So we put the work into live tracking, and kept the one contact channel that works at a red light: a masked phone call, one tap, no typing.
Letting the admin edit the route. The people who pay for the service ask for this more than anything else, and self serve looks like the obvious answer. Then you look at what one edit does. A stop moved by a well meaning admin at 22:00 changes the morning of everyone else on that bus, and the admin cannot see the other stops, the vehicle, or the driver's hours. So we built the request flow instead: the admin says what they need, and our operations team and the routing engine decide how the route absorbs it. Route changes stay behind ops. That is not a missing feature, it is the reason we run the operation ourselves.
Re-optimising the route up to departure. This one came from us, not from a customer. The routing engine could keep improving a route until the bus leaves, moving a pickup by a few minutes as traffic and bookings change, and it would save real vehicle time. We said no to ourselves. A commute is not a feature, it is a promise: people set an alarm against that pickup time the night before. Moving it from 07:15 to 07:09 overnight is a gain for us and a broken promise for them. Once a route is published the plan is frozen, and what we learn after that goes into the next day's plan. During the day what moves is the estimate, never the plan.
What the no list bought us
The point is not discipline for its own sake, it is where the work goes instead. Three quarters of the requests we log come from the people who run the service rather than from passengers, and that is where most of our engineering went: routing, scheduling, and the tools our operations team lives in. Saying no in the passenger app is what paid for saying yes there.
It also kept the product legible. We run more than 100,000 trips a month across 6,700 routes, and the passenger app that serves all of them is two tabs and one button. Nobody needs onboarding for a service they use twice a day, and that is a design outcome, not luck.
The last surprise was how customers reacted. Walk an admin through a request we turned down and why, and the response is usually relief rather than disappointment. Nobody wants their bus service to get slower because another company asked for something.
It changed our support conversations too. A no with a reason attached lands better than "it is on the roadmap" every time, and passengers rarely argue with a trade off they can see.
None of it is permanent. What we hold on to is not the verdict but the reason, and a reason can expire. When one does, the request comes back to the top of the pile instead of starting over from scratch.
If you want to see what this looks like in the product, take a look at Control Tower or Kopilot. If you are replacing a provider or moving employee transportation in house, ask us for a demo and we will walk you through the no list too.