The Database Connection¶
What is this?¶
Every model query runs through one Connection object, reachable as db().
It is opened lazily on the first query, kept alive across the request, and
re-opened by itself when the server drops it. This page covers the settings
that shape it. All of them live in z_config/z_settings.ini (see
Booter Settings) and all of them are optional apart from
the credentials.
Endpoint and credentials¶
dbhost = database.example.com
dbport = 3306
dbname = app
dbusername = app
dbpassword = secret
dbhost may also carry the port (host:3306), except with db_ssl
turned on: the server certificate is matched against dbhost as a whole,
and no certificate names a port, so with TLS the port belongs in dbport
and a combined value is rejected with an error saying exactly that.
Migrations connect separately (through Doctrine DBAL) but read the same settings, so there is nothing to configure twice.
Timeouts and retries¶
db_connection_timeout = 900
db_max_retries = 3
db_connection_timeout is the number of seconds after which an idle
connection is checked before being reused.
db_max_retries is how many extra attempts a statement gets when it fails
for a reason that is worth retrying: a deadlock, a lock-wait timeout, a
Galera certification conflict, or a dropped connection (which is recovered
by reconnecting through the endpoint and re-running the statement). Set it
to 0 to disable retries entirely.
One statement may be applied twice
If a write reached the server but the acknowledgment was lost with the
connection, the retry applies it again. Every exec() auto-commits, so
the exposure is a single statement.
Encrypted transport (TLS)¶
Clusters that reject unencrypted clients (MariaDB's
require_secure_transport, or anything reachable over a public network)
need this turned on:
db_ssl = true
That is the whole configuration: the server certificate is verified
against the trust store your system already uses, which knows every
publicly issued certificate (for example Let's Encrypt). A private or
self-signed authority is added to that same store (on Debian: drop it
into /usr/local/share/ca-certificates/ and run
update-ca-certificates), or handed to PHP via openssl.cafile.
The certificate is always verified. That is worth a sentence, because
mysqli itself is lax here: given no authority it encrypts without
verifying, and it never consults the system trust store on its own. The
framework resolves that store for you so that db_ssl = true means
verified, and raises an error rather than connecting unverified when no
trust store can be found.
Persistent connections¶
db_persistent = true
A persistent connection is kept open by the PHP worker after the request ends and handed to the next request, which skips the TCP, TLS and authentication handshake (measured against the e2e cluster: about 2.2 ms per encrypted connect versus 0.2 ms per reuse). It is safe to reuse: mysqli resets the session before handing it over and replaces a connection that no longer answers, so a node that died does not poison the pool.
It is off by default because of placement: a worker stays on whichever node it first reached, so a load-balanced cluster only rebalances as workers recycle. Turn it on where the handshake actually costs you, an encrypted or remote database being the typical case.
Restart your PHP workers after changing db_ssl
mysqli pools connections by host, port, user, password and database,
not by transport, so a worker still holding a plaintext connection
keeps using it after you turn db_ssl on. Reload PHP-FPM (or your web
server) when you change the transport.