Postfix - Early Switching Away From bdb on Debian 13 Trixie

A few days ago, Wietse Venema (author of Postfix) sent an email to the Postfix users mailing list entitled “Automatic migration to non-Berkeley DB” (2026-01-04). A discussion followed on the mailing list, and this triggered me to investigate how this would apply to my mail server - and, inevitably, I tried to re-configure my mail server without using bdb.

The gist: Berkeley DB has already been removed from some of the major Linux distributions. RedHat Enterprise Linux 10, for example, no longer provides bdb, and the version of Postfix on RHEL 10 is built without bdb support. Several smaller distributions have also already made the move. For the countless Postfix installations relying on hash: and btree: database types, this represents a fundamental infrastructure change that will inevitably be coming to all mail server administrators at some point.

Venema outlined an elegant solution for Postfix 3.11: an automatic emulation layer that would transparently migrate databases on-demand, re-indexing them in the background using modern alternatives like CDB or LMDB. The helper daemon would handle the transition seamlessly, with Postfix continuing to work even if administrators ignored the migration reminders.

My current configuration

Of course, having been made aware of this, I had to have a look at whether/where my mail server uses hash: and/or btree:.

BASH
# postconf | grep -E '(hash:|btree:)'
address_verify_map = btree:${data_directory}/verify_cache
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
postscreen_cache_map = btree:${data_directory}/postscreen_cache
postscreen_dnsbl_reply_map = texthash:/etc/postfix/dnsbl_reply
smtp_tls_session_cache_database = btree:${data_directory}/smtp_tls_session_cache
smtpd_sender_login_maps = hash:/etc/postfix/sender_login_maps $virtual_alias_maps
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_tls_session_cache
transport_maps = hash:/etc/postfix/transport
Click to expand and view more

The question then arises which database to use instead of bdb. On the same mailing list, I found two recent discussions on this topic, in which cdb was mentioned, as well as lmdb . Since I am not familiar with either one, I searched online. This basically boiled down to:

LMDB offers superior performance for concurrent, high-write, large-scale scenarios; CDB excels at simple, static lookups.

So, what kind of database usage do I have on my mail server?

From the above postconf output, I can see that there are a couple of static databases (e.g. aliases; updated by me once during server configuration), as well as databases that are updated frequently, incrementally (by Postfix), like the one for postscreen.

For the first set of databases, cdb would be ideal. For the second set, lmdb would be required.

Could I just go with lmdb and call it a day? Definetally! I run a tiny mail server for myself and a few. I doubt using cdb would be measurable.

Still, if I had a larger server, I could configure things as follows (based on the above postconf output):

What Original db type Static OR Incremental Purpose New db type
address_verify_map btree Incremental Caches expensive recipient verification probes lmdb
alias_database hash Static Local email aliases (e.g., root → admin) cdb
alias_maps hash Static Local email aliases lookup cdb
postscreen_cache_map btree Incremental Tracks clients that passed/failed postscreen tests lmdb
smtp_tls_session_cache_database btree Incremental Caches outbound TLS session parameters lmdb
smtpd_sender_login_maps hash Static Maps sender addresses to SASL login names for auth cdb
smtpd_tls_session_cache_database btree Incremental Caches inbound TLS session parameters lmdb
transport_maps hash Static Routes mail to specific transports/destinations cdb

This would then result in the following configuration in /etc/postfix/main.cf (the location of main.cf may be different on your server).

BASH
# postconf  | grep -E '(hash:|btree:|cdb:|lmdb:)'
address_verify_map = lmdb:${data_directory}/verify_cache
alias_database = cdb:/etc/aliases
alias_maps = cdb:/etc/aliases
postscreen_cache_map = lmdb:${data_directory}/postscreen_cache
postscreen_dnsbl_reply_map = texthash:/etc/postfix/dnsbl_reply
smtp_tls_session_cache_database = lmdb:${data_directory}/smtp_tls_session_cache
smtpd_sender_login_maps = cdb:/etc/postfix/sender_login_maps $virtual_alias_maps
smtpd_tls_session_cache_database = lmdb:${data_directory}/smtpd_tls_session_cache
transport_maps = cdb:/etc/postfix/transport
Click to expand and view more

The smtp_tls_session_cache_database and smtpd_tls_session_cache_database are seemingly not really necessary on a small server with little traffic, according to a post by Viktor Dukhovni to the postfix-users mailing list today. So, as I am making the above changes, I am actually commenting out those two databases. I don’t expect I will notice a difference.

Migration Process

The migration involves three steps: converting the databases, updating the configuration, and cleaning up.

Step 1: Convert static databases to CDB

For static lookup tables, use postmap (or postalias for /etc/aliases):

BASH
postalias cdb:/etc/aliases
postmap cdb:/etc/postfix/sender_login_maps
postmap cdb:/etc/postfix/transport
Click to expand and view more

This creates .cdb files alongside your existing .db files.

Step 2: Update main.cf

Edit /etc/postfix/main.cf and change all hash: references to cdb: for static tables, and btree: to lmdb: for dynamic caches (as shown in the table above).

Step 3: Restart and clean up

BASH
postfix stop

# Remove old BDB cache files
rm /var/lib/postfix/postscreen_cache.db
rm /var/lib/postfix/verify_cache.db
rm /var/lib/postfix/smtp_tls_session_cache.db
rm /var/lib/postfix/smtpd_tls_session_cache.db

postfix start
Click to expand and view more

Step 4: Test everything works For the below tests, change the values in italics to something that works for you. For example, look up what you have got in your transport map, and use a corresponding value.

BASH
# Test static lookups
postalias -q _root_ cdb:/etc/aliases
postmap -q _gmail.com_ cdb:/etc/postfix/transport

# Send test email
echo "Migration test" | mail -s "Test" _your@email.address_

# Watch logs
tail -f /var/log/mail.log
Click to expand and view more

Step 5: Clean up old BDB files (after confirming everything works)

BASH
rm /etc/aliases.db
rm /etc/postfix/sender_login_maps.db
rm /etc/postfix/transport.db
Click to expand and view more

Why Migrate Now?

While Postfix 3.11 will handle this migration automatically, there are good reasons to migrate proactively:

  1. Control the timing - Migrate during a maintenance window, not when your distribution forces it
  2. Optimize while you’re at it - Use CDB for static data, LMDB for dynamic (or just LMDB for everything on small servers)
  3. Reduce future surprises - One less thing to worry about when upgrading

For my small mail server, the entire migration took about 15 minutes, including testing. The server has been running smoothly since, with zero Berkeley DB dependencies.

When major distributions inevitably remove Berkeley DB support from their Postfix packages, I’ll already be ahead of the curve. And if you’re reading this, you can be too.

Start searching

Enter keywords to search articles

↑↓
ESC
⌘K Shortcut