Contact

Currently building Ohm, a music app for iOS that reads the moment you're in, because listening to music should be [like] telepathy.

Nº 9 A Small Private Publication 3 min read

Filed Every Song Started With A

Filed 23 October 2026 sofua.co.uk

The problem

For a month, every Ohm session drew its songs from one corner of a listener’s library: the songs that start with “A”. Of the 500 songs a session could choose from, 489 began with “A”.

The point of Ohm is to bring back the right song from your whole library. Whatever else was working, the first session back wasn’t a good one, and that first session is what decides whether someone comes back.

How I found it

Nothing failed. There was no error and no crash. The sort ran and returned 500 rows.

I found it on 21 June, a month after I wrote it. I’d built the pipeline and wanted to improve the diversity of the candidate pool, so I went looking at what was in it. That meant reading the actual song titles, and nearly all of them started with “A”.

What caused it

On 21 May I’d written a sort to put the songs people play most at the front. The server picks 500 candidates from each library, and I sorted on a column called last_seen_at, newest first. The goal was to bias toward actively listened-to tracks.

But last_seen_at wasn’t an Apple field. It was a timestamp from my own sync, recording when it last saw each song, and the sync wrote the same value on every row. One timestamp, across 55,914 songs. An error I wouldn’t think I could make after writing code for so long.

When you sort and every row ties, the database hands the rows back in the order it stored them. That was the order Apple sent them in, which is alphabetical.1

Why I blamed Apple

Apple Music’s web API documents the library call as fetching “all the library songs in alphabetical order”, and every song arrives with no date added, no play count and no last-played time. “Apple doesn’t timestamp your library” sounded like the whole answer, so I stopped looking.

That’s true of the web API. It isn’t true of the phone. On iOS, MusicKit gives every library song its date added, last-played date and play count, and sorts by any of them. On my phone, a sorted read of 400 songs takes 427 milliseconds, and the whole library of 58,056 songs loads in 1.6 seconds. I’d been using MusicKit since March to find and play songs. I didn’t read those three fields until September.

So the data that would have given listeners a better first session was on their phones the whole time.2 Getting that data to the server for on-demand sorting and filtering is a different story.

How I fixed it

I stopped depending on a timestamp from Apple. Candidates are now ordered by when the listener last played each song in Ohm, then by whether it’s in their Replay, then by whether it’s in one of their playlists. Those are signs of what someone actually listens to, and they’re already in Ohm. I fixed it on 22 June, the day after I found the bug.

The effect

Two things changed. The alphabetical pool is gone, so a session’s candidates now come from across the listener’s library instead of one corner of it.

And I changed where I look for timestamps. I’d been trying to get them from Apple’s web API, which doesn’t have them. I now get them from MusicKit on the phone, which does. That decision matters more than the bug fix itself, because it changes where Ohm reads listening data from.

For a month before that, sessions couldn’t reach most of a listener’s library.

What’s still open

The date added still doesn’t reach the server intact. The phone uploads it, and then the nightly library sync overwrites it with Apple’s empty value (fix due soon). Until then, the server can’t tell a song you added last week from one you added years ago. Fixing it is part of a bigger change to how syncing works, which I haven’t made yet.

The last-played date has its own catch. Apple documents it as the last play “on this device”. When I first read it, the song at the top of my recently-played list had a last-played date of June 2025. So I don’t use it as a play time. (Strategy changed as of 26 September 2026) It would bring listeners the wrong songs.

What I’d do again

When a sort looks broken, check whether every row has the same value before you blame the data source. And when a vendor’s API looks like the limit, check whether the device in the listener’s pocket already has the answer.

Footnotes

  1. That last step is my best explanation, not something I measured. ↩

  2. Apple does document the alphabetical order. What I never did was ask whether the phone could do better. ↩