Data Source=app.witdb

That is a complete connection string. Everything else has a default, and a database that already exists remembers most of it.

The database remembers how it was made

A .witdb records the storage engine, the cache, the journal and the encryption it was created with. When you open it, any setting you did not name is taken from the file.

That has two consequences worth knowing before you write a connection string in a config file.

Omitting a setting is safe. A database created with Cache=lru opens with the LRU cache from Data Source=app.witdb, without you having to repeat it everywhere the database is opened.

Naming a setting the database disagrees with is refused rather than ignored. Opening a Store=lsm database with Store=btree is an error, because silently giving you a different engine than you asked for is worse than failing.

The same applies to the transaction model, and there the failure it prevents was quiet and destructive. The MVCC store keeps every value under a versioned key and no other configuration does, so a database written with MVCC=true, the default, and opened with MVCC=false used to open without complaint and then report every table as missing. The rows were never lost, they were invisible, and the natural next step of creating the schema on what looked like an empty database wrote over one that was intact. Both directions are refused now, naming the setting.

Presence is what counts, not the value. MVCC=true written explicitly is a different thing from leaving MVCC out, even though both end up with MVCC on.

Three settings are never restored from the file: File Locking, Synchronous Commit and Isolation Level. A file may not quietly make a database less durable or less exclusive than the defaults promise, for a caller who said nothing about either, so those have to be asked for every time. Isolation is excluded for a second reason as well: it is a property of a session rather than of the data.

Core

Parameter Values Default
Data Source A path, or :memory: required
Mode ReadWriteCreate, ReadWrite, ReadOnly, Memory ReadWriteCreate
Store btree, lsm, inmemory btree
Connection Timeout Seconds to wait for the database to open 30
Default Timeout Seconds a command runs before it is cancelled 30
Pooling true, false false
Min Pool Size, Max Pool Size Connections held in the pool 1, 100

Data Source points at a file for the B+Tree store and at a directory for LSM.

Mode=ReadWriteCreate creates the database when it is missing, and it is the default. Mode=ReadWrite and Mode=ReadOnly both mean open an existing one, and both fail when the path is not there, naming the mode and pointing at ReadWriteCreate. A mistyped path is an error rather than an empty database.

Connection Timeout is how long to wait for the file lock, not how long to wait for a query. A bounded wait rather than a single attempt is deliberate: restarting a host overlaps the outgoing process with the incoming one, and refusing immediately turns that window into a startup crash. SQLite covers the same window with busy_timeout. Zero means one attempt.

Encryption

Parameter Values Default
Password The password none
Encryption aes-gcm, chacha20-poly1305 aes-gcm when a password is given
Legacy Encryption true, false false
Data Source=secure.witdb;Password=your-password
Data Source=secure.witdb;Encryption=chacha20-poly1305;Password=your-password

A password with no Encryption gets AES-GCM. An Encryption with no password is refused, since it would produce an unencrypted database that looks encrypted in the config file.

Salt and iteration count live in the file rather than in the connection string, so nothing here has to match how the database was created.

Legacy Encryption=true opens a database encrypted before 13.1.0, which the engine otherwise refuses. Use it to get your data out and then change the password, which rewrites the database in the current format. See encryption.

Transactions

Parameter Values Default
Transactions true, false true
MVCC true, false true
Isolation Level ReadUncommitted, ReadCommitted, RepeatableRead, Serializable, Snapshot ReadCommitted
Journal wal, rollback wal
Synchronous Commit true, false true
File Locking true, false true

Synchronous Commit=false moves the moment of durability to somewhere you cannot predict: a process crash is still survivable, a power cut is not. File Locking=false drops the cross-process guard, so a second process can open the same file. Neither is restored from the database, so both have to be written every time you want them.

MVCC=false gives a single-writer database where one transaction holds a database-wide write lock. It is faster when there is genuinely one writer and it takes concurrent transactions away entirely. It also interacts badly with Store=lsm, in the other direction from what you might expect: see storage engines.

Cache and pages

Parameter Values Default
Cache clock, lru clock
Cache Size Pages held in memory 1000
Page Size Bytes per page, a power of two from 512 to 65536 4096

Page Size is fixed when the database is created and cannot be changed afterwards. Cache Size can differ between connections; it is memory, not layout.

Booleans

true, yes, 1 and on all mean true, and false, no, 0 and off all mean false, in any case. A value that is none of those is an error rather than a silent false.

Keywords that no longer exist

Removed What to do
Parallel Mode Remove it. The B+Tree store is always serialised, since it has no locking of its own, and the LSM store locks internally. There is nothing left to choose
Max Writers Remove it. It sized the LSM write buffer, which is no longer selectable from a connection string, and which measured slower through a database anyway because the transaction layer serialises writers before they reach it

Both are rejected with that advice rather than ignored.

Building one in code

csharp
using OutWit.Database.AdoNet;

var builder = new WitDbConnectionStringBuilder
{
    DataSource = "/var/app/data.witdb",
    Password = configuration["Database:Password"],
    CacheSize = 5000,
    IsolationLevel = WitDbIsolationLevel.Snapshot
};

using var connection = new WitDbConnection(builder.ConnectionString);

It parses as well as builds, so an existing string can be read, changed and written back out. Validate() returns the problems it can see without opening anything, which is useful at startup:

csharp
var errors = builder.Validate();

if (errors.Count > 0)
    throw new InvalidOperationException(string.Join("; ", errors));

Some complete ones

// Tests
Data Source=:memory:

// A desktop application's document
Data Source={appData}/MyApp/state.witdb;Password={userPassword}

// Read-heavy, with room to cache
Data Source=analytics.witdb;Mode=ReadOnly;Cache Size=20000;Cache=lru

// A service, snapshot reads
Data Source=/var/app/data.witdb;Password={secret};Isolation Level=Snapshot

Where to go next