Performance tuning parameters
Workload-specific cache, S3, FUSE, writeback, and metadata settings.
Performance settings should be changed as a group and tested against the target
workload. The examples below are YAML for brewfs mount --config; equivalent
BREWFS_* environment variables are used by the benchmark runners.
Start with the safe baseline
This is the recommended starting point for Redis metadata and an S3-compatible data
backend. It keeps the default upload_before_commit write path: after a successful
fsync or close, both object data and metadata are durable and visible.
data:
backend: s3
s3:
bucket: brewfs-data
endpoint: http://127.0.0.1:9000
region: us-east-1
force_path_style: true
disable_payload_checksum: true
part_size: 16777216
max_concurrency: 32
meta:
backend: redis
redis:
url: redis://127.0.0.1:6379/0
open_file_cache_ttl_ms: 30000
open_file_cache_capacity: 65536
allow_write_open_cache: false
cache:
root: /var/cache/brewfs
writeback_mode: upload_before_commit
fuse:
workers: 1
max_background: 512Set cache.root to fast local SSD storage, not a network filesystem. The cache must
have sufficient free space for the configured read and write SSD budgets.
Capacity and parallelism controls
| Setting | Default | Tune it for | Trade-off |
|---|---|---|---|
cache.read_memory_bytes | 4 GiB | Hot reads | Higher resident memory |
cache.read_ssd_bytes | 20 GiB | Larger working sets | More local SSD consumption |
cache.write_memory_bytes | 384 MiB | Bursty writes | Higher memory pressure |
cache.write_ssd_bytes | 20 GiB | Write staging | More local SSD consumption |
cache.memory_budget_bytes | 1280 MiB | Reader/writer buffers | Must fit alongside cache memory |
data.s3.max_concurrency | 32 | Multipart S3 transfers | Can saturate the endpoint or network |
cache.upload_concurrency | 10 | Per-writer upload parallelism | Too high can worsen read tail latency |
fuse.workers | 1 | Concurrent FUSE request handling | More scheduling and CPU overhead |
fuse.max_background | 512 | In-flight FUSE requests | More queued work under overload |
chunk_size defaults to 64 MiB and block_size to 4 MiB. Keep block size aligned
with the workload and object-store behavior; changing either affects object layout and
should be evaluated on a fresh test dataset.
Read-heavy and mixed random I/O
For throughput-oriented reads, the benchmark profile increases cache capacity and
FUSE concurrency. read_direct_io: true prevents large buffered FUSE reads from
being split, but it also disables mmap for the affected read handles.
cache:
root: /var/lib/brewfs/cache
read_memory_bytes: 4294967296
read_ssd_bytes: 4294967296
write_memory_bytes: 4294967296
write_ssd_bytes: 4294967296
memory_budget_bytes: 12884901888
prefetch_enabled: true
prefetch_max_bytes: 67108864
prefetch_concurrency: 64
fuse:
workers: 6
max_background: 512
read_direct_io: trueFor low-latency random reads, test with cache.range_background_prefetch: false as
well. Background full-block fetches can help sequential access, but may compete with
foreground reads on an object store. Compare p95/p99 latency, not only throughput,
before leaving it enabled.
Large writes and S3 writeback
The high-throughput writeback profile commits metadata before asynchronous uploads.
It is only valid with data.backend: s3; it is intentionally not a safe default.
cache:
writeback_mode: commit_before_upload
writeback_persist_sync: false
writeback_require_stage_before_commit: true
writeback_upload_concurrency: 6
upload_concurrency: 32
dirty_slice_target_size: 67108864
dirty_slice_max_age_ms: 2000
writeback_recent_pending_soft_bytes: 2147483648
writeback_recent_pending_hard_bytes: 3221225472
compression: none
verify_cache_checksum: full
fuse:
workers: 6
max_background: 512commit_before_upload can improve write throughput by making the local staging cache
the immediate writeback target. If the process exits unexpectedly or that cache disk
fails before queued objects reach S3, data already published in metadata can be
missing; another client can temporarily observe the missing object. Use it only when
this durability window is acceptable and monitor pending uploads. Keep
upload_before_commit for the normal production durability contract.
compression: none removes compression CPU from benchmark-style large writes. It
trades more network and object-store space for CPU throughput; lz4 remains the
general-purpose default, while zstd favors storage reduction over CPU cost.
Metadata-intensive workloads
The open-file cache avoids repeated attribute and slice lookups. A conservative configuration caches read handles only:
meta:
open_file_cache_ttl_ms: 30000
open_file_cache_capacity: 65536
allow_write_open_cache: falseFor a single-client benchmark or a workload that explicitly accepts weaker cross-client close-to-open freshness, use this short-lived profile:
meta:
open_file_cache_ttl_ms: 1000
open_file_cache_capacity: 65536
allow_write_open_cache: trueDo not enable allow_write_open_cache: true as a blanket multi-client production
optimization. It allows non-append write handles to reuse cached attributes, which can
delay observation of another client's changes.
Read-ahead, cache integrity, and bandwidth
| Setting | Recommended use |
|---|---|
cache.prefetch_enabled | Keep enabled for sequential workloads; A/B test for random I/O. |
cache.prefetch_max_bytes | Default 64 MiB maximum look-ahead; raise only after confirming cache headroom. |
cache.prefetch_concurrency | Default 64; lower it if background I/O affects foreground latency. |
cache.range_background_prefetch | Useful when small range reads have locality; disable to test random-read tail latency. |
cache.populate_write_cache_after_upload | Keeps freshly written blocks available to reads after upload. |
cache.persist_write_cache_after_upload | Persists those blocks to the read-cache disk at the cost of local write I/O. |
cache.verify_cache_checksum | full protects cache integrity; none is a benchmark-only trade-off. |
cache.bandwidth.upload_limit_mibps / download_limit_mibps | Protect a shared network or object store with explicit MiB/s limits. |
Validate every profile
Use a fresh benchmark dataset, drain writeback before cold-read tests, and record the complete configuration alongside the result. Inspect BrewFS statistics for cache hits, background prefetches, pending writeback bytes, and metadata open-cache hit rates. The Benchmark methodology documents the fio profiles and reproducibility rules used for the published numbers.

