mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-03-02 22:46:55 -05:00
[Bug]: Slow file upload/processing speed with large library (~54k items) despite optimal config #3202
Labels
No labels
authentication
awaiting release
backlog
bug
chapter editor
config-issue
ebooks
encoding/embedding
enhancement
help wanted
listening sessions & progress
planned
possible plugin
progress sync
sorting/filtering/searching
unable to reproduce
upload
users & permissions
waiting
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/audiobookshelf-advplyr#3202
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @piotr1alien-art on GitHub (Jan 25, 2026).
What happened?
File upload/processing caps at ~3-3,5 MB/s. Diagnostic steps show this is not due to CPU (Zlib off), disk I/O (iostat shows low %util), network, or reverse proxy. The bottleneck appears to be the high volume of small database I/O operations generated per file in a large library.
What did you expect to happen?
File upload/processing caps at min~16-18 MB/s.
Steps to reproduce the issue
Audiobookshelf version
ABS v2.30.0/2.32.1, Debian 12,
AB_ZLIB_LEVEL=0, SQLite DB on NVMe (WAL mode), library on SSD RAID.How are you running audiobookshelf?
Debian/PPA
What OS is your Audiobookshelf server hosted from?
Linux
If the issue is being seen in the UI, what browsers are you seeing the problem on?
Firefox
Logs
Additional Notes
No response
@piotr1alien-art commented on GitHub (Jan 25, 2026):
2026-01-25 14:39:46.440
FATAL
[Server] Unhandled rejection: Error at Database. (/snapshot/audiobookshelf/node_modules/sequelize/lib/dialects/sqlite/query.js:185:27) at /snapshot/audiobookshelf/node_modules/sequelize/lib/dialects/sqlite/query.js:183:50 at new Promise () at Query.run (/snapshot/audiobookshelf/node_modules/sequelize/lib/dialects/sqlite/query.js:183:12) at /snapshot/audiobookshelf/node_modules/sequelize/lib/sequelize.js:315:28 at async SQLiteQueryInterface.bulkInsert (/snapshot/audiobookshelf/node_modules/sequelize/lib/dialects/abstract/query-interface.js:346:21) at async recursiveBulkCreate (/snapshot/audiobookshelf/node_modules/sequelize/lib/model.js:1697:25) at async bookAuthor.bulkCreate (/snapshot/audiobookshelf/node_modules/sequelize/lib/model.js:1786:12) at async ApiRouter.update (/snapshot/audiobookshelf/server/controllers/AuthorController.js) { name: 'SequelizeUniqueConstraintError', errors: [ ValidationErrorItem { message: 'bookId must be unique', type: 'unique violation', path: 'bookId', value: null, origin: 'DB', instance: null, validatorKey: 'not_unique', validatorName: null, validatorArgs: [] }, ValidationErrorItem { message: 'authorId must be unique', type: 'unique violation', path: 'authorId', value: null, origin: 'DB', instance: null, validatorKey: 'not_unique', validatorName: null, validatorArgs: [] } ], parent: [Error: SQLITE_CONSTRAINT: UNIQUE constraint failed: bookAuthors.bookId, bookAuthors.authorId] { errno: 19, code: 'SQLITE_CONSTRAINT', sql: "INSERT INTO
bookAuthors(id,createdAt,bookId,authorId) VALUES ('73db31a5-3de8-4551-86ef-22c1fccd5d6b','2026-01-25 13:39:46.427 +00:00','5a32c81b-5e37-4fa8-8d0c-7b40c929c245','c4c746a4-7f3e-43a3-9761-e3aa46e6c51a');" }, original: [Error: SQLITE_CONSTRAINT: UNIQUE constraint failed: bookAuthors.bookId, bookAuthors.authorId] { errno: 19, code: 'SQLITE_CONSTRAINT', sql: "INSERT INTObookAuthors(id,createdAt,bookId,authorId) VALUES ('73db31a5-3de8-4551-86ef-22c1fccd5d6b','2026-01-25 13:39:46.427 +00:00','5a32c81b-5e37-4fa8-8d0c-7b40c929c245','c4c746a4-7f3e-43a3-9761-e3aa46e6c51a');" }, fields: [ 'bookId', 'authorId' ], sql: "INSERT INTObookAuthors(id,createdAt,bookId,authorId) VALUES ('73db31a5-3de8-4551-86ef-22c1fccd5d6b','2026-01-25 13:39:46.427 +00:00','5a32c81b-5e37-4fa8-8d0c-7b40c929c245','c4c746a4-7f3e-43a3-9761-e3aa46e6c51a');" } promise: Promise { Error at Database. (/snapshot/audiobookshelf/node_modules/sequelize/lib/dialects/sqlite/query.js:185:27) at /snapshot/audiobookshelf/node_modules/sequelize/lib/dialects/sqlite/query.js:183:50 at new Promise () at Query.run (/snapshot/audiobookshelf/node_modules/sequelize/lib/dialects/sqlite/query.js:183:12) at /snapshot/audiobookshelf/node_modules/sequelize/lib/sequelize.js:315:28 at async SQLiteQueryInterface.bulkInsert (/snapshot/audiobookshelf/node_modules/sequelize/lib/dialects/abstract/query-interface.js:346:21) at async recursiveBulkCreate (/snapshot/audiobookshelf/node_modules/sequelize/lib/model.js:1697:25) at async bookAuthor.bulkCreate (/snapshot/audiobookshelf/node_modules/sequelize/lib/model.js:1786:12) at async ApiRouter.update (/snapshot/audiobookshelf/server/controllers/AuthorController.js) { name: 'SequelizeUniqueConstraintError', errors: [ [ValidationErrorItem], [ValidationErrorItem] ], parent: [Error: SQLITE_CONSTRAINT: UNIQUE constraint failed: bookAuthors.bookId, bookAuthors.authorId] { errno: 19, code: 'SQLITE_CONSTRAINT', sql: "INSERT INTObookAuthors(id,createdAt,bookId,authorId) VALUES ('73db31a5-3de8-4551-86ef-22c1fccd5d6b','2026-01-25 13:39:46.427 +00:00','5a32c81b-5e37-4fa8-8d0c-7b40c929c245','c4c746a4-7f3e-43a3-9761-e3aa46e6c51a');" }, original: [Error: SQLITE_CONSTRAINT: UNIQUE constraint failed: bookAuthors.bookId, bookAuthors.authorId] { errno: 19, code: 'SQLITE_CONSTRAINT', sql: "INSERT INTObookAuthors(id,createdAt,bookId,authorId) VALUES ('73db31a5-3de8-4551-86ef-22c1fccd5d6b','2026-01-25 13:39:46.427 +00:00','5a32c81b-5e37-4fa8-8d0c-7b40c929c245','c4c746a4-7f3e-43a3-9761-e3aa46e6c51a');" }, fields: [ 'bookId', 'authorId' ], sql: "INSERT INTObookAuthors(id,createdAt,bookId,authorId) VALUES ('73db31a5-3de8-4551-86ef-22c1fccd5d6b','2026-01-25 13:39:46.427 +00:00','5a32c81b-5e37-4fa8-8d0c-7b40c929c245','c4c746a4-7f3e-43a3-9761-e3aa46e6c51a');" } }@piotr1alien-art commented on GitHub (Jan 25, 2026):
SQLite version 3.50.1 2025-06-06 14:52:32
Enter ".help" for usage hints.
sqlite> SELECT * FROM bookAuthors WHERE bookId='5a32c81b-5e37-4fa8-8d0c-7b40c929c245' AND authorId='c4c746a4-7f3e-43a3-9761-e3aa46e6c51a';
699899b5-7fcf-4e61-8473-2e48af7d4e36|2025-04-30 12:08:42.760 +00:00|5a32c81b-5e37-4fa8-8d0c-7b40c929c245|c4c746a4-7f3e-43a3-9761-e3aa46e6c51a
sqlite> SELECT bookId, authorId, COUNT() as count
FROM bookAuthors
GROUP BY bookId, authorId
HAVING COUNT() > 1; ...> ...> ...>
sqlite> .exit
@nichwall commented on GitHub (Jan 25, 2026):
I'm confused, is this with scanning a brand new library of 54000 books or uploading a single book to an existing 54000 book library?
@piotr1alien-art commented on GitHub (Jan 25, 2026):
In my case, it's about uploading/updating a single book to an already existing large library (~54k items).
It seems like a race condition or a lack of proper "upsert" logic. I’ve caught a SequelizeUniqueConstraintError in the logs. Even though the system resources are underutilized, the server throws a FATAL error because it tries to INSERT a bookId and authorId pair that already exists in the SQLite database, instead of ignoring or updating it.
Here is the specific error from my logs: SQLITE_CONSTRAINT: UNIQUE constraint failed: bookAuthors.bookId, bookAuthors.authorId
When I checked the database manually: SELECT * FROM bookAuthors WHERE bookId='...' AND authorId='...'; The entry was already there (created months ago), but the upload process tried to recreate it with a new ID, crashing the server.