Webdav slow performance when auth enabled

Directory listing using the default webdav app (v1.2.13 / 2025-12-05) can be rather slow when authentication is enabled, due to the default password storage algorithm (bcrypt).

To improve performance, convert it to a custom app, then edit it’s config to switch password storage to sha1. You can also enable the HTTP2 protocol, which has improved performance due to multiplexing, compressed headers, etc.

For regenerating the password storage using sha1, you could use rapidtoolset(dot)com/en/tool/htpasswd-generator or other tools.

Using an example credential of webdav / webdav for testing would look as follows.
In your htauth section:

  htauth:
    content: webdav:{SHA}Sz9Iv2Lht7CS7sHd6AAn8mxusOM=

To enable HTTP2, in your httpd-conf section, ensure the http2_module is loaded:

  httpd-conf:
    content: >
      LoadModule http2_module modules/mod_http2.so

Then in your virtualhost section, update the Protocols line to enable HTTP2. You can also optionally disable lockdiscovery here:

    <VirtualHost *:443>
       # Enable both HTTP2 and HTTP 1.1
       Protocols h2 http/1.1

       # When DavLockDiscovery is off, PROPFIND always returns an empty lockdiscovery section. 
       # This can improve performance if clients use PROPFIND a lot, and should be completely safe when only reading content.
       DavLockDiscovery off

Lastly, in Directory config section where Dav is on, consider setting DavDepthInfinity On

        <Directory "/">
          # Allow clients to request full directory trees in a single call, which can reduce the number of round trips.
          DavDepthInfinity on

Pay mind to spaces when editing the custom app config. It does matter, so if your changes result in an app that won’t start, it’s possibly due to incorrect space syntax.

Thanks for the information. I’ve updated my webdav server and this seems to help.

1 Like

Umm… sha1 should never be used for password hashing on production servers. If this is some home NAS, whatever, but if you’re doing this at $placeofwork, go have a chat with the security team.

1 Like

Yeah, no SHA1 but the other settings are helpful!

Glad it was helpful! Although you may not wish to use SHA1, there are other options too…

It is clear the main performance overhead when basic auth is enabled, is due to the high default “bcrypt compute factor” (12) that is configured for storing the passwords.
That factor can be set between 4-17, and is identified at the ## location within bcrypt hash strings, like in the EXAMPLE: webdav:$$2b$$##$$…

BENCHMARKING FUN TIME

Using the default CPU/RAM resources with webdav 1.2.13, retrieving a directory list of 700 items, and testing with various hashes and an example webdav/webdav account.
My results are listed from generally most to least secure hashes…

Password Hash Type List Time Hash string (webdav/webdav)
bcrypt_f(17) Unusable webdav:$$2y$$17$$iRQC9e1BwptxcloPRNTUA.PUVogbVN7d8XVLbBzA/4DJkrHrbeyNC
bcrypt_f(12) 122 seconds webdav:$$2a$$12$$E9mvj967Fdmha5hf9dYfyuQh9GHAYDpJPy2ajz2uGetq4reD6WABi
bcrypt_f(8) 7.8 seconds webdav:$$2a$$08$$zD7yMkS1sg9xkat/kMH/r.n1WD7AVeBX0h370ORiPYEmHQeHa8BUS
SHA512 1.1 seconds webdav:$$6$$CvdkWnCh46VWjo7Q$$00SZrLDgk8LEe8NPlqy6mntwaeYfVbsajOB6y8.PD4TnkfIcGbasuTAJAWuyqTdu4aBEElX3cv/rYJpqQdtci1
SHA256 1.3 seconds webdav:$$5$$HnA6200rGCrHymwi$$7HYA0O9i1JJFxTBA07LiEY8pCUJdT64c/RrYOzzh2A7
bcrypt_f(4) .58 seconds webdav:$$2a$$04$$azt6/5.WzOIG1XvZFvvxAOnFgvQ279r4QnBHKmjv8pzHIzSUdig4S
SHA1 .05 seconds webdav:{SHA}Sz9Iv2Lht7CS7sHd6AAn8mxusOM=
MD5 .13 seconds webdav:$$apr1$$IOdVO6UU$.sBXio7SDj6SSvgEylrxf.
CRYPT .03 seconds webdav:sxUjpsjrZw1a.

For general use, choosing a more performant, yet reasonably secure hash like SHA512, may be more beneficial for most users.
Since my primary use case is a (Kodi) NAS, with webdav shares set to READONLY, I’m still going to prefer one of the fastest methods (SHA1 or CRYPT), for quick indexing and file access.
For those saddled with $dayjob, security requirements may vary based on use case…

BCrypt IS very CPU intensive, so adding more CPUs to the container may help, when sticking with that.
Bcrypt at 17 was (not surprisingly) completely unusable, and after 25 minutes of 100% CPU on 2x httpd service threads, I killed the container.
SHA512 was unexpectedly a little better than SHA256

Those who would like to use alternate hash types following their own performance and security needs, can also do so from the truenas shell.
You’ll need to sudo to root, find your running webdav container name, and then run the “htpassword” program in there, to generate a new hash to insert into the YAML configuration of the app.

truenas_admin@truenas\[\~\]$ sudo -s
[sudo] password for truenas_admin:

root@truenas[/home/truenas_admin]# docker ps
CONTAINER ID   IMAGE          COMMAND              CREATED         STATUS                   PORTS                           NAMES
be2c95f90b7c   httpd:2.4.66   “httpd-foreground”   6 hours ago     Up 6 hours (healthy)     80/tcp, 0.0.0.0:443->443/tcp   ix-webdav-webdav-1

Then using the NAME or CONTAINER ID of your running webdav app, generate new hash strings for a username and password of webdav:

#For bcrypt_f(12):
docker exec ix-webdav-webdav-1 /usr/local/apache2/bin/htpasswd -C 12 -nbB webdav webdav
#For bcrypt_f(8):
docker exec ix-webdav-webdav-1 /usr/local/apache2/bin/htpasswd -C 8 -nbB webdav webdav
#For SHA512:
docker exec ix-webdav-webdav-1 /usr/local/apache2/bin/htpasswd -nb5 webdav webdav
#For SHA256:
docker exec ix-webdav-webdav-1 /usr/local/apache2/bin/htpasswd -nb2 webdav webdav
#For bcrypt_f(4):
docker exec ix-webdav-webdav-1 /usr/local/apache2/bin/htpasswd -C 4 -nbB webdav webdav
#For SHA1:
docker exec ix-webdav-webdav-1 /usr/local/apache2/bin/htpasswd -nbs webdav webdav
#For MD5: 
docker exec ix-webdav-webdav-1 /usr/local/apache2/bin/htpasswd -nbm webdav webdav
#For CRYPT:
docker exec ix-webdav-webdav-1 /usr/local/apache2/bin/htpasswd -nbd webdav webdav

NOTE: Any single dollar signs in the hash strings must be escaped as $$ when adding them to the YAML config file.

Cheers!

This should be mostly addressed by webdav app v1.2.14, which will allow users to configure the number of bcrypt rounds via the app config UI.

RE: