← all write-ups

TheDoubleTapProblem

Reliability · order flow

The scenario

You are checking out on a spotty connection. You tap "place order." Nothing seems to happen, no loading spinner, no confirmation, nothing. So you tap it again, this time with a bit more force, like that helps. A minute later, you get two order confirmations and two charges for the same thing.

Why it happens

On an unreliable network, the user's tap may have actually registered the first time, the request just has not returned a visible response yet. A second tap, made in good faith because the interface gave no feedback, submits a second, genuinely separate request. Without a mechanism to recognize "these two requests are actually the same attempt," the backend has no reason to treat them as anything other than two distinct orders.

What I would build instead

  • Assume near-instant repeat taps are noise, not intent. If two identical order submissions arrive within a few seconds of each other, the system should silently treat the second one as a duplicate of the first and simply not process it again, no need to interrupt the user with a question for something that is almost certainly just a connectivity hiccup.
  • Reserve the clarifying question for genuine ambiguity. If a second, identical order comes in after a longer gap, say, a couple of minutes, that timing pattern is less clearly a glitch and more plausibly an intentional reorder. That is the case where a quick confirmation prompt earns its place, not every duplicate, only the ones where intent is actually unclear.
  • Give immediate visual feedback on tap, always. A large part of this problem is preventable simply by making sure the button visibly responds the instant it is tapped, even before the network request completes, so users are not left guessing whether anything happened at all.

Why this matters, and how I would measure it

This is a good example of a problem that has both a backend fix (idempotency handling) and a simpler frontend fix (better tap feedback) that reduces how often the backend fix even gets tested in the first place. Good product thinking here means not over-relying on just one layer of the fix.

I would track duplicate-charge refund requests as the core metric, it should drop sharply once near-instant duplicates are silently absorbed, while genuine reorder confirmations (the rarer, intentional case) should barely change at all, since those users actually meant to place a second order.