Skip to content

[Bug] Large PDF writes (like updating metadata) block the Node.js event loop #371

Description

@santisbon

What went wrong?

Large PDF writes (like updating metadata) block the Node.js event loop for a long time which causes readiness probes to consider the pod unhealthy and Kubernetes pulls the pod from the service endpoints.

I see the warning is at 25MB and there's a size check but it doesn't offload to a worker.

Loading the pdf is async but this is CPU-bound, not I/O, so it doesn't yield the event loop.

This also happens at write time and most importantly on save. This last one is the heaviest operation.

Suggested fix: Run pdf-lib's PDFDocument.load() and PDFDocument.save() CPU-bound operations in Node.js worker_threads for large files so the main event loop stays free to answer health checks.

An alternative with less refactoring: detect files above PDF_BUFFER_WARNING_BYTES before the write and return { status: 'skipped' reason: 'large-pdf-would-block-event-loop' } similar to the dryRun, keeping the metadata in the database only.

Steps to reproduce

  1. Upload a large PDF book ~60MB.
  2. Edit metadata and write to file.
  3. Wait. After a while (depending on your probe config) the pod is no longer accepting connections and the app is unavailable to users.

Expected vs actual behavior

Expected:
While saving data to a large file, the app remains responsive to UI actions and the HTTP server can respond to requests like readiness probes.
Actual:
The server can't respond to requests while the large PDF write is happening, so the probe fails and the pod is removed from the service endpoints. Nobody can access the site.

Your setup

Book Orbit v1.10.0 bookorbit/bookorbit:latest
Deployment: Kubernetes
OS: Ubuntu 26.04
Browser: Brave

Relevant logs (optional)

Screenshots (optional)

No response

Before submitting

  • I've searched existing issues and this hasn't been reported yet.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingreleasedIssue or PR is included in a released version.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions