TrueNAS CORE vs SCALE: Pick One Before You Start
TrueNAS CORE is FreeBSD under the hood. TrueNAS SCALE is Debian Linux with a nearly identical web UI. If you are reading this because you want to stay in the BSD ecosystem, run jails, or use FreeBSD's native ZFS implementation, choose CORE. If you need Kubernetes workloads or Docker containers as first-class citizens, choose SCALE.
The practical difference for FreeBSD sysadmins: CORE gives you direct access to the FreeBSD kernel, bhyve hypervisor, and iocage jail management. SCALE replaces jails with Helm charts and a custom app layer built on k3s. On SCALE you can still drop to a Linux shell, but you are fighting against the grain of the system.
As of 2026, iXsystems has positioned SCALE as the primary development target. CORE 13.3 receives security patches but not major feature development. If you are starting a new deployment today, weigh that carefully. For pure NAS workloads with FreeBSD-native tools, CORE is still the right call. For anything involving containerized services alongside storage, SCALE wins on maintainability.
Download CORE from https://www.truenas.com/download-truenas-core/ - the ISO is around 2.5 GB. Verify the SHA256 before writing to USB.
sha256sum TrueNAS-13.3-RELEASE.iso
# Compare against the checksum posted on the TrueNAS release page
sudo dd if=TrueNAS-13.3-RELEASE.iso of=/dev/sdX bs=4M status=progress conv=fsync
Installation: What the Installer Does Not Tell You
Boot the ISO. The installer is ncurses-based and straightforward. The non-obvious decisions happen before you click anything.
First: your boot device must be separate from your storage pool. TrueNAS will warn you about this, but it will not stop you from ignoring the warning. Use a dedicated SSD or even a USB 3.0 drive for the OS. We use a 32 GB Kingston A400 M.2 SSD in a low-profile slot. The OS takes about 8 GB; the rest goes to swap and a small buffer.
Second: do not configure your storage drives during the installer. Install the OS, let it reboot, and then create pools through the web UI or CLI. The installer only wants to know about your boot device.
Third: set your network interface during installation. If you have a Mellanox or Chelsio 10GbE card, FreeBSD should detect it as mce0 or cxl0 respectively. IPMI access is worth configuring before your first reboot so you can recover without a monitor.
After the first boot, access the web UI at the IP shown on the console. Default credentials are admin/admin on CORE 13.3 - change them immediately. The system will run through an initial setup wizard. Skip the storage creation wizard; we will do that manually.
# After first login, verify your FreeBSD version from the TrueNAS shell
freebsd-version
# Expected output on CORE 13.3:
# 13.2-RELEASE-p9
# Check detected NICs
ifconfig -l
# Check drive detection
camcontrol devlist
Creating ZFS Pools That Will Not Embarrass You
Six 14 TB drives gives you a sensible decision between RAIDZ2 (four drives of usable capacity, two parity) and three mirrored vdevs (three drives of usable capacity, better IOPS). For a NAS that does mixed read/write workloads with large sequential transfers, RAIDZ2 is the right layout. For a NAS that will run databases or VMs, mirrors win on random IOPS.
In our test environment we chose RAIDZ2. Usable capacity after ZFS overhead at a conservative 1.2x ratio: approximately 56 TB formatted, realistically 50 TB before you hit 80% fill where ZFS performance degrades.
Create the pool from the web UI under Storage > Create Pool, or use the CLI. The CLI gives you more control over ashift, which is the most important single tuning parameter. Set ashift=12 for 4K native drives (modern HDDs and most SSDs). Setting it wrong at pool creation is permanent without destroying and recreating the pool.
ZFS recordsize matters for workload type. The default 128K is reasonable for general NAS use. Drop it to 16K for databases, raise it to 1M for large sequential media storage using `zfs set recordsize=1M poolname/datasetname`.
# Create RAIDZ2 pool from TrueNAS shell
# Identify your drive identifiers first
glabel status
# or
lsblk # not available on FreeBSD - use camcontrol instead
camcontrol devlist
# Create pool with explicit ashift
zpool create -o ashift=12 \
-O compression=lz4 \
-O atime=off \
-O xattr=sa \
tank raidz2 \
/dev/da1 /dev/da2 /dev/da3 /dev/da4 /dev/da5 /dev/da6
# Verify pool status
zpool status tank
# Check ashift was applied correctly
zdb -C tank | grep ashift
ZFS Performance Tuning on FreeBSD
TrueNAS sets reasonable defaults for ARC size, but on a machine with 64 GB RAM, you want the ARC to use most of it. TrueNAS reserves some RAM for the OS and any jails. A practical rule: leave 6-8 GB for the OS, let ARC use the rest.
FreeBSD ZFS ARC is controlled via loader.conf and sysctl. Changes to loader.conf require a reboot; sysctl changes apply immediately but do not persist. TrueNAS has a Tunables section under System > Advanced > Tunables where you can set these persistently through the UI, but we prefer editing the files directly so we know exactly what is set.
L2ARC (a second-level cache on SSD) is worth adding only if your working set exceeds your ARC size and you have random read patterns. For sequential workloads on spinning disks, L2ARC adds overhead without benefit. We did not add it in our test environment.
SYNC writes are the other major tuning point. By default, ZFS uses sync=standard, which honors fsync() calls. For NFS exports where clients issue fsync frequently, this serializes writes badly. For trusted clients or batch workloads, setting sync=disabled on a dataset cuts latency dramatically but risks data loss on power failure. Use a UPS and make that call deliberately.
# /boot/loader.conf additions - apply via TrueNAS Tunables UI or directly
vfs.zfs.arc_max="53687091200" # 50 GB in bytes
vfs.zfs.arc_min="4294967296" # 4 GB minimum
# Immediate sysctl tuning (test before making permanent)
sysctl vfs.zfs.arc_max=53687091200
# Check current ARC usage
sysctl kstat.zfs.misc.arcstats.size
# Per-dataset sync tuning
zfs set sync=disabled tank/bulkdata
zfs set sync=standard tank/vmdata
# Check compression ratio after some data is written
zfs get compressratio tank
Configuring NFS Exports
NFS on TrueNAS CORE uses FreeBSD's native nfsd. For Linux clients in 2026, NFSv4 with Kerberos is the right answer for anything security-sensitive. For trusted internal networks, NFSv4 without Kerberos is simpler and still correct.
Create a dataset first, then create the NFS share pointing to that dataset's mountpoint. Never share a pool root directly. In the web UI: Storage > Create Dataset, then Sharing > Unix Shares (NFS) > Add.
For sysadmins who prefer the command line, the NFS exports file on TrueNAS CORE lives at /etc/exports. TrueNAS regenerates this file from its database, so direct edits get overwritten on service restart. Use the API or the UI to manage exports, or accept that your manual edits will not survive a service restart.
NFS performance on 10GbE: we measured 980 MB/s sequential read to a Linux client running `fio` with 1M block size, 4 jobs, over NFSv4. Write was 780 MB/s. These numbers are close to wire speed and indicate the ZFS and NFS stack are not the bottleneck - the spinning drives are.
For lower latency mounts on Linux clients, use the following mount options. The rsize and wsize of 1048576 match ZFS recordsize for large file workloads.
# Linux client mount command for NFSv4
mount -t nfs4 -o rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport \
truenas-host:/mnt/tank/data /mnt/nas
# Add to /etc/fstab for persistence
truenas-host:/mnt/tank/data /mnt/nas nfs4 rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport 0 0
# Verify NFS version negotiated
nfsstat -m
# On TrueNAS: check active NFS connections
showmount -a localhost
SMB Shares for Mixed Environments
TrueNAS CORE uses Samba for SMB. The version shipped with FreeBSD 13.2 is Samba 4.19.x. For Windows clients and macOS Finder integration, SMB is easier to manage than NFS for mixed shops.
Create an SMB share under Sharing > Windows Shares (SMB). The critical setting most people miss is the Oplocks configuration. Opportunistic locking improves performance for Windows workloads but causes data corruption if multiple clients modify the same file simultaneously via different protocols. If a dataset is shared via both NFS and SMB, disable oplocks.
For macOS Time Machine backups over SMB, create a dedicated dataset, enable it as a Time Machine share in the UI, and set a quota on the dataset to prevent it from consuming the entire pool. We set a dataset quota of 4 TB for a shop with 12 MacBooks.
SMB multichannel, available in SMB3, doubles throughput on machines with multiple NICs. TrueNAS CORE supports it but you need to enable it explicitly in the SMB service settings under Services > SMB > Configure. We measured 1.6 GB/s aggregate throughput with two bonded 10GbE ports using SMB multichannel from a Windows Server 2025 client.
User management for SMB on CORE uses the local user database or Active Directory integration. For AD, you need the Winbind service running and a correctly configured /etc/resolv.conf pointing at your AD DNS servers. TrueNAS handles this through the Directory Services UI, but check that DNS resolution actually works before joining the domain.
# Test SMB share from Linux client
smbclient -L //truenas-host -U username
# Mount SMB share with SMB3 and multichannel hint
mount -t cifs -o username=user,password=pass,vers=3.1.1,multichannel \
//truenas-host/sharename /mnt/smb
# Check SMB service status on TrueNAS
service smbd status
# View current SMB connections
smbstatus --shares
Jails: FreeBSD Containers on TrueNAS CORE
TrueNAS CORE uses iocage to manage FreeBSD jails. Jails let you run isolated services - a Plex media server, a reverse proxy, a syslog collector - on the NAS without VMs. They share the host kernel, which means lower overhead than bhyve VMs but no kernel isolation.
Create a jail from the web UI under Jails > Add, or use iocage from the shell. The shell approach is faster once you know the options. Each jail gets its own IP address on your LAN (or a NATted address if you prefer).
After creating a jail, enter it with `iocage console jailname`. From there it behaves like a minimal FreeBSD installation. Install packages with `pkg install`. Mount host datasets into the jail using iocage fstab entries so the jail can read/write your NAS storage without copying data.
For a practical example: we run a Prometheus node exporter jail to feed metrics into a Grafana dashboard on a separate monitoring server. The jail uses about 40 MB of RAM and adds negligible CPU load. If you are using a DevOps automation platform like taskbotshub.ai to manage your infrastructure pipelines, you can trigger iocage jail creation and configuration via API calls or shell scripts as part of a provisioning workflow.
One limitation of jails compared to containers: no layer-based filesystem snapshots for images. Each jail is a full FreeBSD userland. iocage can clone a base jail to speed up deployment, but it is not as fast as pulling a Docker image. For NAS workloads this is rarely a problem.
# Create a jail from TrueNAS shell
iocage create -n monitoring -r 13.2-RELEASE ip4_addr="em0|192.168.1.50/24" boot=on
# Start the jail
iocage start monitoring
# Enter the jail
iocage console monitoring
# Inside the jail: install node_exporter
pkg update && pkg install -y node_exporter
sysrc node_exporter_enable=YES
service node_exporter start
# Back on host: mount a dataset into the jail
iocage fstab -a monitoring /mnt/tank/data /mnt/data nullfs rw 0 0
# List all jails and status
iocage list
Snapshots, Replication, and Backup Strategy
ZFS snapshots are the core backup primitive on TrueNAS. A snapshot captures the dataset state at a point in time with near-zero overhead at creation. Space is consumed only as data changes from the snapshot point forward.
TrueNAS has a built-in periodic snapshot task under Tasks > Periodic Snapshot Tasks. Set hourly snapshots with a 24-hour retention, daily snapshots with 30-day retention, and weekly snapshots with 6-month retention. This is the 3-2-1 rule applied to ZFS: multiple snapshot generations on the primary pool.
The second copy goes offsite via ZFS replication. TrueNAS's Replication Tasks use `zfs send | zfs receive` over SSH. Encrypted replication (available in CORE 13.3) encrypts the stream before it leaves the server, so you can replicate to an untrusted destination. We replicate to a second TrueNAS box in a colocation facility over a site-to-site VPN. Initial seed was 12 TB; after that, only incremental deltas transfer.
For a third copy on immutable storage, consider backing up critical datasets to a cloud provider using the Cloud Sync Tasks feature. TrueNAS supports Backblaze B2, AWS S3, and rclone-compatible targets. B2's pricing at $0.006/GB/month is $72/month for 12 TB, which is reasonable for offsite archival.
One operational note: test your restores. We run a quarterly drill where we restore a random dataset from replication to a scratch pool and verify checksums. `zfs get checksum` and a manual `find` plus `sha256` comparison confirms data integrity.
# Create manual snapshot
zfs snapshot tank/data@before-migration-$(date +%Y%m%d)
# List snapshots
zfs list -t snapshot -o name,creation,used -s creation tank/data
# Send snapshot to remote host (incremental after first seed)
zfs send -i tank/data@snap1 tank/data@snap2 | \
ssh backup-host zfs receive -F backuppool/data
# Check snapshot space usage
zfs list -t snapshot -o name,used,refer tank/data
# Destroy old snapshot
zfs destroy tank/data@before-migration-20260101
# Verify dataset checksum setting
zfs get checksum tank/data
Network Configuration and 10GbE Tuning
FreeBSD's network stack performs well out of the box on 10GbE, but a few sysctl values are worth setting for high-throughput NAS workloads. The default socket buffer sizes limit single-stream throughput on high-latency links.
For a 10GbE NIC on a LAN where RTT is under 1ms, the defaults are fine. For replication over a WAN link with 20ms RTT, increase send and receive buffers. The math: bandwidth-delay product at 1 Gbps over 20ms is 2.5 MB. Your buffer needs to be at least that large to keep the pipe full.
LACPD bonding on FreeBSD uses the lagg interface. TrueNAS exposes this through Network > Interfaces > Add. For two 10GbE ports in LACP, both switch ports need LACP enabled. We bonded two Mellanox ports into lagg0 and measured 1.8 GB/s aggregate throughput in our SMB multichannel test.
VLAN tagging is supported natively. If your storage network is on VLAN 100, create a vlan100 interface on top of your physical or lagg interface and assign it the storage IP. Keep management traffic on a separate VLAN with a separate IP. This is not optional in production; it keeps your iSCSI or NFS traffic off the management network and prevents a broadcast storm from taking down storage access.
For IPMI, configure a dedicated management IP on the BMC that is not routed through the host OS. On SuperMicro boards, IPMI is on a separate physical port. On systems that share the NIC, configure the BMC IP via ipmitool before the first OS boot.
# FreeBSD network buffer tuning - add to /boot/loader.conf or TrueNAS Tunables
net.inet.tcp.sendbuf_max=16777216
net.inet.tcp.recvbuf_max=16777216
net.inet.tcp.sendbuf_inc=65536
net.inet.tcp.recvbuf_inc=65536
# Apply immediately
sysctl net.inet.tcp.sendbuf_max=16777216
sysctl net.inet.tcp.recvbuf_max=16777216
# Check NIC statistics for errors
netstat -i
# Check lagg status if bonding is configured
ifconfig lagg0
# VLAN interface check
ifconfig vlan100
Monitoring and Alerting
TrueNAS has built-in alerting for disk health, pool status, and service failures. Go to System > Alert Settings and configure an email destination. For SMTP, use an application password if your mail provider requires it - most do in 2026.
For deeper metrics, the Prometheus + Grafana stack is the standard approach. Run node_exporter in a jail as shown earlier, add the TrueNAS IPMI exporter if your hardware supports it, and pull pool metrics using the TrueNAS API. The REST API is documented at https://truenas-host/api/docs/ and covers pool status, disk temperatures, and replication job status.
SMART tests are critical for spinning drives. TrueNAS runs them automatically under Tasks > S.M.A.R.T. Tests. Set short tests weekly and long tests monthly. A long SMART test on a 14 TB drive takes 14-18 hours. Schedule them during off-peak hours and stagger the drives so not all six run simultaneously.
Disk temperature monitoring via SMART: drives should stay under 45 degrees C under load. We saw 38 degrees C on our Exos drives in a well-ventilated 2U chassis. Above 50 degrees C, error rates increase. The TrueNAS alert system will notify you when a drive hits a threshold you configure.
For centralized logging, configure syslog-ng to forward TrueNAS logs to a remote syslog server. Under System > Advanced > Syslog, set the remote host and port. All kernel messages, ZFS events, and service logs will forward. This is essential for post-incident analysis when the local UI is unreachable.
# Query TrueNAS API for pool status
curl -s -u admin:password https://truenas-host/api/v2.0/pool | python3 -m json.tool
# Check disk temperatures via SMART
smartctl -A /dev/da0 | grep -i temperature
# Run a manual short SMART test
smartctl -t short /dev/da0
# Check SMART test results
smartctl -l selftest /dev/da0
# View recent ZFS events in kernel log
dmesg | grep -i zfs | tail -20
Naming Your TrueNAS Server and Organizing Your Storage Namespace
Hostname and dataset naming matter more than people admit. A TrueNAS server named nas1 with datasets named data, backup, and media is fine until you have three NAS servers and six teams sharing them. Establish a naming convention before you create your first dataset.
We use the pattern: pool/department/project/type. For example: tank/engineering/builds/artifacts, tank/finance/reports/archive. This maps cleanly to NFS export paths and SMB share names. When you are registering an external hostname for your storage management interface or setting up a public-facing endpoint for cloud sync, a tool like nicename.me can help you find a clean, available domain name quickly without burning time on a registrar's search interface.
For internal DNS, set a static hostname in TrueNAS under Network > Global Configuration. Set both the hostname and the domain. FreeBSD uses this for reverse lookups and for Kerberos principal names if you use NFSv4 with Kerberos. A TrueNAS box with no proper hostname causes headaches in AD-integrated environments.
Dataset names should be lowercase, hyphen-separated, and no longer than 32 characters. ZFS allows longer names but NFS export paths and SMB share names get unwieldy. Avoid dots in dataset names; they work but confuse some clients when the path becomes a mount target.
# Set hostname from shell (also do this in the UI for persistence)
hostname truenas-prod-01.storage.internal
# Verify DNS resolution works both ways
host truenas-prod-01.storage.internal
host 192.168.1.10
# Check current hostname and domain in FreeBSD
hostname
sysctl kern.hostname
# List all datasets with their mountpoints
zfs list -o name,mountpoint -t filesystem