What happened?
GET /api/me/items-in-progress loads in-progress library items with findAllExpandedWhere, which eager-loads every podcast episode. Sequelize repeats the parent libraryItem row for each joined episode, so the libraryFiles JSON gets duplicated once per episode. On a podcast library with long serialized shows this runs the Node process out of heap and kills the server.
Measured on my server, duplicated libraryFiles across just the in-progress items:
Podcast A 1409 eps x 1057KB = 1455 MB
Podcast B 1197 eps x 960KB = 1122 MB
Podcast C 1042 eps x 1100KB = 1119 MB
total across all in-progress items = 5657 MB
One item on its own is enough to exhaust an 8 GB heap. The limit is applied only after the response is built, so it does not help.
Only Android Auto calls this endpoint, so from the outside it looks like "the server crashes whenever I connect Android Auto". With a Docker restart policy set it turns into a loop: the server restarts, Android Auto retries, the server dies again.
What did you expect to happen?
The endpoint should load only the episodes it needs and stay within reasonable memory regardless of how many episodes a podcast has.
Steps to reproduce the issue
- Create a podcast library with items that have a large number of episodes (mine are serialized web novels, one episode per chapter)
- Play several of them so they have in-progress media progress records
- GET /api/me/items-in-progress
- Watch server memory climb until the process is OOM killed
Audiobookshelf version
v2.35.1
How are you running audiobookshelf?
Docker
What OS is your Audiobookshelf server hosted from?
Linux
Logs
<--- Last few GCs --->
[7:0x1544bf949650] 625561133 ms: Scavenge 8090.3 (8216.5) -> 8088.8 (8229.5) MB, 16.41 / 0.00 ms (average mu = 0.661, current mu = 0.431) allocation failure;
[7:0x1544bf949650] 625562353 ms: Mark-Compact 8103.0 (8229.5) -> 8100.4 (8243.7) MB, 1179.50 / 0.00 ms (average mu = 0.505, current mu = 0.248) allocation failure; scavenge might not succeed
<--- JS stacktrace --->
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
Additional Notes
Found by capturing requests at the reverse proxy while connecting through the Android Auto Desktop Head Unit emulator. I ruled out /api/libraries/:id/personalized for all three of my libraries and an unbounded /api/libraries/:id/items first; those return in under 200 ms and barely move memory. /api/me/items-in-progress reproduces it every time.
My data: 21,360 podcast episodes across 72 items, 48 in-progress media progress records, 9,566 media progress records in total.
Still present on master as of 513a067. I have a fix and will open a PR.
What happened?
GET /api/me/items-in-progressloads in-progress library items withfindAllExpandedWhere, which eager-loads every podcast episode. Sequelize repeats the parentlibraryItemrow for each joined episode, so thelibraryFilesJSON gets duplicated once per episode. On a podcast library with long serialized shows this runs the Node process out of heap and kills the server.Measured on my server, duplicated
libraryFilesacross just the in-progress items:One item on its own is enough to exhaust an 8 GB heap. The limit is applied only after the response is built, so it does not help.
Only Android Auto calls this endpoint, so from the outside it looks like "the server crashes whenever I connect Android Auto". With a Docker restart policy set it turns into a loop: the server restarts, Android Auto retries, the server dies again.
What did you expect to happen?
The endpoint should load only the episodes it needs and stay within reasonable memory regardless of how many episodes a podcast has.
Steps to reproduce the issue
Audiobookshelf version
v2.35.1
How are you running audiobookshelf?
Docker
What OS is your Audiobookshelf server hosted from?
Linux
Logs
Additional Notes
Found by capturing requests at the reverse proxy while connecting through the Android Auto Desktop Head Unit emulator. I ruled out
/api/libraries/:id/personalizedfor all three of my libraries and an unbounded/api/libraries/:id/itemsfirst; those return in under 200 ms and barely move memory./api/me/items-in-progressreproduces it every time.My data: 21,360 podcast episodes across 72 items, 48 in-progress media progress records, 9,566 media progress records in total.
Still present on master as of 513a067. I have a fix and will open a PR.