The hard part of a feature request is almost never the decision. Most teams know inside a minute whether they are going to build the thing. The hard part is the two minutes after that, when a real person who took the trouble to write it up is waiting to hear back and the honest answer is no. So the request sits in the queue instead, unanswered, and a month goes by.
Here is how to say no to feature requests without losing the person who asked: decide quickly, answer in public where the requester and everyone who voted can read it, give the actual reason, and be explicit about which kind of no it is. The decline is rarely what costs you the relationship. The silence is.
That makes this a product problem as much as a communication one. A good no needs somewhere to live, a status that means it, and a notification that carries it to everyone who cared.

Why an unanswered feature request costs more than a declined one
Ignoring a request is the most common way to say no, and it is the only version that reliably does damage. It teaches the person that writing to you is a waste of an afternoon, and it teaches everyone watching the same thing.
The best evidence I know of for how this actually plays out is an Ask HN thread from August 2022 titled “How to say no to a GitHub issue feature request?”, which collected 261 points and 232 comments. It is an open source maintainer asking, not a SaaS team, but the pressure is recognisable: someone wants a feature, will not pay for it, and behaves as though the answer is negotiable.
One commenter, politelemon, lays out the silent option plainly: “You are perfectly entitled to completely ignore the request. Don’t comment any more, just stay silent for ages and ages. The issue can languish for years.” It is an accurate description of what most backlogs already do, which is the uncomfortable part.
The thread then splits over what to say instead, and the split is the useful bit. nicbou argues that “‘No’ is a full sentence. You do not owe anyone an explanation beyond ‘I do not feel like working on this feature’.” sanjayio pushes back: “This can come off as rude if you’re trying to make a collaborative project. I’d link to a roadmap or be honest and say this doesn’t pique your interest.” Both are right about different situations. A maintainer with no commercial relationship can end the conversation. A SaaS team with a renewal date cannot, and the roadmap link is the cheapest way to make a no feel like a position rather than a brush-off.
How to say no to feature requests in public
A decline should be visible to everyone, not sent as a one-to-one email, because most of the value of the answer goes to people who never wrote in. For every customer who files a request, several more had the same thought and searched for it first. A public decision answers all of them at once and stops the same request arriving eight more times.
Python’s PEP process has been doing this for decades. PEP 1 says a proposal “can also be ‘Rejected’. Perhaps after all is said and done it was not a good idea. It is still important to have a record of this fact.” A rejected PEP is not deleted. It keeps its number, its text and its rationale, and anyone who proposes the same thing in two years lands on it.
Your board works the same way if you let it. The declined request stays up with its votes intact, carrying the reason underneath, and it becomes the answer to a question nobody has asked yet. A public roadmap does the other half of that job: it shows what the no was in service of, which is the single thing that makes a decline read as a choice rather than as indifference.
The private reply has one legitimate use, and it is worth keeping: an enterprise account whose request is tangled up in their contract gets a call as well as the public decision. Not instead of it.
No, not now, and not unless are three different answers
Conflating the three is what makes a no feel arbitrary. “We are not doing this” and “we would like to and cannot this quarter” and “we would build this if you could show us it is not just you” are different commitments, and a requester who cannot tell which one they received will read the vaguest possible version and come back in six weeks.
The Rust project formalised exactly this distinction. Its RFC process has a “postponed” label for proposals it is deferring, and the README is careful about when not to use it: a postponed RFC “has already passed an informal first round of evaluation, namely the round of ‘do we think we would ever possibly consider making this change, as outlined in the RFC pull request, or some semi-obvious variation of it.’ When the answer to the latter question is ‘no’, then the appropriate response is to close the RFC, not postpone it.” That is the whole discipline in two sentences. Do not reach for the softer label because the harder one is uncomfortable to type.
| Answer | What it actually means | The status it needs | What the requester should do |
|---|---|---|---|
| No | It conflicts with what the product is for, and more votes will not change that | A closed or declined status the request keeps, with the reason attached | Stop waiting. Consider the workaround or another tool |
| Not now | We agree, it is below the line this quarter | An open backlog status that is visibly not the roadmap | Vote, subscribe, add context that might move it up |
| Not unless | We will build it if a specific condition is met, usually more demand or a clearer problem | Open, with the condition written down | Bring the missing evidence, or accept it will not happen |
The failure mode on the last row is promising a condition you have no intention of honouring. The same HN thread has a sharp version of this, from masklinn: “If you don’t intend to merge the feature, you should not say that patches are welcome.” Swap “patches” for “votes” and it is the standard SaaS sin. A request parked at “not unless 50 people ask” that would still be declined at 500 is a lie with a number in it.
Deciding which requests deserve which answer is a separate discipline, and we have written about prioritising feature requests elsewhere. This piece is about what happens once you have decided.
How do you say no when twenty people asked for the same thing?
You merge the duplicates into one thread first, decide once, and let the decision notify everyone who voted, so that twenty conversations collapse into a single published answer. Doing it the other way round, twenty individual replies, is what makes teams avoid declining anything: the cost scales with the number of people who asked, so the request with the most demand behind it becomes the one you are least willing to answer.
This is the mechanical part, and it is the part a feature request tool should carry rather than you. In Sleekplan, near-duplicates get flagged and merged without losing their votes or comments, so one idea keeps one thread and one vote count. When the status on that thread changes, every subscriber gets an email and an in-app notification. The decline reaches all twenty people in the time it takes to write one paragraph.
The same insight shows up from the other direction on our own board. In September 2026 a user filed a request asking to reject an idea with a specific reason, keep it recorded internally with a rejected status, and notify the submitter automatically. The request is not “let me say no more often”. It is “let me say no properly, once, and have the system carry it”. That is a feature request about feature requests, and it is a fair description of what most teams are missing.
One detail worth getting right: the internal reason and the public reason are not always the same sentence. Internal statuses let the team track “blocked on the billing rewrite” while customers see the one public status you map it to. Keep the public text honest and short. “Not planned: this is a reporting problem and we are solving it in analytics instead” is a real reason. “Thanks for the feedback, we will consider it” is not.
Feature creep is the bill for every no you did not say
Every request you neither build nor decline stays alive as a small obligation, and the ones you do build to avoid a difficult conversation are the expensive kind. Pendo’s 2019 Feature Adoption Report, which analysed feature usage across 615 Pendo subscriptions, found that 80 percent of features in the average software product are rarely or never used. The report does not say which of those were built to close a conversation, but anyone who has shipped a feature for one loud account can guess.
Des Traynor made the structural case for this in Product strategy means saying no, published in 2013 and still the clearest version of the argument. His line about scope is the one I keep returning to: “even the tiniest additions add hidden complexity that isn’t accounted for in the ‘but it’s just 5 minutes’ estimate.” He also names the pattern behind most reluctant yeses, “this customer is about to quit”, as feature blackmail.
I do not fully agree with his framing that the only word is no, and neither does the Rust RFC process. “Not now” is a real answer when the condition is honest and written down. But the direction is right: the default should be a decline you can defend, not a yes you can avoid an argument with. A product that has said no to the right things is easier to describe, easier to onboard into, and cheaper to maintain, and none of those show up on the ticket you closed.
Start with the requests that already went quiet
Open your board, sort by oldest, and find every request that has been sitting without a status change for more than three months. That list is your actual backlog of unsaid noes, and working through it is a better use of an afternoon than any new prioritisation framework.
For each one, pick no, not now or not unless, write one sentence of reason in the requester’s language, set the status, and let the notification go out. Expect a few unhappy replies on the first pass and very few after that. Then make it a habit: nothing sits in the queue past a week without an answer, which is the same rhythm a working feedback management loop runs on. The queue stops being a place where requests go to be ignored, and the next time you decline something, the person reading it already knows you were going to answer.