It feels like: "while we're building the user profile page, we might as well add the ability to upload an avatar." That's one feature. It takes half a day. Fine.
Except avatars need to be stored somewhere, which means an S3 bucket and an upload endpoint. They need to be resized so you're not serving 4MB images on every page load. They need to be deleted when the user deletes their account. The account deletion flow doesn't exist yet, so now you're building that too. And you need to handle the case where someone uploads a file that isn't an image.
What started as half a day is a week. And that's assuming nothing else touched the user model in the meantime.
How the compounding works
Each added feature has its own surface area: edge cases, error states, tests, documentation, and interactions with every other feature that was there before. It also adds ongoing maintenance cost. A feature that takes two days to build might add ten minutes to every future sprint because someone has to think about it when touching nearby code.
The compounding isn't just about this project. It's about the project in six months, when someone new needs to understand the codebase, or when a bug surfaces in a feature that nobody remembered adding.
Software that does fewer things is easier to maintain, easier to test, and easier to hand off. This is not a principle people disagree with in theory. It is a principle that disappears the moment someone has a good idea during a sprint review.
The right question
The question to ask is not "can we add this." The answer to that is almost always yes, eventually. The right question is "what does this cost relative to the value it delivers at launch?" And the honest follow-on: "does the product fail without it?"
Most features that feel urgent before launch look optional in retrospect. Avatar uploads do not make or break most software. The reporting export that someone wants before go-live is often used by two people and could have been a CSV download with twenty lines of code instead of the full UI that got built.
When you're mid-build and a new requirement appears, the thing to ask is whether this is a thing the product cannot ship without, or a thing someone would like to have. Those are different conversations.
How to have the conversation
The mechanism that works is having a written scope document and treating it as a reference point rather than a suggestion.
When a new feature request comes in, the response is not "no, we can't." That creates friction and makes the client feel blocked. The response is "that's not in the current scope. We can add it to the post-launch backlog, or we can scope it out properly and figure out what it pushes."
This reframe puts the decision where it belongs: with the client, with full information. "This would add about ten days to the timeline" is a different conversation than "we can't do that." One is blocking, one is informing. Clients generally make reasonable decisions when they have accurate information about tradeoffs.
The key is doing this consistently, starting from the first change request. Absorbing the first one silently sets a precedent that changes are free. They are not.