5 min read

Post-Mortem of a Few Sleepless Weeks

A story about 43% of users losing their sleep data, and two developers losing their sleep in the process.
Post-Mortem of a Few Sleepless Weeks
Artwork handcrafted by Patricia Bedoya.

Some bugs are embarrassing. Some are humbling. This one was both.

Between February 17 and March 10, a significant chunk of FitWoody users experienced something we'd consider a cardinal sin for a fitness app: their sleep data simply disappeared from the Home screen. No warning. No error message. Just... nothing where your sleep score should be.

We owe you an honest account of what happened, what we did about it, and what we've changed so it never happens again.

How it started

On February 17, we shipped v2.3, our most ambitious update yet. It included Training Load, a feature we'd been working on for months that tracks how hard your body is actually working across your training sessions. We were genuinely proud of it.

What we didn't realize was that, in restructuring parts of the app to support Training Load, we'd quietly broken the pipeline responsible for importing your sleep data in the background. The data was there, sitting in Apple Health, perfectly intact. FitWoody just wasn't picking it up.

The worst part? Neither Patricia nor I noticed. Our beta testers didn't notice either, because we all happened to fall into the group of users the bug never touched. That's what made it so hard to catch: this wasn't a bug that broke the app for everyone. It was silent, selective, and only surfaced for a specific subset of users depending on their device, usage patterns, and how the background sync happened to behave. From the inside, everything looked fine. From the outside, for those affected, it was broken from day one.

A chain reaction, not a single mistake

Once we started getting reports from users (thank you, seriously), we dug in. What we found wasn't one bug. It was three, stacked on top of each other like a very unfortunate sandwich.

Some were introduced by v2.3. Some had been lurking in the codebase for much longer, invisible until the right conditions exposed them. Here's a plain-English summary of what was actually going wrong:

Bug 1: Training Load broke the sleep pipeline without touching it. When we restructured the app's background sync to support Training Load, we accidentally broke how sleep data was imported in the background. iOS would kill the process before it could finish. The data existed in Apple Health, perfectly fine. FitWoody just wasn't collecting it.

Bug 2: A date format mismatch that silently broke everything. Somewhere in the chain between our database and the app, dates were being subtly reformatted. The difference was invisible to the human eye (a Z at the end of a timestamp becoming +00), but it was enough to make every single date-based query in the app return nothing. Silently. No error, no warning, just empty results.

Bug 3: The infinite failure loop. This was the last one, and the nastiest. When the app tried to import sleep data that had already been partially processed, it would hit a database conflict, roll back the entire batch of records, and then try again from the same point. And fail again. And try again. Forever. The data never made it in, and nothing indicated anything was wrong.

All of them, combined, resulted in sleep data not showing up for a meaningful portion of our users. We released fixes in v2.3.2, v2.3.3, and v2.3.4, between February 25 and March 10. Each patch helped, but each one also revealed another layer of the problem underneath. At our worst point, around February 28, sleep sync had dropped roughly 43% compared to normal levels.

Not great.

The moment we changed our approach

After v2.3.3, we realized we were fixing things partially and shipping blind. We'd push a release, it would solve the issue for some users, and then someone else would report that it still wasn't working for them. Lather, rinse, repeat.

So we paused and built something we should have had earlier: a proper diagnostics system built into the app itself.

From v2.3.4 onwards, if something goes wrong and you want to help us investigate, you can go to Settings → About → Report a Bug and send us a full diagnostic report from your device. It captures exactly what the app was doing at the moment of the failure, without exposing any personal data.

The impact was immediate. The last bug in this chain, a tricky database conflict that was silently wiping sleep records and triggering an endless failure loop, was found and fixed within hours of receiving the first diagnostic report from a user who sent us one. Without that tool, it would have taken weeks.

What we've changed for the future

Beyond the immediate fixes, this incident forced us to rethink a few things:

  • Background sync now runs in a protected phase that iOS can't interrupt before the job is done.
  • Sleep import has a safety net: even if the background process fails, opening the app triggers a catch-up import.
  • Our database now handles duplicate data gracefully, no matter how many times the same records are processed.
  • Every critical point in the sync pipeline is now logged, so if something breaks again, we'll know exactly where and why.

And yes, we've written extensive internal documentation so that the next time we touch this part of the codebase, whoever is reading it (probably future-us at 11pm) knows where the landmines are.

A note on transparency

FitWoody's whole premise is that your data should work for you. An app that tracks your sleep but fails to show it isn't just broken, it's failing at its core job. We take that seriously.

We're also a two-person team building something we genuinely believe in. That means we move fast, and sometimes we break things. What we can promise is that when we do, we'll tell you what happened, fix it properly, and make it better going forward.

Thank you

This section is important.

To everyone who emailed us, replied to our messages, sent screenshots, or patiently updated through three consecutive patches hoping the next one would finally fix it: thank you. Your patience and willingness to help made the difference between a months-long nightmare and a resolved incident.

A special thank you to Jacobo Vidal, who sent in a diagnostic report that handed us exactly the information we needed to close the last chapter of this.

One more thing

If you were on a free trial during this period and couldn't properly use FitWoody because of the sleep bug, that's not the experience we want you to judge us by.

We'd like to give you another shot.

Click here and we'll give you a fresh one-month trial. Because a fitness app that doesn't show your sleep data is a bit like a bicycle with no wheels, and you deserve to see what FitWoody actually looks like when it works.

Thanks for sticking with us.