Optimizing OpenBSD performance: adjusting kernel parameters with sysctl and loader.conf, monitoring the system with systat, top, and netstat, and tuning network buffers and pf performance to serve more traffic more reliably.

In episode 18 you ran virtualization on top of OpenBSD. Your system now has a lot of work: firewall, web server, mail, and VMs. The next question that arises: is the system serving all of it efficiently? This episode covers performance and optimization.
OpenBSD is better known for security than for speed — and this is a conscious design decision. But there are many ways to make sure the system uses its resources well: reading the situation with monitoring tools, adjusting kernel parameters with sysctl, and measuring pf performance. Remember the principle: measure first, change little by little, measure again.
Before tuning, you need to know what's happening. The three most important built-in tools:
top
systat cpu
systat netstat
systat vmstattop shows the processes using the most CPU/memory.systat cpu displays CPU usage live.systat netstat shows network traffic per interface.systat vmstat shows memory and swap activity.netstat is also used for connections and statistics:
netstat -rn
netstat -i
netstat -an | grep LISTENnetstat -i shows per-interface statistics — this is where you see dropped packets or errors, an early sign of hardware or configuration problems.
sysctl reads and changes kernel parameters at runtime:
sysctl hw.physmem
sysctl kern.maxproc
sysctl net.inet.tcp.mssdfltTo change temporarily:
sysctl net.inet.tcp.recvspace=65536
sysctl kern.maxfiles=20000To make it permanent, write to /etc/sysctl.conf:
net.inet.tcp.recvspace=65536
net.inet.tcp.sendspace=65536
kern.maxfiles=20000Each line is read at boot. OpenBSD's defaults are already sane — change them only for specific needs, and test the impact.
Warning
Excessive tuning more often hurts than helps. Change one parameter, measure the impact, then continue. If in doubt, leave the default — OpenBSD chooses its defaults for security and stability reasons, not just practicality.
Some parameters can only be set before the kernel boots, via /etc/boot.conf or loader.conf. Example for memory and devices:
set timeout 3For parameters that must be present as the kernel loads (for example bsd.mp), use loader in boot.conf. In practice, most daily tuning is done through sysctl — loader.conf is for very specific cases.
pf is not free. Measure its condition with:
pfctl -s info
pfctl -s rules -v
pfctl -s states | wc -lpfctl -s info shows the number of packets processed, blocked, and evaluation statistics — a picture of the firewall load. pfctl -s states counts active states. If states balloon, check your pass rules and max-src-conn (episode 13).
Buffers determine how much data the kernel can hold before processing. For services serving many connections, raising the TCP buffer size often helps:
net.inet.tcp.recvspace=65536
net.inet.tcp.sendspace=65536
net.inet.tcp.mssdflt=1440
net.inet.tcp.rfc1323=1rfc1323 enables window scaling — important for high throughput on long-distance connections. Start with these values, then watch systat netstat to see whether buffers are filling up.
For queueing and overload protection, OpenBSD provides pf queueing (altq) and max-src-* settings. A simple example of limiting bandwidth:
altq on egress cbq bandwidth 100Mb queue { web }
queue web bandwidth 80Mb
pass out on egress queue webQueues ensure important traffic (for example web) isn't starved by other traffic. This is part of sustainable performance: a firewall that stays stable in a traffic storm.
Practical steps for a server that's starting to feel slow:
top and systat vmstat — who's eating resources?netstat -i for interface errors.pfctl -s info for the firewall load./etc/sysctl.conf if needed.Optimization isn't a numbers race, it's removing real bottlenecks.
Info
If the problem is clearly in one service (for example slow httpd), look at that service's configuration before blaming the kernel. Sometimes the answer is a relayd health check (episode 16) flooding the backend, or a backup (episode 11) running during peak hours.
In episode 19 you optimized OpenBSD: monitoring with top, systat, and netstat, adjusting kernel parameters with sysctl and /etc/sysctl.conf, using loader.conf for boot parameters, and measuring and tuning pf and network buffer performance.
Key takeaways:
top, systat, and netstat before changing anything.sysctl changes parameters at runtime; /etc/sysctl.conf makes them permanent.pfctl -s info is the firewall load dashboard.In the next episode, episode 20, we'll understand -current vs -stable & development — when to use snapshots and stable releases, the syspatch mechanism for security patches, and building the world from source with make build and cvs/git.