Skip to content

[Bug]: /api/me/items-in-progress can run the server out of memory #5483

Description

@robert-clayton

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

  1. Create a podcast library with items that have a large number of episodes (mine are serialized web novels, one episode per chapter)
  2. Play several of them so they have in-progress media progress records
  3. GET /api/me/items-in-progress
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions