Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

A performance optimization can make an app feel faster while quietly making its answer wrong. In a case described by Kotlin developer Arqam Waheed, limiting how much workout history an analysis read could inspect caused the app to miss a training plateau—the very problem its analysis feature was meant to identify.

Why a history limit changed the result

Waheed’s app, WhyRep, analyzes strength-training logs to detect stalls and suggest changes. It derives verdicts from raw set logs when a user reads them, so each analysis traverses exercise history. To avoid repeatedly loading every session, Waheed tried to bound that history.

The app’s plateau rules count consecutive missed sessions, with thresholds that vary by lifter tier and movement type. The widest rule in the methodology described in the post was 14 consecutive misses for an elite lifter on a small-joint movement. At one session per week, the relevant history could extend beyond three months.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A two-week cutoff therefore used elapsed time as a proxy for the number of sessions needed to make a decision. That proxy could exclude the very misses the rule needed to evaluate.

Why counting misses was not enough

Waheed next used a row cap derived from the widest miss window, with room for a baseline and a spare. That calculation assumed that at most one loaded row would not count as a miss. But the progression logic skipped no-verdict sessions when counting misses without resetting the streak. Those sessions still occupied rows in the bounded result.

Ordinary no-verdict paths included flagged deloads, weight changes without earned overload, rep-range changes, and variant changes. A history could therefore contain more rows than counted misses. Neutral records consumed space and pushed older, decision-relevant misses beyond the cap.

How the bug appeared in a realistic scenario

In the author’s example, an elite-tier lifter performed barbell curls across 40 weekly sessions, stalled at 30 kg for 8 reps, and had a deload at session 34. In the control case without that deload, the plateau verdict fired at session 15. With the deload, the bounded read missed it at session 13.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The screen still rendered. There was no crash, error, or log line; the severity indication and documented rep-range fix simply disappeared. These session counts describe one scenario in the author’s account, not a general statistic or an independently reproduced test.

Waheed summarized the design mistake this way: “The unit was wrong, not the number.” The algorithm counted missed sessions, but the optimization limited rows. Those quantities diverged whenever rows could be skipped for the decision while still taking up space in the result.

Fixed cap versus expanding read

Approach How it decides what to read Correctness implication Read-work trade-off
Fixed row cap Stops after a predetermined number of rows. Can omit needed misses when neutral or no-verdict rows consume part of the limit. Limits the read, but the source reports no measured latency, memory, or database-cost comparison.
Expanding read Starts with the nominal window and widens until a stopping condition shows older rows cannot change the answer. Uses the algorithm’s decision rules to establish that the available history is sufficient. Ordinary progressing cases settle on the first query; a long uninterrupted stall may require a wider read. The source gives no measured cost comparison.

How the author made the read sufficient

The fix replaced a fixed row budget with an expanding read. It widened the window until one of three conditions held:

  • The read reached the beginning of the exercise history, so no older rows existed.
  • The read contained a PROGRESS verdict, which resets the miss streak.
  • The consecutive-miss count had already reached the widest plateau window.

Each stopping condition connects the amount of data read to the logic that determines the verdict. A PROGRESS verdict breaks the relevant streak; reaching the maximum miss threshold means the plateau rule can already be evaluated; reaching the beginning of history rules out an unseen earlier record. As Waheed put it, “The loop is not a retry, it is a search for sufficiency.”

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

This approach does not claim every analysis needs a large read. The author reports that ordinary progressing cases settled on the first query, while a long uninterrupted stall could require a wider read. The available account does not quantify the added query, latency, or database cost.

Why the earlier tests missed it

Waheed added a test named AnalysisWindowTest > a deload inside a long stall must not hide the plateau and reports checking that it failed with the old constant. Five earlier tests had passed, but they reflected the same incomplete assumption: the row limit was treated as if it tracked the count of misses.

The more useful test question was not simply whether a plateau could be detected in a clean history. It was whether records that do not count toward the decision could still occupy enough of the input window to hide the evidence. Naming the scenario in the test makes that failure mode visible to future maintainers.

Waheed also says he had not built a general property-based testing approach for realistic generated training histories. Generating plausible histories requires a domain model. That is an unresolved challenge in this case, not evidence that property-based testing is inherently unsuitable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What this incident means for performance work

Treat input bounds as behavior changes

Reducing the amount of data an algorithm sees can change its answer, even if the UI still renders and execution succeeds. Review a bound as a potential behavior change, not only as a performance change.

Count both decisions and consumed records

When an algorithm counts a particular event—such as a missed session—but a limit applies to all rows, identify every record type that can occupy the limited input without counting toward the decision. A cap is safe only if its relationship to the decision remains valid across those cases.

Prefer a proof-based stopping rule when counts can diverge

If no fixed relationship connects counted events with consumed rows, a constant cap cannot by itself prove that older data is irrelevant. A stopping condition based on the algorithm’s own rules can establish sufficiency more directly, though it may require more reads for histories that do not reach an early stopping point.

Do not rely on crash monitoring to catch a wrong answer

Waheed says his existing Sentry instrumentation would not have detected the missing verdict. Monitoring that catches failures and latency remains useful, but a successfully returned, incorrect result may need domain-focused tests or other correctness checks to be noticed.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

A separate diagnostic example: controlling feature state

Feature configuration can also complicate diagnosis, though it is separate from WhyRep’s history-window bug. Chromium documents an “Enable benchmarking” flag that can set features to fixed states to help determine whether an observed problem comes from non-default feature configuration. Chromium also notes that the flag resets automatically after three restarts; on the third restart, it may appear off while its effect remains active. See Chromium’s flag source. This is a product-specific example of controlling a diagnostic variable, not a fix for an algorithm that reads too little history.

What the case does—and does not—establish

The incident illustrates how an optimization can silently alter application behavior and how neutral records can break a bound based on a different unit. The DEV Community post displays “Posted on Aug 23” without a year. Its implementation details and test outcomes are Waheed’s account; no independent reproduction or industry-wide prevalence figure is established here. The account provides qualitative trade-offs for the expanding read, not a measured performance comparison.

Read the case in full in Arqam Waheed’s DEV Community post about WhyRep.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.