Reward Loop Pulls 29% Harder When the Progress Bar Lies
Twenty-nine percent. That is the number that fell out of a two-week instrumentation experiment I ran on a throwaway habit-tracking app, and it has been nagging at me ever since. The feature under test was a progress bar that advanced on a schedule unrelated to the user's actual behavior — a small, deliberate lie told in pixels. Users who saw the lying bar returned to the app 29% more often in the following week than users who saw an honest one. The obvious question is why a fabricated sense of momentum should outperform the truth, and the more useful question for anyone building software is what that gap actually represents.
The Progress Bar Is a Promise, and Promises Are Cheap to Fake
A progress bar is not a measurement. It is a promise about the shape of the future. When you show someone a bar that is 60% full, you are asserting that the remaining 40% is finite, knowable, and close. That assertion is doing almost all of the psychological work. The bar itself is decoration.
This is why the lying version outperformed. My honest bar advanced only when the user logged an entry, which meant it sat still for days at a time when they were busy, sick, or bored. The dishonest bar advanced on a timer — roughly 4% per day regardless of input — and so it always had something new to show. Users opened the app, saw movement, and felt that the thing was still alive.
The mechanism here is not mysterious. It is the same one that makes a loading spinner feel faster than a static "Loading..." label even when the actual wait is identical. Researchers have documented this repeatedly: perceived progress, not actual progress, drives persistence. A 2010 study by Minjung Koo and Ayelet Fishbach found that when people were shown how far they had already come, they were more likely to keep going on a task; when shown how far they had left, they were more likely to quit. The framing of the bar — past-tense or future-tense — mattered more than the underlying numbers.
What my experiment added was a wrinkle: the bar did not even need to be accurate. It only needed to move.
The Two Audiences for Every Bar
There is a second thing happening that is easy to miss. A progress bar speaks to two different readers at once.
The first reader is the user, who wants to know whether the effort is worth continuing. The second reader is the user's future self, who will look back on the streak, the count, or the filled bar and decide whether to identify as "someone who does this." The lying bar served the first reader poorly and the second reader extremely well. It manufactured a history that did not exist, and histories are sticky.
This is where the ethics get sharp, and where I want to be careful. I am not arguing that you should lie to your users. I am arguing that you should understand what you are doing when you choose what the bar measures. Most developers pick the metric that is easiest to instrument — raw events, raw sessions, raw logins — and never ask whether that metric tells a coherent story to either reader. The result is a bar that is technically honest and psychologically inert.
Variable Rewards, and Why the Schedule Matters More Than the Prize
The behavioral literature on this is older than the web and considerably more careful than most product blogs make it sound. B.F. Skinner's work on schedules of reinforcement established that behavior maintained on a variable-ratio schedule — where the reward arrives after an unpredictable number of actions — is more resistant to extinction than behavior maintained on a fixed schedule. The pigeon keeps pecking because the next peck might be the one.
Product teams discovered this and, predictably, over-applied it. Every notification became a slot machine. Every feed refresh became a pull of the lever. The result is a generation of interfaces that are maximally sticky and minimally satisfying, and users have gotten good at recognizing them. The word "enshittification" entered common usage for a reason.
But there is a subtler finding buried in the reinforcement literature that gets far less attention, and it is the one that matters for the 29% number. Variability does not only apply to whether the reward arrives. It applies to how the reward is presented. A reward that arrives with an unexpected shape — a slightly different animation, a message that acknowledges a specific detail, a bar that moves in an irregular increment — reads as more alive than a reward that arrives identically every time, even when the underlying value is the same.
That is what the lying bar was actually doing. It was not withholding rewards. It was varying the presentation of progress in a way that kept the interface feeling responsive. The 29% lift was not the product of deception. It was the product of texture.
The Trap of Optimizing the Wrong Variable
Here is where I think most teams go wrong, and where the experiment has changed how I build.
When a team sees a 29% lift from a progress bar, the instinct is to double down on the bar. Make it bigger. Make it animate. Add confetti. Add a streak counter. Add a leaderboard. Each addition is cheap, each one produces a measurable bump, and after six months you have an interface that is exhausting to look at and impossible to leave.
The problem is that you have optimized for return frequency rather than return value. Those are different quantities, and they diverge. A user who opens your app eleven times a day because the bar keeps moving is not the same as a user who opens it once because it solves a problem. The first user is cheap to acquire and expensive to keep. The second user is the opposite.
Daniel Kahneman's work on loss aversion is relevant here, and it cuts against the usual reading. Loss aversion — the finding that losses loom roughly twice as large as equivalent gains — is typically invoked to explain why streaks work. You do not want to break the chain. But the same principle explains why streaks eventually produce resentment. Once the streak exists, the user is no longer playing to win. They are playing not to lose, and that is a different, more anxious, less enjoyable game. The bar that once felt like momentum starts to feel like a debt.
I watched this happen in my own data. The 29% lift held for the first ten days. By day fourteen, the lying-bar cohort was opening the app more often but completing fewer meaningful actions per session. They were checking, not doing. The bar had become the product.
What Honest Systems Can Borrow From Dishonest Ones
The productive move, I think, is to separate the two things the lying bar was doing and keep only the defensible one.
The indefensible part is the fabrication: showing progress that did not occur. That is a debt you eventually pay, either in user trust or in the engineering effort required to keep the fiction consistent. Anyone who has maintained a fake progress indicator across a dozen edge cases knows the cost.
The defensible part is the responsiveness. The honest bar was inert because it only moved when the user acted, which meant it was silent exactly when the user needed encouragement. The fix is not to lie about the progress. It is to find something true that moves.
Three Substitutions That Preserve the Lift
In the months since, I have tried three replacements in production systems, and all three have held up reasonably well.
Replace cumulative progress with recent activity. Instead of a bar that fills toward a distant goal, show a small chart of the last seven days. It moves every day because time moves every day, and it is entirely honest. Users read it as "am I on track," which is the question the bar was always trying to answer.
Replace the goal with a range. A bar implies a single destination. A range — "you're in the healthy band" — removes the implied debt and still provides the feedback. This is a small change with a large effect on how the interface feels over weeks rather than days.
Replace the milestone with the next concrete step. Most progress bars are vague about what comes next. Naming the next action, in plain language, does more work than the bar ever did. "Add two more entries to see your weekly pattern" outperforms a 70%-full bar in every test I have run, and it does not require the user to trust a number they cannot verify.
None of these produce the full 29%. In my tests they land somewhere between 14% and 22% on return frequency, which is a real lift and, more importantly, a lift that does not decay the way the lying bar did. The curve stays flat instead of bending downward at day ten.
The Engineering Question Underneath the Psychology Question
There is a reason this matters more now than it did five years ago, and it is not primarily a design reason.
Modern applications increasingly run on event streams, WebSocket connections, and background sync loops. The state a user sees is rarely the state that exists; it is a projection, assembled from whatever messages have arrived and whatever the client has cached. In that architecture, "progress" is not a stored number you read from a database. It is a computed estimate, and estimates are always wrong by some margin.
This means every developer building a real-time system is already making the choice my experiment forced into the open. When the client has partial information, do you show a stalled bar, a spinner, or an optimistic guess? Most teams choose the optimistic guess because it feels better, and most teams never measure whether it is accurate. That is the lying bar, shipped by default, in every product that has ever shown a progress indicator during a sync.
The 29% is not a curiosity. It is a measurement of how much users prefer a responsive interface to an accurate one when the two conflict. And they do conflict, constantly, in any system where the truth takes time to arrive.
The forward-looking question is not whether to show progress. It is whether you can build a system where the honest signal is also the responsive one. That is a harder engineering problem than it sounds — it requires knowing what is actually true about a user's state at any given moment, which means event sourcing, careful idempotency, and a willingness to show a less flattering number when the flattering one is not yet supported. It is the kind of problem that pays off slowly and then all at once.
I have started treating progress indicators the way I treat error messages: as claims the system makes about reality, which the system had better be able to defend. The bar that lies is cheap to build and expensive to own. The bar that tells the truth and still moves — that one takes actual work, and it is the only kind worth shipping.