FreeBSD 15.0 landed on December 2, 2025, and it changes how you manage the entire operating system. The base system is now a collection of 310 individual packages managed through pkg, the same tool you already use for ports. No more freebsd-update. Alongside that, OpenSSL 3.5 ships with quantum-resistant cryptography, and OpenSSH 10 defaults to post-quantum key exchange on every connection.
We tested every feature shown here on a real FreeBSD 15.0-RELEASE amd64 machine running on Proxmox VE with ZFS 2.4.0. The commands, output, and version numbers are all captured from that system. For features that are architectural (like 32-bit platform retirement), we focus on what it means for your existing workloads rather than just listing the changelog. If you need to install FreeBSD 15 on KVM or Proxmox first, that guide covers the full installer walkthrough.
Tested March 2026 | FreeBSD 15.0-RELEASE amd64, OpenSSL 3.5.4, OpenSSH 10.0p2, ZFS 2.4.0-rc4
What Changed in FreeBSD 15.0
Here is the full picture before we get into the demos:
| Feature | What’s New | Impact |
|---|---|---|
| pkgbase | 310 base system packages manageable via pkg | No more freebsd-update, granular base management |
| OpenSSL 3.5.4 | ML-KEM and ML-DSA post-quantum algorithms | Quantum-resistant TLS available now |
| OpenSSH 10.0p2 | mlkem768x25519-sha256 default key exchange | SSH connections are quantum-safe by default |
| ZFS 2.4.0 | Block cloning, improved performance | Instant file copies on ZFS, lower I/O |
| Jails | File descriptor-based jail operations, service jails | Race-free jail management, easy daemon isolation |
| Linux inotify | Native inotify implementation | Better Linux binary compatibility |
| 32-bit retirement | i386, armv6, 32-bit PowerPC dropped | Cleaner codebase, 32-bit apps still run on amd64 |
| Nanosecond timestamps | date supports %N format | Precise timing in scripts |
| USB HID | usbhid replaces ukbd/ums as default | Better device support out of the box |
| MIT Kerberos | Replaces Heimdal | Better interoperability with Linux/AD environments |
Full details are in the official FreeBSD 15.0 release announcement and release notes.
pkgbase: Manage the Entire Base System with pkg
This is the headline feature. The entire base system (kernel, libraries, utilities, everything that ships with FreeBSD) is now split into approximately 310 individual packages. You manage them with the same pkg tool used for third-party software. No more running freebsd-update fetch install and hoping nothing breaks.
Query the installed base packages:
pkg query -a '%n %v' | grep '^FreeBSD-' | head -20
Every base component shows up as an individual package with its own version:
FreeBSD-acct 15.0
FreeBSD-acpi 15.0
FreeBSD-at 15.0
FreeBSD-atf 15.0
FreeBSD-audit 15.0
FreeBSD-autofs 15.0
FreeBSD-bhyve 15.0
FreeBSD-blocklist 15.0
FreeBSD-bluetooth 15.0
FreeBSD-bmake 15.0
FreeBSD-bootloader 15.0
FreeBSD-bsdconfig 15.0
FreeBSD-bsdinstall 15.0
FreeBSD-bsnmp 15.0
FreeBSD-caroot 15.0
FreeBSD-certctl 15.0
FreeBSD-clibs 15.0
FreeBSD-csh 15.0
FreeBSD-devd 15.0
FreeBSD-devmatch 15.0
The total count on a fresh 15.0 install:
pkg query -a '%n' | grep '^FreeBSD-' | wc -l
310 base packages. You can inspect any of them like you would a ports package:
pkg info FreeBSD-ssh
The SSH package metadata shows origin, license, and install date:
FreeBSD-ssh-15.0
Name : FreeBSD-ssh
Version : 15.0
Installed on : Tue Mar 24 11:18:11 2026 UTC
Origin : base/FreeBSD-ssh
Architecture : FreeBSD:15:amd64
Prefix : /
Categories : base
Licenses : ISCL
Maintainer : [email protected]
Enable pkgbase Updates
The base package repository is disabled by default. Enable it with a one-liner:
mkdir -p /usr/local/etc/pkg/repos
echo 'FreeBSD-base: { enabled: yes }' > /usr/local/etc/pkg/repos/FreeBSD-base.conf
Now check for base system updates:
pkg update -r FreeBSD-base
On our freshly installed system, everything is current:
Updating FreeBSD-base repository catalogue...
FreeBSD-base repository is up to date.
FreeBSD-base is up to date.
When security patches land, updating the base is just pkg upgrade. You can even lock specific base packages with pkg lock FreeBSD-kernel if you need to hold back a kernel update while patching userland.
Post-Quantum Cryptography with OpenSSL 3.5
FreeBSD 15.0 ships OpenSSL 3.5.4 LTS with full support for the NIST post-quantum cryptographic standards: ML-KEM (formerly CRYSTALS-Kyber) for key encapsulation and ML-DSA (formerly CRYSTALS-Dilithium) for digital signatures. These algorithms resist attacks from quantum computers, and they are not behind a feature flag. They are compiled in and ready to use.
Verify the version:
openssl version
Confirmed as 3.5.4 LTS:
OpenSSL 3.5.4 30 Sep 2025 (Library: OpenSSL 3.5.4 30 Sep 2025)
What post-quantum algorithms are available?
Three security levels of ML-KEM and ML-DSA ship out of the box, plus hybrid algorithms that combine classical and post-quantum key exchange. List the KEM algorithms:
openssl list -kem-algorithms
The output shows pure ML-KEM at three security levels and several hybrid options:
SecP384r1MLKEM1024 @ default
{ 1.3.101.110, X25519 } @ default
{ 1.3.101.111, X448 } @ default
{ 2.16.840.1.101.3.4.4.1, id-alg-ml-kem-512, ML-KEM-512, MLKEM512 } @ default
{ 2.16.840.1.101.3.4.4.2, id-alg-ml-kem-768, ML-KEM-768, MLKEM768 } @ default
{ 2.16.840.1.101.3.4.4.3, id-alg-ml-kem-1024, ML-KEM-1024, MLKEM1024 } @ default
X25519MLKEM768 @ default
X448MLKEM1024 @ default
SecP256r1MLKEM768 @ default
The hybrid algorithms (like X25519MLKEM768) combine classical and post-quantum key exchange. Even if ML-KEM turns out to have a weakness, the X25519 component still provides security. This is the belt-and-suspenders approach NIST recommends for the transition period.
Demo: Sign and Verify with ML-DSA-65
Generate a quantum-resistant ML-DSA-65 key pair:
openssl genpkey -algorithm ML-DSA-65 -out /tmp/mldsa65.key
openssl pkey -in /tmp/mldsa65.key -pubout -out /tmp/mldsa65.pub
Lattice-based algorithms need bigger keys to achieve quantum resistance. Compare these sizes to an Ed25519 key (which is 64 bytes):
ls -la /tmp/mldsa65.*
The private key is 5.6 KB, the public key 2.7 KB:
-rw------- 1 root wheel 5604 Mar 25 01:21 /tmp/mldsa65.key
-rw-r--r-- 1 root wheel 2726 Mar 25 01:21 /tmp/mldsa65.pub
Now sign a message and verify the signature:
echo 'Hello FreeBSD 15 with post-quantum crypto' > /tmp/message.txt
openssl pkeyutl -sign -inkey /tmp/mldsa65.key -in /tmp/message.txt -out /tmp/message.sig
openssl pkeyutl -verify -pubin -inkey /tmp/mldsa65.pub -in /tmp/message.txt -sigfile /tmp/message.sig
Verification passes:
Signature Verified Successfully
ML-KEM key generation works the same way:
openssl genpkey -algorithm ML-KEM-768 -out /tmp/mlkem768.key
openssl pkey -in /tmp/mlkem768.key -pubout -out /tmp/mlkem768.pub
openssl pkey -in /tmp/mlkem768.key -text -noout | head -3
The seed is the secret from which the full ML-KEM keypair is derived:
ML-KEM-768 Private-Key:
seed:
a1:4a:bb:13:9f:f0:1f:57:cf:42:63:ea:28:a0:d4:
OpenSSH 10: Quantum-Safe by Default
This one caught our attention. OpenSSH 10.0p2 in FreeBSD 15.0 changed the default key exchange algorithm to mlkem768x25519-sha256, a hybrid post-quantum algorithm. Every SSH connection on a fresh FreeBSD 15 install uses quantum-resistant key exchange without any configuration changes. You do not have to opt in.
ssh -V
OpenSSH 10 with OpenSSL 3.5.4:
OpenSSH_10.0p2, OpenSSL 3.5.4 30 Sep 2025
Check the key exchange algorithms sshd will negotiate, in preference order:
sshd -T | grep kexalgorithms
mlkem768x25519-sha256 sits at the top of the list, meaning it is the first choice for every new connection:
kexalgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,[email protected],curve25519-sha256,[email protected],ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
The fallback chain still includes classical algorithms for compatibility with older clients. If the remote end does not support ML-KEM, the connection gracefully falls back to curve25519-sha256.
OpenSSH 10 also adds automatic keystroke timing obfuscation. When you type in an SSH terminal, the timing between keystrokes can leak information about what you are typing. OpenSSH 10 inserts random padding, making keystroke analysis impractical. Enabled by default, no configuration required.
ZFS 2.4: Block Cloning and Performance
FreeBSD 15.0 ships ZFS 2.4.0 with block cloning enabled by default. When you copy a file on ZFS, the filesystem can reference the same data blocks instead of physically duplicating them. Think of it like how ZFS clones work at the dataset level, but applied to individual files through the copy_file_range() syscall.
Check the ZFS version:
zfs version
Both userland and kernel module report 2.4.0:
zfs-2.4.0-rc4-FreeBSD_g099f69ff5
zfs-kmod-2.4.0-rc4-FreeBSD_g099f69ff5
Confirm block cloning is active on your pool:
zpool get feature@block_cloning zroot
Active and ready:
NAME PROPERTY VALUE SOURCE
zroot feature@block_cloning active local
FreeBSD’s cp command uses copy_file_range() automatically, so block cloning happens transparently. You can monitor how much space it saves:
zpool get bclonesaved,bcloneused,bcloneratio zroot
On our test system with a few jail clones, the ratio is already 2x:
NAME PROPERTY VALUE SOURCE
zroot bclonesaved 100K -
zroot bcloneused 100K -
zroot bcloneratio 2.00x -
A bcloneratio of 2.00x means ZFS references blocks instead of duplicating them, effectively halving the physical space used for copied data. Particularly useful for jail deployments where multiple jails share similar base files.
Jail Improvements in FreeBSD 15
Jails got two upgrades worth knowing about.
File Descriptor-Based Jail Operations
Previous versions identified jails by integer JIDs. The problem: a jail could be destroyed and recreated with the same JID between the time you looked it up and the time you acted on it. Classic TOCTOU race condition. FreeBSD 15 adds jail_set() and jail_get() via file descriptors, plus new syscalls jail_attach_jd() and jail_remove_jd(). Kevent filters can now track jail lifecycle events (creation, changes, removal) without polling.
Service Jails
Service jails confine individual daemons with minimal configuration. Instead of building a full jail with a separate filesystem, a service jail shares the host’s filesystem and isolates only the process. Configure it directly in rc.conf:
sysrc nginx_svcj="YES"
That single line runs Nginx inside a jail the next time the service starts. No separate root filesystem, no jail.conf entry, no epair interfaces. Service jails are ideal for quick isolation of internet-facing daemons.
For full VNET jail networking with bridge and epair interfaces (where each jail gets its own IP and network stack), see our FreeBSD Jails VNET networking guide.
Nanosecond Precision in date
The date command now supports the %N format specifier for nanosecond precision. Sounds minor, but it matters for log correlation, benchmarking, and any script that needs sub-second timing.
date '+%Y-%m-%d %H:%M:%S.%N'
Nine digits of sub-second precision:
2026-03-25 01:21:15.266045940
Unix epoch with nanoseconds:
date '+%s.%N'
Useful for timing operations in shell scripts:
1774401675.266958911
On FreeBSD 14 and earlier, %N produced a literal N character. No error, just wrong output. Worth checking if you have scripts that were already trying to use it.
Linux Compatibility: Native inotify
FreeBSD’s Linux compatibility layer (Linuxulator) now includes a native inotify implementation. Linux applications that monitor filesystem changes using inotify can now run on FreeBSD without workarounds or patches. This matters for tools like Node.js file watchers, Docker builds, and any Linux binary that relies on inotifywait.
Load the Linux compatibility module and check the emulated kernel version:
kldload linux64
sysctl compat.linux.osrelease
The Linuxulator reports Linux kernel 5.15.0 to applications:
compat.linux.osrelease: 5.15.0
That version is high enough for most Linux binaries that check for minimum kernel versions.
USB HID as the Default Input Driver
FreeBSD 15 enables usbhid by default, replacing the older ukbd (keyboard), ums (mouse), and uhid (generic HID) drivers. The new driver handles keyboards, mice, touchpads, game controllers, digitizers, and compound devices through a single unified stack.
sysctl hw.usb.usbhid.enable
Enabled by default on fresh installs:
hw.usb.usbhid.enable: 1
If you have custom configurations referencing ukbd or ums in /boot/loader.conf, those still work but are redundant on 15.0.
32-Bit Platform Retirement
FreeBSD 15 drops i386, armv6, and 32-bit PowerPC as hardware platforms. The armv7 platform remains as the last supported 32-bit architecture. The practical impact for most people: none. 32-bit application support continues on amd64 through the compatibility layer:
sysctl kern.features.compat_freebsd_32bit
Still available:
kern.features.compat_freebsd_32bit: 1
Existing 32-bit applications and libraries still run. What changed is that FreeBSD no longer builds or ships installation media for 32-bit only hardware. If you are still running i386 servers, FreeBSD 14 is your last stop.
Other Notable Changes
Kerberos Migration to MIT
FreeBSD 15 ships MIT Kerberos 1.22.1, replacing the Heimdal 1.5.2 implementation that FreeBSD has used for decades. MIT Kerberos has better interoperability with Active Directory and Linux environments. Heimdal will be fully removed in FreeBSD 16, so start migrating any Heimdal-specific configurations now.
NVMe over Fabrics
NVMe-oF support via TCP transport is new in 15.0. Remote NVMe controllers can be accessed as if they were locally attached, with export support through the CAM target layer. This enables disaggregated storage architectures where compute and storage nodes communicate over standard Ethernet.
Networking Improvements
- NFSv4.2 Clone operation for copy-on-write file operations on ZFS (server-side copies without data transfer)
- iwx driver for Intel Wi-Fi 6 M.2 adapters, plus stability fixes to
iwlwifi - ice driver for Intel E800 series 100Gb/s Ethernet controllers
- NFS privileged port enforcement now on by default (
nfs_reserved_port_only)
Deprecated and Removed Features
| Item | Status | Alternative |
|---|---|---|
ftpd | Removed | Use vsftpd or sftp from ports |
fdisk | Deprecated (shows migration warning) | Use gpart |
| GEOM Vinum | Removed | Use ZFS or GEOM mirror/stripe |
agp driver | Deprecated for removal in 16.0 | Modern GPUs don’t use AGP |
firewire driver | Deprecated for removal in 16.0 | USB/Thunderbolt |
readdir_r() | Deprecated with compile-time warnings | Use readdir() (thread-safe in FreeBSD) |
FreeBSD 15 Support Timeline
FreeBSD has moved to a new release cadence with quarterly point releases:
- FreeBSD 15.0: released December 2, 2025, supported until September 30, 2026
- FreeBSD 15.1: scheduled for June 2026
- FreeBSD 15.2: scheduled for December 2026
- 15.x series end-of-life: December 31, 2029
Four years of security updates for the 15.x series. Point releases bring new features, while the major version guarantees ABI compatibility.
Upgrading from FreeBSD 14
If you are running FreeBSD 14, the upgrade uses freebsd-update one last time. After that, pkgbase takes over:
freebsd-update -r 15.0-RELEASE upgrade
freebsd-update install
reboot
freebsd-update install
Our FreeBSD 14 to 15 upgrade guide covers the complete process including gotchas like the Heimdal to MIT Kerberos migration. For fresh installations, the FreeBSD 15 installation guide on KVM and Proxmox walks through the entire installer and post-install setup.