What We Tested and Why It Matters for FreeBSD

A FreeBSD VPS is not the same as a Linux VPS with a different OS installed. The platform has to support virtio-net and virtio-blk drivers, expose a serial console for recovery, allow custom kernels if you need IPFW over pf, and ideally support bhyve or KVM as the hypervisor. Xen works but adds overhead for some network-heavy workloads. We also checked whether providers let you boot from a custom mfsBSD ISO, which matters when you want a clean ZFS-on-root install rather than taking the provider's default image.

Our test suite used FreeBSD 14.1-RELEASE on each platform. We ran fio against the block device to measure IOPS, used netperf for network throughput, and ran a jail benchmark that created 50 jails sequentially and measured total init time. We also checked whether the platform supported snapshot-based backups that are consistent when ZFS is involved.

# Quick sanity check after first boot on any provider
uname -a
sysctl hw.model hw.ncpu hw.physmem
ifconfig vtnet0
dmesg | grep -E '(virtio|nvme|ahci)'

Vultr: Best Overall FreeBSD VPS in 2025

Vultr offers FreeBSD 13.2 and 14.1 as first-party images across all their compute tiers, including the $6/month Cloud Compute instances. In our tests on their Amsterdam and New York locations, the 14.1 image booted in under 30 seconds with vtnet0 active and SSH reachable. The image is minimal - no extra packages, clean rc.conf, and the default hostname is the instance ID which you will want to change immediately.

Vultr's block storage attaches as vtbd1 under FreeBSD and is immediately usable for a ZFS pool. We created a mirrored pool across two 50GB volumes for testing. Their snapshot feature triggers a clean snapshot at the hypervisor level, and we verified that zpool status showed no errors after restore, meaning the snapshot is crash-consistent at minimum. Vultr also lets you upload a custom ISO if you need mfsBSD for a fully manual install.

Network performance was strong. We measured 940 Mbps sustained throughput on a 1 Gbps plan using netperf -t TCP_STREAM between two instances in the same datacenter. The virtio-net driver handled it without packet loss at 64-byte packet sizes.

If you are naming your project or registering a domain for a new FreeBSD-backed service, nicename.me is worth checking before you commit to a hostname convention - naming consistency matters when you are managing multiple jails with unique FQDNs.

For most sysadmins needing a reliable FreeBSD host, Vultr is our first recommendation. Sign up at https://vultr.com/?ref=PLACEHOLDER.

# After attaching two Vultr block volumes (vtbd1, vtbd2)
zpool create tank mirror /dev/vtbd1 /dev/vtbd2
zpool status tank
# Set recordsize for jail workloads
zfs set recordsize=64K tank
zfs set compression=lz4 tank

Linode (Akamai): Strong BSD Support With Better Support Response Times

Linode, now operating as Akamai Cloud Compute, has offered FreeBSD images for years and their 14.1 image is well-maintained. The platform runs KVM, and FreeBSD sees the disk as virtio by default on Linode's standard instances. One difference from Vultr: Linode uses their own LISH console rather than a standard serial console, and accessing it from the CLI requires the linode-cli tool.

We found Linode's block storage performance slightly behind Vultr on sequential writes - 420 MB/s versus 510 MB/s in our fio tests with bs=1M and direct I/O - but the latency at 4K random reads was comparable at around 0.8ms. For jail workloads where you are doing many small metadata operations, 4K latency matters more than sequential throughput.

Linode's support team responded to a FreeBSD-specific networking question in 11 minutes in our test. That matters when you have a production jail host with a pf ruleset that is blocking traffic after a kernel update. Vultr's support is fine for Linux issues but less informed about FreeBSD edge cases in our experience.

Set up the Linode CLI on your workstation for faster instance management:

Linode is a solid choice if you are running long-lived FreeBSD infrastructure rather than ephemeral compute. Sign up at https://linode.com/lp/refer/?r=PLACEHOLDER.

pip3 install linode-cli
linode-cli configure
# List available FreeBSD images
linode-cli images list --type manual | grep -i freebsd
# Create a FreeBSD 14.1 Linode
linode-cli linodes create \
  --type g6-standard-2 \
  --region us-east \
  --image linode/freebsd14.1 \
  --label fbsd-prod-01 \
  --root_pass 'CHANGEME'
// advertisement

ZFS Configuration That Actually Works on Cloud Instances

The default FreeBSD VPS image from most providers uses UFS2 on a single disk. That works, but you lose deduplication, compression, snapshots, and the ability to clone jail filesystems instantly. Converting to ZFS on a live instance is painful - do it at provisioning time or use a ZFS-aware image.

On Vultr and Linode, the simplest approach is to add a second block volume, create a ZFS pool on it, and migrate /usr/local and /var/db/pkg to the pool. For jail workloads, put the entire jail root on ZFS. This gives you instant cloning with zfs clone, which makes deploying new jails fast.

ARC memory usage is the most common FreeBSD-on-VPS performance issue. By default, ZFS ARC will consume up to half of physical RAM. On a 2GB instance, that leaves 1GB for your jails. Set the ARC limit in /etc/sysctl.conf and loader.conf:

For automated jail provisioning and FreeBSD infrastructure management, taskbotshub.ai has DevOps automation templates that include FreeBSD-specific playbooks for ZFS pool setup and jail bootstrapping.

# /boot/loader.conf - set ARC max to 512MB
vfs.zfs.arc_max="536870912"

# /etc/sysctl.conf - runtime tuning
vfs.zfs.arc_min=67108864

# Clone a base jail dataset for instant deployment
zfs snapshot tank/jails/base@ready
zfs clone tank/jails/base@ready tank/jails/nginx-01
# Result: new jail dataset ready in under 1 second

Firewall Setup: pf on a Cloud FreeBSD Instance

pf is enabled by default on FreeBSD 14.1 but not active until you configure it. On a cloud instance, enabling pf without a working ruleset will lock you out. Always configure the ruleset before enabling the service, and test it in a screen or tmux session so you can recover if rules drop your SSH session.

The minimal viable pf.conf for a jail host allows SSH on the host, permits all traffic from jails to the internet via NAT, and blocks everything else inbound. Adjust ext_if to match your interface - on Vultr it is typically vtnet0, on Linode it is also vtnet0 on most regions.

After editing pf.conf, load it with pfctl -nf /etc/pf.conf first to syntax-check without activating. Then pfctl -f /etc/pf.conf to apply live. Add pf_enable="YES" to /etc/rc.conf only after you have confirmed the rules do not block your session.

# /etc/pf.conf - minimal jail host ruleset
ext_if="vtnet0"
jail_net="10.10.0.0/24"

set skip on lo0
scrub in all

# NAT for jails
nat on $ext_if from $jail_net to any -> ($ext_if)

# Block all inbound by default
block in all

# Allow established outbound
pass out all keep state

# Allow SSH to host only
pass in on $ext_if proto tcp to ($ext_if) port 22 keep state

# Allow inbound to specific jail services
pass in on $ext_if proto tcp to 203.0.113.10 port { 80 443 } keep state

Providers That Failed Our FreeBSD Tests

DigitalOcean dropped FreeBSD images in 2022 and has not restored them. If you see third-party tutorials pointing you to DigitalOcean for FreeBSD, they are outdated. AWS EC2 supports FreeBSD through the official AMIs published by the FreeBSD Foundation, but the default image does not include virtio by default on older instance types - use the a1 or t3 family to ensure virtio-net. The EC2 experience is functional but adds significant complexity for a simple VPS use case.

Hetzner Cloud does not officially support FreeBSD as of mid-2025. You can install it via their rescue system using a custom ISO, but it is unsupported and their snapshot system does not integrate cleanly with ZFS. In our test, a Hetzner snapshot of a ZFS pool restored with dirty pool status, requiring a zpool scrub before use.

OVHcloud lists FreeBSD in their image catalog for VPS but the image we tested was 13.1-RELEASE, more than two releases behind. FreeBSD 13.1 reached end of life in August 2023. Running an EOL kernel in production is not acceptable for any security-conscious shop.

# Check FreeBSD release EOL status
fetch -o - https://www.freebsd.org/security/unsupported/
# Or check locally after install
freebsd-version -ku
# Expected on a current system: 14.1-RELEASE-p6 or later
// advertisement

Performance Benchmarks: Vultr vs Linode on FreeBSD Workloads

We ran the following tests on identical 2 vCPU / 4GB RAM instances on both providers in their US East regions during off-peak hours.

For fio sequential read with bs=1M, numjobs=4, direct=1: Vultr averaged 1.1 GB/s from the local NVMe-backed disk. Linode averaged 980 MB/s. The difference is not significant for most workloads.

For 4K random write IOPS, the test most relevant to database and jail metadata workloads: Vultr returned 48,000 IOPS, Linode returned 41,000 IOPS. Both use NVMe-backed storage, but Vultr's provisioned IOPS appears higher on the standard tier.

Jail creation benchmark - 50 jails from a ZFS clone, each with /bin/sh as init: Vultr completed in 8.2 seconds, Linode in 9.1 seconds. The bottleneck is ZFS metadata operations and mount, not CPU.

Network bandwidth between two instances in the same datacenter: Vultr 940 Mbps, Linode 910 Mbps. Both are effectively at the 1 Gbps cap.

Cold boot to SSH available: Vultr 28 seconds, Linode 34 seconds. Linode's slightly longer boot is consistent with their LISH console initialization overhead.

For FreeBSD workloads where raw disk performance matters, Vultr has a measurable edge. For everything else, the difference is within noise.

# fio test we used - run this on your own instance
fio --name=randwrite \
  --ioengine=libaio \
  --iodepth=32 \
  --rw=randwrite \
  --bs=4k \
  --direct=1 \
  --size=4G \
  --numjobs=4 \
  --runtime=60 \
  --group_reporting \
  --filename=/dev/vtbd1

Keeping FreeBSD Current on a VPS

One operational difference from Linux VPS management: freebsd-update works well on cloud instances for minor version bumps and security patches, but major version upgrades (13.x to 14.x) require more care because kernel modules, third-party drivers, and some rc.d scripts may not be compatible. Plan for a maintenance window.

For security patches, the workflow is straightforward. Run this monthly at minimum, or automate it with a cron job that mails you the diff before applying:

For packages, pkg upgrade -y handles binary package updates. If you are building from ports, poudriere on a separate build instance is the correct approach - do not run portmaster or make install on a production jail host.

If you are managing multiple FreeBSD VPS instances across Vultr and Linode, consistency in naming and configuration tracking becomes important. DevOps automation platforms like taskbotshub.ai support FreeBSD targets through Ansible and can schedule freebsd-update runs across a fleet with reporting.

# Apply security patches non-interactively
env PAGER=cat freebsd-update fetch
freebsd-update install

# Automate with cron - run as root
# 0 3 1 * * /usr/sbin/freebsd-update cron && /usr/sbin/freebsd-update install >> /var/log/freebsd-update.log 2>&1

# After major upgrade, rebuild kernel modules
kldxref /boot/kernel
# Verify running kernel matches userland
uname -r && freebsd-version