LDAP Login Performance Issue in BookStack with Large AD Environment #5317

Open
opened 2026-02-05 09:57:13 +03:00 by OVERLORD · 14 comments
Owner

Originally created by @titafubaki on GitHub (Jun 16, 2025).

Describe the Bug

When using LDAP for authentication in BookStack, the login process takes excessively long, often exceeding 60 seconds. This delay is significant enough that I had to adjust the PHP timeout settings to successfully log in. The Active Directory environment in use contains a large number of groups (approximately 108,000) and users (approximately 83,000). Despite the scale of the AD environment, other software solutions utilizing LDAP do not experience similar performance issues, suggesting that the implementation method in BookStack may be contributing to the problem.

Steps to Reproduce

  1. Configure BookStack to use LDAP for authentication.
  2. Attempt to log in with a user account from a large AD environment.
  3. Observe the time taken for the login process to complete.

Expected Behaviour

The login process should complete in a reasonable time frame, similar to other software solutions using LDAP.

Screenshots or Additional Context

No response

Browser Details

MS Edge 137 on Win11

Exact BookStack Version

25.05

Originally created by @titafubaki on GitHub (Jun 16, 2025). ### Describe the Bug When using LDAP for authentication in BookStack, the login process takes excessively long, often exceeding 60 seconds. This delay is significant enough that I had to adjust the PHP timeout settings to successfully log in. The Active Directory environment in use contains a large number of groups (approximately 108,000) and users (approximately 83,000). Despite the scale of the AD environment, other software solutions utilizing LDAP do not experience similar performance issues, suggesting that the implementation method in BookStack may be contributing to the problem. ### Steps to Reproduce 1. Configure BookStack to use LDAP for authentication. 2. Attempt to log in with a user account from a large AD environment. 3. Observe the time taken for the login process to complete. ### Expected Behaviour The login process should complete in a reasonable time frame, similar to other software solutions using LDAP. ### Screenshots or Additional Context _No response_ ### Browser Details MS Edge 137 on Win11 ### Exact BookStack Version 25.05
OVERLORD added the 🐛 Bug label 2026-02-05 09:57:14 +03:00
Author
Owner

@ssddanbrown commented on GitHub (Jun 17, 2025):

Hi @titafubaki, is there significant group nesting (groups members of groups) in this environment?
My first thought is that this may be due to our recursive group lookup.

@ssddanbrown commented on GitHub (Jun 17, 2025): Hi @titafubaki, is there significant group nesting (groups members of groups) in this environment? My first thought is that this may be due to our recursive group lookup.
Author
Owner

@titafubaki commented on GitHub (Jun 17, 2025):

Hi @ssddanbrown, while there is indeed some degree of nested groups present in our AD setup, my experience suggests that this nesting is not extensive. However, in our situation, the nesting levels are relatively shallow, which should not contribute substantially to the delays we're experiencing as I even get them in cases I assign groups directly to the users.

@titafubaki commented on GitHub (Jun 17, 2025): Hi @ssddanbrown, while there is indeed some degree of nested groups present in our AD setup, my experience suggests that this nesting is not extensive. However, in our situation, the nesting levels are relatively shallow, which should not contribute substantially to the delays we're experiencing as I even get them in cases I assign groups directly to the users.
Author
Owner

@ssddanbrown commented on GitHub (Jun 17, 2025):

Okay, thanks for the response.

Do you have a specific slow test-case you can use to generate some numbers. I'd be interested to know for a single test-scenario:

  • How many groups are provided back with the user?
  • What is (roughly) the nesting depth of these?
  • How many groups do these then have?

Just trying to understand the actual scale and shape of the group heirachy/nesting at play.

Also, It'd be great to confirm login time with LDAP_USER_TO_GROUPS=false set (group sync disabled) just to confirm that this is due to group sync behaviour specifically rather than something something more generic like request latency or DNS.

@ssddanbrown commented on GitHub (Jun 17, 2025): Okay, thanks for the response. Do you have a specific slow test-case you can use to generate some numbers. I'd be interested to know for a single test-scenario: - How many groups are provided back with the user? - What is (roughly) the nesting depth of these? - How many groups do these then have? Just trying to understand the actual scale and shape of the group heirachy/nesting at play. Also, It'd be great to confirm login time with `LDAP_USER_TO_GROUPS=false` set (group sync disabled) just to confirm that this is due to group sync behaviour specifically rather than something something more generic like request latency or DNS.
Author
Owner

@titafubaki commented on GitHub (Jun 17, 2025):

Sorry, I have to clarify, this is with LDAP_USER_TO_GROUPS=false. It does not seem to add any significant time on top to enable it. This was my thinking as well so I have tried to not use it.
I can anyway construct a test szenario to have some raw numbers if needed.

@titafubaki commented on GitHub (Jun 17, 2025): Sorry, I have to clarify, this is with LDAP_USER_TO_GROUPS=false. It does not seem to add any significant time on top to enable it. This was my thinking as well so I have tried to not use it. I can anyway construct a test szenario to have some raw numbers if needed.
Author
Owner

@ssddanbrown commented on GitHub (Jun 17, 2025):

Ah, that's interesting then, should only be a few connections made.

If possible, It'd be great if you could replicate the same kinda of action using the ldapsearch CLI tool from the very same BookStack host (if/how that's installed may depend on OS in use). So use all the same details (user, password, base DN) and perform a search using the same filter as set for BookStack.
Then see if that also takes a very long time via the CLI, or if that's super quick.

@ssddanbrown commented on GitHub (Jun 17, 2025): Ah, that's interesting then, should only be a few connections made. If possible, It'd be great if you could replicate the same kinda of action using the [ldapsearch](https://linux.die.net/man/1/ldapsearch) CLI tool from the very same BookStack host (if/how that's installed may depend on OS in use). So use all the same details (user, password, base DN) and perform a search using the same filter as set for BookStack. Then see if that also takes a very long time via the CLI, or if that's super quick.
Author
Owner

@titafubaki commented on GitHub (Jun 18, 2025):

Hi @ssddanbrown,

I conducted a test using the ldapsearch CLI tool on the same Ubuntu 24.04 system where BookStack is running. I utilized the same LDAP user and connection details as configured in BookStack. Here is the command I used:

ldapsearch -x -H ldaps://XXX.XXX.XXX:636
-D "CN=SOMEUSER,OU=Users,OU=OU4,OU=OU3,OU=OU2,OU=OU1,DC=XXX,DC=XXX,DC=XXX"
-w 'PASSWORD'
-b "OU=OU1,DC=XXX,DC=XXX,DC=XXX"
-s sub "(&(sAMAccountName=SOMEUSERNAME))"
-v
The search executed for the same user account took approximately 3 seconds to complete.

@titafubaki commented on GitHub (Jun 18, 2025): Hi @ssddanbrown, I conducted a test using the ldapsearch CLI tool on the same Ubuntu 24.04 system where BookStack is running. I utilized the same LDAP user and connection details as configured in BookStack. Here is the command I used: ldapsearch -x -H ldaps://XXX.XXX.XXX:636 \ -D "CN=SOMEUSER,OU=Users,OU=OU4,OU=OU3,OU=OU2,OU=OU1,DC=XXX,DC=XXX,DC=XXX" \ -w 'PASSWORD' \ -b "OU=OU1,DC=XXX,DC=XXX,DC=XXX" \ -s sub "(&(sAMAccountName=SOMEUSERNAME))" \ -v The search executed for the same user account took approximately 3 seconds to complete.
Author
Owner

@titafubaki commented on GitHub (Jun 24, 2025):

Hi @ssddanbrown, maybe something else interesting. If the user credentials at logon are wrong I get almost immediately an error. When they are right it just start loading for a minute or so and then log in.

@titafubaki commented on GitHub (Jun 24, 2025): Hi @ssddanbrown, maybe something else interesting. If the user credentials at logon are wrong I get almost immediately an error. When they are right it just start loading for a minute or so and then log in.
Author
Owner

@ssddanbrown commented on GitHub (Jun 24, 2025):

@titafubaki Interesting; All that should occur after that is a bind as the user account, using the provided password.
You could test that like above, but just ensure you're binding via the login account.

I'm still sceptical if groups are in play, but that maybe your env changes are stuck/cached with group sync enabled. Group sync behaviour is way more likely to lead to this kind of scenario.

  • How are you actually running BookStack, what install method was used for this instance?
  • If you temporarily change AUTH_METHOD back to standard, does the login form top field change back to email?
@ssddanbrown commented on GitHub (Jun 24, 2025): @titafubaki Interesting; All that should occur after that is a bind as the user account, using the provided password. You could test that like above, but just ensure you're binding via the login account. I'm still sceptical if groups are in play, but that maybe your env changes are stuck/cached with group sync enabled. Group sync behaviour is way more likely to lead to this kind of scenario. - How are you actually running BookStack, what install method was used for this instance? - If you temporarily change `AUTH_METHOD` back to standard, does the login form top field change back to email?
Author
Owner

@titafubaki commented on GitHub (Jun 25, 2025):

Hi There, good guess :D
it seems to be stuck. I use the linuxserver/bookstack docker deployment and the variables are defined in the compose file.
changing back to standard does not show the email field.

@titafubaki commented on GitHub (Jun 25, 2025): Hi There, good guess :D it seems to be stuck. I use the linuxserver/bookstack docker deployment and the variables are defined in the compose file. changing back to standard does not show the email field.
Author
Owner

@ssddanbrown commented on GitHub (Jun 25, 2025):

After changing env options, are you re-creating (re-upping) the stack, or at least the BookStack container?
If you are just restarting the existing containers, that might not applying the config changes.

@ssddanbrown commented on GitHub (Jun 25, 2025): After changing env options, are you re-creating (re-upping) the stack, or at least the BookStack container? If you are just restarting the existing containers, that might not applying the config changes.
Author
Owner

@titafubaki commented on GitHub (Jul 4, 2025):

You was right it was stuck. reupping removed the delay. but when enabling the group sync again it is slow again.

@titafubaki commented on GitHub (Jul 4, 2025): You was right it was stuck. reupping removed the delay. but when enabling the group sync again it is slow again.
Author
Owner

@titafubaki commented on GitHub (Jul 4, 2025):

I'm not a programmer by trade, but I've reviewed some of the code. It appears that BookStack attempts to retrieve all groups recursively for a user during login. This process can be time-consuming, especially if a user belongs to many groups or if those groups are deeply nested. Wouldn't it be more efficient to reverse the approach by examining the groups defined within the roles and querying them? This could be done in the background rather than during each user login. If that's not feasible, at the very least, making the group synchronization asynchronous could prevent it from slowing down the login process itself. Please correct me if I'm wrong.

@titafubaki commented on GitHub (Jul 4, 2025): I'm not a programmer by trade, but I've reviewed some of the code. It appears that BookStack attempts to retrieve all groups recursively for a user during login. This process can be time-consuming, especially if a user belongs to many groups or if those groups are deeply nested. Wouldn't it be more efficient to reverse the approach by examining the groups defined within the roles and querying them? This could be done in the background rather than during each user login. If that's not feasible, at the very least, making the group synchronization asynchronous could prevent it from slowing down the login process itself. Please correct me if I'm wrong.
Author
Owner

@ssddanbrown commented on GitHub (Jul 4, 2025):

Wouldn't it be more efficient to reverse the approach by examining the groups defined within the roles and querying them?

Maybe, depending on how BookStack & the LDAP system is configured, but I think we'd still need to traverse the tree from the user to validate how the found groups link to the user's actual groups.

This could be done in the background rather than during each user login.
making the group synchronization asynchronous

We rarely have async functionality, only specific things via an option, since the technology stack at play does not allow async behaviour by default.
Even if it did allow it (or we made this an option) I'm not too comfortable with having user rights managed async like that, especially if already taking a minute. I'm pretty sure that would be reported back to me as a security issue. I'd rather leave it as a critical part of login for predictability.

@ssddanbrown commented on GitHub (Jul 4, 2025): > Wouldn't it be more efficient to reverse the approach by examining the groups defined within the roles and querying them? Maybe, depending on how BookStack & the LDAP system is configured, but I think we'd still need to traverse the tree from the user to validate how the found groups link to the user's actual groups. > This could be done in the background rather than during each user login. > making the group synchronization asynchronous We rarely have async functionality, only specific things via an option, since the technology stack at play does not allow async behaviour by default. Even if it did allow it (or we made this an option) I'm not too comfortable with having user rights managed async like that, especially if already taking a minute. I'm pretty sure that would be reported back to me as a security issue. I'd rather leave it as a critical part of login for predictability.
Author
Owner

@Golden-Chicken97 commented on GitHub (Aug 20, 2025):

Our Bookstack instance is also having Problems with a very slow login process. I have been getting complaints that it sometimes takes over 10 seconds to load. We are also using LDAP and nested Groups but on a much smaller scale.
Inside of the Bookstack Instance there 95 Roles

@Golden-Chicken97 commented on GitHub (Aug 20, 2025): Our Bookstack instance is also having Problems with a very slow login process. I have been getting complaints that it sometimes takes over 10 seconds to load. We are also using LDAP and nested Groups but on a much smaller scale. Inside of the Bookstack Instance there 95 Roles
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/BookStack#5317