← ALL FIELD NOTES

LOG 037 · TECHNICAL · 2023-10-01

Rebuilt listen tracking around fragments without breaking old clients

1 min read

Situation

Goodpods is a podcast app, and how much of an episode a user actually heard is its most important behavioural data. The existing model stored one simple listen record per user per episode. It could not capture partial listens, where users skipped around, whether they finished an episode, or what playback speeds they used. The product wanted features that all depended on richer data: advanced analytics for podcasters, leaderboards ranked by listen time, and per-user stats like listen minutes.

Task

I was responsible for replacing the listen data model on the live system while keeping every existing client working.

Action

I designed a fragments model: instead of one record per episode, each listening session writes a fragment of what was actually played, so seeks, sleep-timer stops, and resumed sessions all show up in the data. I built the new table and schema first, then a set-listen endpoint for clients to write fragments. Backward compatibility was the main migration risk, so rather than forcing every client to update at once, I reworked the existing endpoints to stay compatible and wrote a daily task that rolled fragments up into the old listen type. Old code paths kept reading the shape they expected while new features read fragments directly. I then swept the codebase for every place that assumed one listen per episode and fixed each to handle multiple fragments, which included rewriting a 628-line episode test file. On top of the new model I built the stats aggregation task, admin endpoints, and a user listen stats endpoint. I also fixed a slow episode query mid-migration, and later extended fragments with a sleep-timer end reason and split platform tracking into Android and iOS.

Result

The migration was backwards compatible: fragments were converted into the old listen type daily, so existing clients and downstream code kept working throughout. The richer data enabled advanced analytics for podcasters, leaderboards ranked by listen time, and per-user stats like listen minutes.