[PR #1431] [MERGED] Implement X-Accel Redirect #3545

Closed
opened 2026-04-25 00:16:04 +02:00 by adam · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/advplyr/audiobookshelf/pull/1431
Author: @lkiesow
Created: 1/23/2023
Status: Merged
Merged: 1/24/2023
Merged by: @advplyr

Base: masterHead: x-accel


📝 Commits (1)

  • 08250e2 Implement X-Accel Redirect

📊 Changes

4 files changed (+26 additions, -5 deletions)

View changed files

📝 server/Server.js (+1 -0)
📝 server/controllers/LibraryItemController.js (+4 -0)
📝 server/managers/CacheManager.js (+10 -0)
📝 server/routers/StaticRouter.js (+11 -5)

📄 Description

This patch implements X-Accel redirect headers as an optional way for offloading static file delivery from Express to Nginx, which is far better optimized for static file delivery.

This provides a really easy to configure way for getting a huge performance boost over delivering all files through Audiobookshelf.

How it works

The way this works is basically that Audiobookshelf gets an HTTP request for delivering a static file (let's say an audiobook). It will first check the user is authorized and then convert the API path to a local file path.

Now, instead of reading and delivering the file, Audiobookshelf will return just the HTTP header with an additional X-Accel-Redirect pointing to the file location on the file syste.

This header is picked up by Nginx which will then deliver the file.

Configuration

The configuration for this is very simple. You need to run Nginx as reverse proxy and it must have access to your Audiobookshelf data folder.

You then configure Audiobookshelf to use X-Accel by setting USE_X_ACCEL=/protected. The path is the internal redirect path used by Nginx.

In the Nginx configuration you then configure this location and map it to the storage area to serve like this:

location /protected/ {
  internal;
  alias /;
}

That's all.

Impact

I just did a very simple performance test, downloading a 1170620819 bytes large audiobook file from another machine on the same network like this, using time -p to measure how log the process took:

URL='https://url to audiobook…'

for i in `seq 1 50`
do
  echo "$i"
  curl -s -o /dev/null "${URL}"
done

This sequential test with 50 iterations and without x-accel resulted in:

real 413.42
user 197.11
sys 82.04

That is an average download speed of about 1080 MBit/s.

With X-Accel enabled, serving the files through Nginx, the same test yielded the following results:

real 200.37
user 86.95
sys 29.79

That is an average download speed of about 2229 MBit/s, more than doubling the previous speed.

I have also run the same test with 4 parallel processes and 25 downloads each. Without x-accel, that test resulted in:

real 364.89
user 273.09
sys 112.75

That is an average speed of about 2448 MBit/s.

With X-Accel enabled, the parallel test also shows a significant speedup:

real 167.19
user 195.62
sys 78.61

That is an average speed of about 5342 MBit/s.

While doing that, I also peaked at the system load which was lower when using X-Accel. Even though the system was delivering far more data. But I just looked at the load1 values and did not build a proper test for that. That means, I cant provide any definitive data.

Supported Media

The current implementation works for audio files and book covers. There are other media files which would benefit from this mechanism like feed covers or author pictures.

But that's something for a future developer ;-)

Documentation

This patch does not yet contain any documentation (except for the one you are looking at right now ;-). There is the reverse proxy section in the main README.md, but I was wondering if it wouldn't make more sense to move the whole proxy documentation into the actual documentation page and including this feature there as well?


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/advplyr/audiobookshelf/pull/1431 **Author:** [@lkiesow](https://github.com/lkiesow) **Created:** 1/23/2023 **Status:** ✅ Merged **Merged:** 1/24/2023 **Merged by:** [@advplyr](https://github.com/advplyr) **Base:** `master` ← **Head:** `x-accel` --- ### 📝 Commits (1) - [`08250e2`](https://github.com/advplyr/audiobookshelf/commit/08250e266e8ecb15e89d212a60e4b53f510e41b0) Implement X-Accel Redirect ### 📊 Changes **4 files changed** (+26 additions, -5 deletions) <details> <summary>View changed files</summary> 📝 `server/Server.js` (+1 -0) 📝 `server/controllers/LibraryItemController.js` (+4 -0) 📝 `server/managers/CacheManager.js` (+10 -0) 📝 `server/routers/StaticRouter.js` (+11 -5) </details> ### 📄 Description This patch implements [X-Accel](https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/) redirect headers as an optional way for offloading static file delivery from Express to Nginx, which is far better optimized for static file delivery. This provides a really easy to configure way for getting a huge performance boost over delivering all files through Audiobookshelf. How it works ------------ The way this works is basically that Audiobookshelf gets an HTTP request for delivering a static file (let's say an audiobook). It will first check the user is authorized and then convert the API path to a local file path. Now, instead of reading and delivering the file, Audiobookshelf will return just the HTTP header with an additional `X-Accel-Redirect` pointing to the file location on the file syste. This header is picked up by Nginx which will then deliver the file. Configuration ------------- The configuration for this is very simple. You need to run Nginx as reverse proxy and it must have access to your Audiobookshelf data folder. You then configure Audiobookshelf to use X-Accel by setting `USE_X_ACCEL=/protected`. The path is the internal redirect path used by Nginx. In the Nginx configuration you then configure this location and map it to the storage area to serve like this: ``` location /protected/ { internal; alias /; } ``` That's all. Impact ------ I just did a very simple performance test, downloading a 1170620819 bytes large audiobook file from another machine on the same network like this, using `time -p` to measure how log the process took: ```sh URL='https://url to audiobook…' for i in `seq 1 50` do echo "$i" curl -s -o /dev/null "${URL}" done ``` This sequential test with 50 iterations and without x-accel resulted in: ``` real 413.42 user 197.11 sys 82.04 ``` That is an average download speed of about 1080 MBit/s. With X-Accel enabled, serving the files through Nginx, the same test yielded the following results: ``` real 200.37 user 86.95 sys 29.79 ``` That is an average download speed of about 2229 MBit/s, more than doubling the previous speed. I have also run the same test with 4 parallel processes and 25 downloads each. Without x-accel, that test resulted in: ``` real 364.89 user 273.09 sys 112.75 ``` That is an average speed of about 2448 MBit/s. With X-Accel enabled, the parallel test also shows a significant speedup: ``` real 167.19 user 195.62 sys 78.61 ``` That is an average speed of about 5342 MBit/s. While doing that, I also peaked at the system load which was lower when using X-Accel. Even though the system was delivering far more data. But I just looked at the `load1` values and did not build a proper test for that. That means, I cant provide any definitive data. Supported Media --------------- The current implementation works for audio files and book covers. There are other media files which would benefit from this mechanism like feed covers or author pictures. But that's something for a future developer ;-) Documentation ----------------- This patch does not yet contain any documentation (except for the one you are looking at right now ;-). There is the reverse proxy section in the main `README.md`, but I was wondering if it wouldn't make more sense to move the whole proxy documentation into the actual documentation page and including this feature there as well? --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
adam added the pull-request label 2026-04-25 00:16:04 +02:00
adam closed this issue 2026-04-25 00:16:04 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/audiobookshelf#3545