# Builder & configuration — design
> **Class:** `design` · **Function:** `builder` · **Constructs:** all functions.
> Only the shape that runs; the *why* is in [`reasoning.md`](reasoning.md).
## f0 — constructing a catalog
`RedbCatalogBuilder` (`builder.rs:82`) implements `iceberg::CatalogBuilder`, so a
catalog is built the standard Iceberg way — `.load(name, props)` — or via typed
setters. It opens (creating parent dirs as needed) the redb file, builds the L0 /
L1.5 caches, and returns a `RedbCatalog`.
```rust
let catalog = RedbCatalogBuilder::default()
.db_path("/var/lib/app/catalog.redb")
.warehouse_location("file:///var/lib/app/warehouse")
.with_storage_factory(Arc::new(LocalFsStorageFactory))
.load("app", HashMap::new())
.await?;
```
## f1 — the configuration surface
Every knob has a typed setter **and** a property key; a `props` entry overrides the
typed field (`builder.rs:161`+). Required: `db_path` and `warehouse_location`
(missing → `DataInvalid`), plus a `StorageFactory` via `with_storage_factory`
(missing → `Unexpected`).
| setter | property key | default | effect |
|---|---|---|---|
| `db_path` | `redb.db-path` | — (required) | the redb file path |
| `warehouse_location` | `warehouse` | — (required) | warehouse root URI |
| `metadata_cache_bytes` | `redb.metadata-cache-bytes` | 128 MiB | L0 budget; `0` disables |
| `table_handle_cache_bytes` | `redb.table-handle-cache-bytes` | 256 MiB | L1.5 byte budget; `0` disables. The deprecated `table_handle_cache_capacity` / `redb.table-handle-cache-capacity` still work, converted to the bytes that handle count could pin in the worst case |
| `durability` | `redb.durability` | `immediate` | `immediate` \| `eventual` \| `none` |
Property keys are public constants (`REDB_CATALOG_PROP_*`, `builder.rs:20`+).
Parse failures on a numeric / enum property surface as `DataInvalid` with the
offending value named.
## f2 — `WriteDurability` (`builder.rs:47`)
| variant | redb mapping | trade-off |
|---|---|---|
| `Immediate` (default) | `Durability::Immediate` | fsync per commit — crash-safe |
| `Eventual` | `Durability::Eventual` | persists shortly after `commit`; higher throughput; may lose the last few commits on a hard crash (db stays consistent) |
| `None` | `Durability::None` | no fsync — fastest; bulk import / bench only (redb only frees pages at higher levels, so exclusive `None` grows the file) |
Applied to every mutation transaction via `set_durability` on the write txn.