# pihole-FTL + unbound with Cache DB Module Options (Redis)

**URL:** <https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676>\
**Category:** Customizing Pi-hole\
**Created:** [October 17, 2019, 3:36pm UTC](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676 "2019-10-17T15:36:44Z")\
**Posts on this page:** 13\
**Page:** 2

<div class="post-metadata">

**Author:** ![DL6ER](https://discourse-cdn.pi-hole.net/user_avatar/discourse.pi-hole.net/dl6er/32/281_2.png) [@DL6ER](https://discourse.pi-hole.net/u/DL6ER)\
**Post date:** [October 21, 2019, 4:36pm UTC](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676/26 "2019-10-21T16:36:38Z")

</div>

> [@jpgpi250](#):
>
> I, and probably others, added **prefetch=yes** to my unbound config, as the result of a [discussion](https://discourse.pi-hole.net/t/anyone-using-knot-resolver/19750/68) (@DL6ER - Everyone of the team agreed to remove the lines) , where it was decided to remove **cache-min-ttl** and **cache-max-ttl** from the [recommended unbound config](https://docs.pi-hole.net/guides/unbound/), so the behavior @GieltjE has seen is probably because of the **prefetch=yes** setting.

Oh yes, but you see there also the reason for why it still wasn't changed - I put it on some paper and then forgot. Problem is that I'm traveling as well now. If you want to submit a docs PR I'd be happy approving and merging it.

> [@jpgpi250](#):
>
> Especially the last one proves Redis is really doing something, even on a system where unbound hasn’t been up very long

Is this a also starting from an empty Redis database?

I'm repeating myself here, but I still don't see what Redis _effectively_ brings into play with `serve-expired: yes` besides a possible restarting resistance.

---

<div class="post-metadata">

**Author:** ![mibere](https://discourse-cdn.pi-hole.net/user_avatar/discourse.pi-hole.net/mibere/32/18057_2.png) [@mibere](https://discourse.pi-hole.net/u/mibere)\
**Post date:** [October 21, 2019, 4:54pm UTC](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676/27 "2019-10-21T16:54:20Z")

</div>

> [@DL6ER](#):
>
> restarting resistance

For me that is already a reason or advantage.

---

<div class="post-metadata">

**Author:** ![jpgpi250](https://discourse-cdn.pi-hole.net/user_avatar/discourse.pi-hole.net/jpgpi250/32/286_2.png) [@jpgpi250](https://discourse.pi-hole.net/u/jpgpi250)\
**Post date:** [October 21, 2019, 5:05pm UTC](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676/29 "2019-10-21T17:05:52Z")

</div>

I noticed another, probably important sentence in the unbound documentation:

```auto
The thread waiting for a response from the Redis server cannot handle other DNS queries.

```

To my understanding, this means a change to the **num-threads** setting will also be required, this to avoid delays

```auto
num-threads: 2

```

anybody agrees / disagrees?

> [@DL6ER](#):
>
> If you want to submit a docs PR I’d be happy approving and merging it.

Where can I find instructions on how to do that without causing problems?

> [@DL6ER](#):
>
> Is this a also starting from an empty Redis database?

To ensure I don't need to troubleshoot Redis problems, I've added the following:

1. Script, /etc/unbound/clearRedisDB.sh, content:

> #!/bin/bash  
> redis-cli FLUSHALL

1. Add line to /lib/systemd/system/unbound.service, content:

> ExecStartPre=/etc/unbound/clearRedisDB.sh

This empties the Redis cache whenever unbound starts, so both caches where empty before this log entries where entered.

---

<div class="post-metadata">

**Author:** ![GieltjE](https://discourse-cdn.pi-hole.net/letter_avatar_proxy/v4/letter/g/ba8739/32.png) [@GieltjE](https://discourse.pi-hole.net/u/GieltjE)\
**Post date:** [October 22, 2019, 8:45am UTC](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676/33 "2019-10-22T08:45:44Z")

</div>

Indeed "prefetch: yes" is in my unbound config, but the serve-expired rows are not present.  
What is the best config to adhere to the RFC's?

---

<div class="post-metadata">

**Author:** ![jpgpi250](https://discourse-cdn.pi-hole.net/user_avatar/discourse.pi-hole.net/jpgpi250/32/286_2.png) [@jpgpi250](https://discourse.pi-hole.net/u/jpgpi250)\
**Post date:** [October 22, 2019, 12:55pm UTC](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676/34 "2019-10-22T12:55:54Z")

</div>

> [@jpgpi250](#):
>
> To my understanding, this means a change to the **num-threads** setting will also be required, this to avoid delays
> 
> ```auto
> num-threads: 2
> 
> ```
> 
> anybody agrees / disagrees?

Answering my own question here. Found [this document](https://www.nlnetlabs.nl/documentation/unbound/howto-optimise/) on how to optimize unbound  
On a [raspberry pi 3B and 3B+](https://www.datenreise.de/en/raspberry-pi-3b-and-3b-in-comparison/), this would imply the correct setting on a 3B would be `num-threads: 4`

With the great help of @mibere (hank you for this), I've made some changes to my unbound config. This implies unbound needs to be compiled with an additional option: `--with-libevent`, which requires the installation of `libevent-dev` (sudo apt-get -y install libevent-dev).

I've already applied some of the proposed settings, not all (yet), and have updated my [GitHub](https://github.com/jpgpi250/unbound_as_unfiltered_DNS-resolver) repository to reflect the changes.

Feel free to comment on / discuss the settings in these configuration files.

> [@GieltjE](#):
>
> but the serve-expired rows are not present.

Not sure, but I don't expect Redis to have a great impact (if any), when these settings are not present. To verify this, you could increase the verbosity of unbound, and check the unbound log for entries containing `redis_lookup found` (sudo cat /etc/unbound/unbound.log | grep redis - use the correct location). It's a lot of logging (verbosity 5), so ensure you have sufficient disk space...  
I'm still using my initial settings, evaluating this and keeping the proposed settings from @mibere in mind (see above).

---

<div class="post-metadata">

**Author:** ![DL6ER](https://discourse-cdn.pi-hole.net/user_avatar/discourse.pi-hole.net/dl6er/32/281_2.png) [@DL6ER](https://discourse.pi-hole.net/u/DL6ER)\
**Post date:** [October 22, 2019, 2:59pm UTC](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676/36 "2019-10-22T14:59:49Z")

</div>

> [@jpgpi250](#):
>
> > If you want to submit a docs PR I’d be happy approving and merging it.
> 
> Where can I find instructions on how to do that without causing problems?

Fork [GitHub - pi-hole/docs: The official Pi-hole documentation](https://github.com/pi-hole/docs) and submit a PR against `master` (there is no `development` branch on this repo). After the PR has been merged, the changes will be automatically deployed to [https://docs.pi-hole.net](https://docs.pi-hole.net)

---

<div class="post-metadata">

**Author:** ![stephensmith1211](https://discourse-cdn.pi-hole.net/user_avatar/discourse.pi-hole.net/stephensmith1211/32/8453_2.png) [@stephensmith1211](https://discourse.pi-hole.net/u/stephensmith1211)\
**Post date:** [October 29, 2019, 9:20pm UTC](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676/37 "2019-10-29T21:20:13Z")

</div>

Thanks for this information. It is useful

---

<div class="post-metadata">

**Author:** ![Talkabout](https://discourse-cdn.pi-hole.net/letter_avatar_proxy/v4/letter/t/a698b9/32.png) [@Talkabout](https://discourse.pi-hole.net/u/Talkabout)\
**Post date:** [March 28, 2020, 1:26pm UTC](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676/38 "2020-03-28T13:26:11Z")

</div>

Hi guys,

wanted to share some experience with unbound and redis on my end. I was searching for a way to have a shared cache across multiple unbound instances. Out of the box there is no way to do this and also redis is not able to provide such a functionality. But fortunately there is an alternative: KeyDB. This tool is 100% Redis compatible and also provides active replication. With that, setting up KeyDB on 2 servers together with unbound, it is possible to have 2 DNS servers sharing same data and provide fallback mechanism in case, one of the servers crashes.

Additionally I was not very happy about the fact that unbound is not setting the expiry date on redis records although the ttl is known at that point of time where those are written to the database. Because of that I changed the unbound code slightly with the help in this thread:

> <https://github.com/NLnetLabs/unbound/issues/195>
>
> Currently the records stored in Redis have no expiry information.
> The DNS TTL i…s encoded in the record itself but the records keep on living in Redis unless removed by an eviction policy.
> A configuration option could be available to add expiry on those records based on the DNS TTL.
> Based on the usage scenario, a user could opt in for the feature.
> 
> Initial thinking is to use \`SETEX\` instead of \`SET\` when that option is enabled. \`SETEX\` provides atomicity which we want but is only supported in Redis \>= 2.0.0. Maybe try to honor the option but give a warning and fallback to \`SET\` when Redis \< 2.0.0.
> 
> Additional notes:
> \- Expiry information seems to require "\[...\] some additional memory used by the key \[...\]".
> \- Redis uses future absolute Unix timestamps for TTLs; clock needs to be stable and care taken if replicating to other machines with different clocks.
> 
> More info for expires in Redis: https://redis.io/commands/expire

My fix is not a final one and I am pretty sure it can be optimized, but with the fix it is not necessary any more to deal with eviction policies, as redis/keydb now automatically removes the expired records. For everybody interested in the code I have attached the changed files that need to be extracted to the subfolder "cachedb" of the unbound source.

Bye  
[cachedb.zip](https://discourse.pi-hole.net/uploads/short-url/aIjPNO1TnHVnQas3DPCxuQJVtpE.zip) (13.2 KB)

P.S. Source code is based on Unbound 1.9.6  
[Pull Request](https://github.com/NLnetLabs/unbound/pull/206)

---

<div class="post-metadata">

**Author:** ![ctrlbrk](https://discourse-cdn.pi-hole.net/user_avatar/discourse.pi-hole.net/ctrlbrk/32/26708_2.png) [@ctrlbrk](https://discourse.pi-hole.net/u/ctrlbrk)\
**Post date:** [August 12, 2021, 5:32pm UTC](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676/40 "2021-08-12T17:32:15Z")

</div>

I realize this is older, but I am trying to do exactly what you've described.

Could you please help me by showing me your modified KeyDB conf and your relevant Unbound conf settings?

Is there an unbound statistic that can verify the cachedb status?

---

<div class="post-metadata">

**Author:** ![jpgpi250](https://discourse-cdn.pi-hole.net/user_avatar/discourse.pi-hole.net/jpgpi250/32/286_2.png) [@jpgpi250](https://discourse.pi-hole.net/u/jpgpi250)\
**Post date:** [August 12, 2021, 6:48pm UTC](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676/41 "2021-08-12T18:48:14Z")

</div>

The GitHub repository has been removed, since it contained outdated / misleading information. It's impossible to provide the settings you need to use, since a lot of them are hardware dependent. Read [this](https://www.nlnetlabs.nl/documentation/unbound/howto-optimise/) document to find the proper settings for your system.

---

<div class="post-metadata">

**Author:** ![ctrlbrk](https://discourse-cdn.pi-hole.net/user_avatar/discourse.pi-hole.net/ctrlbrk/32/26708_2.png) [@ctrlbrk](https://discourse.pi-hole.net/u/ctrlbrk)\
**Post date:** [August 12, 2021, 7:05pm UTC](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676/42 "2021-08-12T19:05:16Z")

</div>

My question was directed to Talkabout, if you could mention him that would be great as I'm not permitted as a new member

---

<div class="post-metadata">

**Author:** ![Talkabout](https://discourse-cdn.pi-hole.net/letter_avatar_proxy/v4/letter/t/a698b9/32.png) [@Talkabout](https://discourse.pi-hole.net/u/Talkabout)\
**Post date:** [August 12, 2021, 9:44pm UTC](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676/43 "2021-08-12T21:44:03Z")

</div>

Hi @ctrlbrk ,

the fix mentioned in the first post has been merged to the master of unbound and released with version 1.13.0.

On KeyDB side you "only" need to add following lines to each instance:

```auto
active-replica yes
replicaof XXX.XXX.XX.XX 6379

```

The "replicaof" needs to be the IP address of the instance to sync with.

On Unbound side you need to configure:

```auto
cachedb:
        backend: "redis"
        redis-server-host: XXX.XXX.XX.XX
        redis-server-port: 6379
        redis-timeout: 500
        redis-expire-records: yes

```

Important here is that you need to build Unbound with redis and cachedb support. To do so add following arguments to "configure"-command:

```auto
--with-libhiredis --enable-cachedb

```

and install all dependencies.

With this configuration your Unbound instances should put the resolved domains into KeyDB and KeyDB takes care of synching them to all other KeyDB instances.

On Raspbian you can use these command lines after you have checked out Unbound code and navigated into the folder:

```auto
sudo apt-get install -y libhiredis-dev libssl-dev libevent-dev libexpat1-dev bison
./configure --prefix=/usr --sysconfdir=/etc --disable-static --with-libevent --with-libhiredis --enable-cachedb --with-pidfile=/run/unbound.pid
make
sudo make install

```

Hope that helps!

---

<div class="post-metadata">

**Author:** ![MichaIng](https://discourse-cdn.pi-hole.net/user_avatar/discourse.pi-hole.net/michaing/32/13351_2.png) [@MichaIng](https://discourse.pi-hole.net/u/MichaIng)\
**Post date:** [July 27, 2025, 12:10pm UTC](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676/44 "2025-07-27T12:10:07Z")

</div>

Sorry for necroing this thread, the topic came just up our end, and I was wondering about the use case for a secondary Unbound cache in general.

> [@jpgpi250](#):
>
> According to tests, performed by @GieltjE (not sure what method was used to perform the test), it makes the system faster.

Why not adjusting parameters of the primary Unbound cache instead? With `cachedb`, Unbound first checks its own cache, then checks the secondary/external cache, so it naturally is slower, compared to aligning the primary cache parameters.

And with Pi-hole, you do already have an additional cache in front of Unbound, that can again be configured to own needs. Adding Redis hence means 3 caches 🤔.

> [@jpgpi250](#):
>
> pihole-FTL is restarted, and thus clears it's cache

While this is true, we are talking about a _single_ request (per host) that takes a little longer. Is speeding up the very first request of each hostname worth the hassle of setting up a secondary (with Pi-hole tertiary) cache? And Unbound is not regularly restarted, unless some `openresolv` auto-(mis)configuration messes with it, which luckily was removed from Debian's `openresolv` package.

I see, basically @DL6ER asked all that already, looping through the thread I could not find a good answer so far, but also some links are down. Would be interested in hearing some use case 🙂.

In any case, Debian Trixie's Unbound has `cachedb` with Redis backend support builtin. For older Debian versions, we started to compile own packages, currently [here](https://dietpi.com/downloads/binaries/bookworm/testing/) (also available for Bullseye), later in the parent dir, adding them eventually to our APT repository, after some little more time of testing. It is latest upstream Unbound, with `cachedb` and Redis-backend enabled as well. While compiled mainly for DietPi users, it is mostly compatible with the original Debian package. No Python module support though (optionally adding Python scripts into Unbound query and answer processing), and we removed all the `resolvconf` cross-configuration stuff causes Pi-hole users headache:

- No `unbound-resolvconf.service` which forcefully adds Unbound to the local `/etc/resolv.conf`, even that IMO this is not recommended, at least not a default.
- No `/etc/resolvconf/update.d/unbound`, which is even worse, adding all external nameservers from `/etc/resolv.conf` to the Unbound forward zone, effectively disabling recursive resolving and in case allowing to bypass upstream DoT. Same nonsense `openresolv` used to do. It was disabled (missing executable bit) in earlier Debian versions, even explaining in the script why it is a bad idea, but is now enabled and effective by default, no idea why. Someone too keep in mind for the Pi-hole team. Documented way to disable this, and the way it was in earlier Debian versions:

```sh
chmod -x /etc/resolvconf/update.d/unbound

```

[Previous page](https://discourse.pi-hole.net/t/pihole-ftl-unbound-with-cache-db-module-options-redis/24676.md?page=1)
