· 8 min read

Spotify Play History

Have you ever wanted to see more of your spotify play history? No? Well, unlike you, I like knowing what I am actually listening to more than once a year.

In order to do workaround the limit that Spotify needlessly imposes on me (come-on, I am sure they are recording all this data…) I have created a small server application that runs on a VPC I have living in the cloud.

The service basically gets an auth token, and pings spotify’s API every 5 minutes, and then dumps any recent history into an SQLite database for later analysis. I chose to use Micronaut for this solution because it provides scheduled tasks, a great interface for building APIs, a great way to build out the DAOs. It’s basically Spring’s less ugly cousin. I find it way easier to work with once dependencies are ironed out.

This code has been living locally forever and I have decided to clean it up (it still has some unused PKCE bits and bobs that I bailed on). I also added some slight reliability improvements.

I switched the service off on my vpc about a year ago and never turned it back on (not sure whY!!)

Here’s a report from a year a go, I just cut a random number of songs and totally didn’t stop when I hit something super cringe. (no judgement!)

TrackArtistsAlbumDuration (ms)Plays
Celestial Spaghetti MachineCamel Power Club, Just JackCan I Tell You a Secret25714214
Back On 74JungleVolcano20948210
Walking On A DreamEmpire Of The SunWalking On A Dream (10th Anniversary Edition)19844010
Wake Me UpAviciiTrue24742610
FisherCamel Power ClubSputnik II32454610
Wicked Games (feat. Anna Naklab) - Radio EditAnna Naklab, Parra for CuvaWicked Games (feat. Anna Naklab) [Radio Edit]1952109
Feel It StillPortugal. The ManWoodstock1632539
She Moves In Her Own WayThe KooksInside In / Inside Out1693069
Valerie (feat. Amy Winehouse) - Version RevisitedAmy Winehouse, Mark RonsonVersion2194139
Inner SmileTexasThe Greatest Hits2306409
Everywhere - 2017 RemasterFleetwood MacTango In the Night (Deluxe Edition)2266539
Have A Nice DayStereophonicsJust Enough Education To Perform2050669
Higher LoveKygo, Whitney HoustonGolden Hour2282678
feelslikeimfallinginlove - Zerb x ColdplayColdplay, Zerbfeelslikeimfallinginlove (Zerb x Coldplay)2366128
Stumblin’ InCYRILStumblin’ In2133638
You’ve Got The LoveFlorence + The MachineLungs (Deluxe Version)1686668
Ho HeyThe LumineersThe Lumineers1631338
TeardropsNEIL FRANCESTeardrops1983318
Lovely DayBill WithersMenagerie2545608
I Wanna Dance with Somebody (Who Loves Me)Whitney HoustonWhitney2912938
Because You Move MeHelsloot, TinlickerBecause You Move Me1963758
MidasHolly Walker, Maribou StatePortraits2183578
Stuck In The Middle With YouStealers WheelStealers Wheel2089467
More Than A Woman - SG’s Paradise EditBee Gees, SG LewisMore Than A Woman (SG’s Paradise Edit)3579367
You Make My Dreams (Come True)Daryl Hall & John OatesVoices1906267
Don’t Know WhyNorah JonesCome Away With Me (Super Deluxe Edition)1862517
Catch & Release - Deepend RemixDeepend, Matt SimonsWhen The Lights Go Down1951737
New Slang - 2021 RemasterThe ShinsOh, Inverted World (20th Anniversary Remaster)2308667
Beautiful DayU2All That You Can’t Leave Behind2484007
Black Friday (pretty like the sun)Lost Frequencies, Tom OdellBlack Friday (pretty like the sun)1455997
Candle FlameErick the Architect, JungleVolcano1740207
Back To YouElley Duhé, Lost Frequencies, X AmbassadorsAll Stand Together1565467
Carry You HomeAlex WarrenYou’ll Be Alright, Kid (Chapter 1)1668807
Looking For the AnswerCamel Power ClubCan I Tell You a Secret3029397
Shalalala Etc.Camel Power ClubCan I Tell You a Secret1976097
All I Do Is DreamingCamel Power ClubCan I Tell You a Secret2738427
Slow It DownBenson BooneFireworks & Rollerblades1618316
TeardropElizabeth Fraser, Massive AttackMezzanine3307736
Keeping Your Head UpBirdyBeautiful Lies (Deluxe)2083956
Dancing in the MoonlightToploaderOnka’s Big Moka2326936
Natural BluesMobyPlay2537736

Here’s some log entries from the application to give you a sense of how it works:

PS C:\Users\narki\src\spotify-playhistory-tool> java -jar .\target\spotify-playhistory-tool-0.1.jar
 __  __ _                                  _
|  \/  (_) ___ _ __ ___  _ __   __ _ _   _| |_
| |\/| | |/ __| '__/ _ \| '_ \ / _` | | | | __|
| |  | | | (__| | | (_) | | | | (_| | |_| | |_
|_|  |_|_|\___|_|  \___/|_| |_|\__,_|\__,_|\__|
12:49:18.712 [main] INFO  x.mej.apps.service.DatabaseService - Schema initialized
12:49:18.722 [main] INFO  x.mej.apps.service.DatabaseService - Initialized processing state for play_history with timestamp 2026-05-20T11:49:18.714310200Z
12:49:18.741 [main] INFO  x.m.a.r.SQLiteTokenRepository - Token table initialized successfully
12:49:19.051 [scheduled-executor-thread-1] INFO  xyz.mej.apps.job.CollectHistoryJob - Starting Spotify Play History Collection
12:49:19.058 [scheduled-executor-thread-1] WARN  x.m.apps.service.PlayHistoryTracker - System is 769min behind real-time - activating catchup mode
12:49:19.059 [scheduled-executor-thread-1] INFO  xyz.mej.apps.job.CollectHistoryJob - CATCHUP MODE ACTIVATED: fetching tracks since 2026-05-20T22:44:54Z
12:49:19.062 [scheduled-executor-thread-1] INFO  x.m.apps.service.SpotifyAuthService - Persisted token is expired, refreshing with stored refresh token
12:49:19.483 [scheduled-executor-thread-1] INFO  x.m.apps.service.SpotifyAuthService - Token refreshed and persisted, expires 2026-05-21T13:49:19.478125800
12:49:19.488 [scheduled-executor-thread-1] INFO  x.m.apps.service.PlayHistoryService - Fetching play history after: 2026-05-20T22:44:54Z
12:49:20.157 [scheduled-executor-thread-1] INFO  x.m.apps.service.PlayHistoryService - Retrieved 50 tracks from Spotify API
12:49:20.157 [scheduled-executor-thread-1] INFO  xyz.mej.apps.job.CollectHistoryJob - Fetched 50 tracks from Spotify API (duplicates will be skipped)
12:49:20.203 [scheduled-executor-thread-1] INFO  x.mej.apps.service.DatabaseService - Processed 20 new play history items out of 20 in batch
12:49:20.204 [scheduled-executor-thread-1] INFO  x.m.a.service.PlayHistoryProcessor - Successfully processed batch of 20 records
12:49:20.232 [scheduled-executor-thread-1] INFO  x.mej.apps.service.DatabaseService - Processed 20 new play history items out of 20 in batch
12:49:20.233 [scheduled-executor-thread-1] INFO  x.m.a.service.PlayHistoryProcessor - Successfully processed batch of 20 records
12:49:20.250 [scheduled-executor-thread-1] INFO  x.mej.apps.service.DatabaseService - Processed 10 new play history items out of 10 in batch
12:49:20.251 [scheduled-executor-thread-1] INFO  x.m.a.service.PlayHistoryProcessor - Successfully processed batch of 10 records
12:49:20.255 [scheduled-executor-thread-1] INFO  x.m.apps.service.PlayHistoryTracker - Updated last processed timestamp to: 2026-05-21T11:48:07Z (processed 50 items)
12:49:20.255 [scheduled-executor-thread-1] INFO  xyz.mej.apps.job.CollectHistoryJob - Catchup complete: returning to normal operation mode
12:54:20.258 [scheduled-executor-thread-1] INFO  xyz.mej.apps.job.CollectHistoryJob - Starting Spotify Play History Collection
12:54:20.259 [scheduled-executor-thread-1] INFO  xyz.mej.apps.job.CollectHistoryJob - Normal collection: fetching tracks since 2026-05-21T11:33:07Z (includes overlap window)

As you can see - it has a catch-up mechanic in-case it falls over and just fetches recently played music.

If you are interested in this sort of thing, please check out the project link. If you have any ideas on how to make it better, I am all ears. My contact details are on this site or raise a PR!