How to Place FreeBSD Tunables in sysctl.conf, loader.conf, or rc.conf Correctly
A method for classifying FreeBSD settings by lifecycle so boot tunables, runtime sysctls, service variables, and device hints live in the right file.
FreeBSD exposes settings through several mechanisms that look like name=value, but they execute at different stages. Putting a runtime sysctl in /boot/loader.conf can do nothing or create confusing duplicate state; putting a loader tunable in /etc/sysctl.conf is too late because the kernel already consumed it during initialization.
Start with the owning manual page
Search the installed manuals for the exact variable and note whether it is described as a loader tunable, writable sysctl, read-only statistic, rc.conf variable, device hint, or application setting.
man 7 tuning
man 5 loader.conf
man 5 sysctl.conf
man 5 rc.conf
Do not infer the class from the variable’s punctuation. Many loader tunables later appear as sysctls for observation, but that does not mean they remain writable after boot.
Use loader.conf only before-kernel settings
/boot/loader.conf is read by the loader before it starts the kernel. It is appropriate for kernel modules and tunables that must exist during early kernel initialization:
zfs_load="YES"
kern.geom.label.disk_ident.enable="0"
Those are examples of syntax, not recommendations for every host. Confirm module names and whether the tunable exists on the installed release.
The loader first reads defaults from /boot/defaults/loader.conf; local changes belong in /boot/loader.conf or a deliberately included local file, never in the defaults file. A syntax error or unsafe value can prevent boot, so keep console access and a boot-environment rollback.
At the loader prompt, show and unset can inspect or temporarily remove variables. Record the original boot environment and file before experimenting.
Use sysctl.conf for writable runtime kernel controls
sysctl(8) reads and writes the kernel’s Management Information Base after boot. Test a supported writable value temporarily first:
sysctl net.inet.ip.forwarding
sysctl net.inet.ip.forwarding=1
If the setting behaves correctly and should persist, place it in /etc/sysctl.conf using its documented syntax. Reload only the intended value or use the supported service path; blindly replaying an entire file on a production host can reapply unrelated changes.
Some sysctls are counters or read-only descriptions. Others have dangerous ranges or change semantics between releases. “Writable” means the kernel accepts a value, not that arbitrary tuning improves performance.
Use rc.conf for services and boot orchestration
/etc/rc.conf configures rc.d services and system startup behavior:
sshd_enable="YES"
ifconfig_igb0="DHCP"
Query effective values with sysrc rather than parsing only one file:
sysrc sshd_enable
sysrc -a | less
Defaults come from /etc/defaults/rc.conf, while local overrides may come from /etc/rc.conf, rc.conf.local, or service-specific conventions. Never edit /etc/defaults/rc.conf.
An rc variable may cause a service to set sysctls or load modules, but the variable still belongs to the service contract. Prefer the documented rc knob over duplicating its side effects manually.
Device hints have their own early-boot role
Device hints identify or configure certain drivers during bus enumeration. Current systems often obtain hardware topology automatically, but /boot/device.hints and loader-set hint.* values remain relevant for specific drivers and embedded/legacy hardware. Copying a hint from another machine can misidentify resources or prevent attachment.
Inspect devinfo, boot messages, and the driver manual. Change one hint at a time with a recovery path.
Verify timing, source, and effect
For every setting, record its owner, allowed values, default, stage, reason, measurement, and rollback. After a reboot, verify the effective value with the authoritative interface—sysctl, kldstat, service, sysrc, device attach logs—not just the file contents.
Remove cargo-cult tuning. VM, network, and ZFS parameters often have interacting automatic sizing; an old value copied from a smaller host can reduce performance or stability on a new release. Benchmark the actual workload and keep only changes whose benefit survives repeat testing.
Correct placement is lifecycle engineering: loader settings prepare the kernel, sysctls adjust the running kernel, rc.conf orchestrates services, and application files configure applications. Treating them as interchangeable key-value stores makes both troubleshooting and rollback unreliable.
Related:
- How to Automate FreeBSD Device Events Safely with devd Rules
- How to Replicate FreeBSD ZFS Datasets Safely with send and receive
Sources: