SSD Nodes Learn 🎉 VPS vanaf $5.50/mnd
Gidsen Matt ConnorDoor Matt Connor · Bijgewerkt 2026-08-13

ZFS op VPS: hoeveel RAM heeft OpenZFS echt nodig?

ZFS biedt checksums en snapshots, maar de ARC verbruikt veel RAM. Ontdek hoe u het geheugengebruik op een VPS met 2 GB of 4 GB beperkt zonder de prestaties te schaden.

Wat ZFS u biedt, en wat het vereist

ZFS op FreeBSD en Linux is nu één codebase, OpenZFS, waardoor de functionaliteiten op beide systemen identiek zijn. Een server die ZFS draait, beschikt over data met checksums, snapshots die geen ruimte innemen totdat data wijzigt, replicatie met zfs send, en compressie die met slechts één eigenschap in te schakelen is. Wat het vereist is geheugen: de ARC (adaptive replacement cache) claimt standaard een groot deel van het RAM-geheugen, en op een VPS (virtual private server) van 2 GB of 4 GB is dat precies het geheugen dat uw applicatie nodig had.

Deze handleiding beoordeelt ZFS vanuit het perspectief van een gehuurde VPS met één of twee virtuele schijven, niet vanuit een opslagserver met veertig schijfposities. De functies die in deze context bruikbaar blijven, zijn de functies die uw tijd waard zijn. De onderdelen die hier niet geschikt voor zijn, is het waard om te kennen voordat u een pool aanmaakt.

OpenZFS op FreeBSD en Linux: één codebase, twee verpakkingsstrategieën

FreeBSD bevat ZFS in het basissysteem sinds FreeBSD 7.0 in 2008, aanvankelijk als experimentele functie. Sinds OpenZFS 2.0 in december 2020 bouwen FreeBSD en Linux vanuit dezelfde broncode, waardoor zfs en zpool zich op beide systemen identiek gedragen en een pool die op het ene systeem is aangemaakt, op het andere kan worden geïmporteerd.

De reden dat ZFS op Linux een pakket is en op FreeBSD deel uitmaakt van het basissysteem, is de licentievorm. OpenZFS valt onder de CDDL (Common Development and Distribution License). De Linux-kernel valt onder de GPL (General Public License) versie 2. Het kernelproject beschouwt deze twee als incompatibel, waardoor de ZFS-code niet wordt samengevoegd met de mainline Linux-kernel en elke distributie zelf beslist hoe deze wordt aangeboden. FreeBSD heeft dit conflict niet, waardoor ZFS simpelweg aanwezig is. Dat is het hele praktische verhaal: één verschil in verpakking, waar u geen partij in hoeft te kiezen.

SSD Nodes biedt geen FreeBSD-images aan, dus op een hier gehuurde server is het Linux-gedeelte van deze handleiding van toepassing. Als u elders FreeBSD draait, krijgt u via een FreeBSD-server ZFS zonder dat er een module gebouwd hoeft te worden of een kernel-upgrade overleefd moet worden.

ZFS installeren en een pool aanmaken

Op Ubuntu zit de module in de kernelpakketten, dus u installeert alleen de commando's.

sudo apt update
sudo apt install -y zfsutils-linux
zfs version

zfs version toont twee regels: de versie van de userland-tools en de versie van de kernelmodule. Als er slechts één regel verschijnt, is de module niet geladen. Het pakket bevindt zich in de universe-component, die standaard is ingeschakeld in Ubuntu-serverimages; als apt het pakket niet kan vinden, voer dan eerst sudo add-apt-repository universe uit.

Op Debian bevinden de pakketten zich in de contrib-component en wordt de module op uw machine gebouwd via DKMS (dynamic kernel module support). Voeg contrib toe aan de Components:-regel in /etc/apt/sources.list.d/debian.sources, voer sudo apt update uit en vervolgens:

sudo apt install -y linux-headers-$(dpkg --print-architecture) zfs-dkms zfsutils-linux

De installatie compileert de module en geeft Building initial module for 6.12.0-... weer; dit duurt enkele minuten. Houd er rekening mee dat elke kernel-upgrade de module opnieuw bouwt. Als het bouwen mislukt, blijft uw pool niet-geïmporteerd totdat u het probleem verhelpt.

Op FreeBSD hoeft niets te worden geïnstalleerd. Schakel de service in en start deze.

sysrc zfs_enable=YES
service zfs start

Nu de pool. Bekijk eerst de stabiele apparaatpaden, omdat /dev/vdb wordt toegewezen op basis van de volgorde van detectie en kan veranderen wanneer u een ander volume aansluit.

ls -l /dev/disk/by-id/
sudo zpool create -o ashift=12 tank /dev/disk/by-id/virtio-abc123def456
zpool status tank

zpool status hoort state: ONLINE weer te geven met uw apparaat vermeld onder tank. ashift=12 stelt de kleinste block-grootte van de pool in op 4 KiB; dit komt overeen met moderne SSD's en kan na creatie niet meer worden gewijzigd.

De meeste gehuurde images booten vanaf een ext4-rootpartitie, dus ZFS is hier een datapool op een tweede volume in plaats van het root-bestandssysteem. Controleer of het apparaat inderdaad het juiste is voordat u erop bouwt, want het bevestigen van de NVMe-schijf die u heeft gekocht kost één minuut, terwijl een rebuild een hele middag in beslag neemt.

Checksums herstellen alleen bij een pool met redundantie

Elk blok dat ZFS schrijft bevat een checksum, en elke leesactie verifieert deze. Detectie werkt altijd. Herstel vereist een tweede kopie.

Bij een pool met één schijf vertelt ZFS u de waarheid en stopt daar. zpool status -v rapporteert dit als volgt:

status: One or more devices has experienced an error resulting in data
        corruption.
action: Restore the file in question if possible.  Otherwise restore the
        entire pool from backup.
errors: Permanent errors have been detected in the following files:

        /tank/data/archive.tar

Het beschadigde bestand wordt benoemd. ext4 zou die bytes zonder opmerkingen hebben teruggegeven, dus dit is al waardevol. ZFS kan het echter niet repareren, omdat er geen tweede kopie in de pool aanwezig is om het vanaf te herstellen.

Bij een mirror wordt dezelfde leesactie uitgevoerd vanaf de goede kant, het slechte blok wordt overschreven en de gebeurtenis verschijnt in de CKSUM-kolom van zpool status. Dat is zelfherstel, en daarvoor zijn twee apparaten nodig.

sudo zpool create -o ashift=12 tank mirror /dev/disk/by-id/DISK1 /dev/disk/by-id/DISK2

Op een VPS is de opslag van de host meestal al redundant, vaak RAID 10 onder de hypervisor. Dat beschermt u tegen een defecte schijf. Het vertelt u echter niet wanneer een blok foutief is teruggekomen, omdat de array niet kan weten welke kopie correct is. ZFS weet dit wel, omdat het de data vergelijkt met een checksum die het zelf heeft geschreven.

Als u één virtuele schijf heeft en enige herstelmogelijkheid wilt, slaat sudo zfs set copies=2 tank/important twee kopieën van elk blok van die dataset op dezelfde schijf op. Dit verdubbelt de ruimte die de dataset gebruikt, het overleeft een slecht blok, maar het doet niets wanneer het volledige volume verdwijnt.

Een scrub leest alles in de pool en verifieert het.

sudo zpool scrub tank
zpool status tank

Een gezonde pool eindigt met een regel zoals scan: scrub repaired 0B in 00:04:11 with 0 errors. Plan dit in; maandelijks is prima voor een kleine pool.

systemctl list-unit-files 'zfs-scrub*'
sudo systemctl enable --now zfs-scrub-monthly@tank.timer

Datasets zijn de eenheid van beleid

Een dataset is een bestandssysteem binnen de pool. Het aanmaken hiervan is goedkoop, dus maak er een aan per taak. Eigenschappen worden overgeërfd vanaf de pool, wat betekent dat u een standaardwaarde eenmaal instelt en deze alleen overschrijft waar nodig.

sudo zfs create tank/data
sudo zfs create tank/pg
sudo zfs set compression=lz4 tank
sudo zfs set atime=off tank
sudo zfs set quota=20G tank/data
sudo zfs set recordsize=16K tank/pg
zfs get -r compression,compressratio,quota tank

Compressie is de eigenschap die mensen uit voorzorg vaak uitschakelen, maar dat is onverstandig. lz4 kost een kleine hoeveelheid CPU en vermindert het aantal bytes dat naar de schijf moet worden geschreven. Bij comprimeerbare data zorgt dit er daarom meestal voor dat lees- en schrijfacties sneller verlopen. zstd comprimeert sterker ten koste van meer CPU-gebruik, wat geschikt is voor logs en archieven die u zelden raadpleegt. Controleer wat u daadwerkelijk bereikt met zfs get compressratio tank en onthoud dat de ratio alleen geldt voor data die is geschreven nadat de eigenschap is ingesteld.

recordsize is het grootste blok dat een dataset schrijft, standaard 128K. Een database die 8 KiB-pagina's schrijft naar 128 KiB-records, verandert één kleine schrijfactie in het lezen van het volledige record, een wijziging en een terugschrijfactie. Stel recordsize=16K in op de database-dataset voordat u de data laadt, omdat de eigenschap alleen van toepassing is op nieuw geschreven blokken.

quota is de manier om te voorkomen dat één dataset de pool volledig vult. Een ZFS-pool die bijna 100% vol is, wordt traag en is lastig op te schonen; houd daarom bewust wat vrije ruimte over.

Snapshots kosten niets totdat gegevens wijzigen

ZFS overschrijft nooit een live blok. Het schrijft een nieuw blok en werkt de pointers bij; dit is wat copy-on-write betekent. Een snapshot is een notitie die zegt: "bewaar de blokken waar deze dataset op dit moment naar verwijst". Het maken ervan is daarom direct en kosteloos.

sudo zfs snapshot tank/data@2026-08-11
zfs list -t snapshot -o name,used,refer -r tank/data

De kolom USED voor een snapshot is de ruimte die uitsluitend door die snapshot wordt bezet. Deze begint bij bijna nul en groeit naarmate u gegevens wijzigt of verwijdert, omdat de oude blokken niet langer kunnen worden vrijgegeven.

Het terughalen van een bestand vereist geen herstelstap.

ls /tank/data/.zfs/snapshot/
cp /tank/data/.zfs/snapshot/2026-08-11/notes.txt /tank/data/notes.txt

De map .zfs is zelfs verborgen voor ls -a totdat u sudo zfs set snapdir=visible tank/data uitvoert. Maak de snapshot voordat u deze nodig heeft, want zonder snapshot leidt een verkeerd rm -rf-commando u naar het ext4-hersteltraject, dat begint met het ontkoppelen van de schijf en daarna alleen maar ingewikkelder wordt.

Een rollback gooit alles weg wat na de snapshot is geschreven.

sudo zfs rollback tank/data@2026-08-11

Het systeem weigert dit als er nieuwere snapshots bestaan, en -r vernietigt die nieuwere snapshots om door te gaan. Controleer de naam van de dataset twee keer voordat u op enter drukt.

Een snapshot is geen back-up. Deze bevindt zich in dezelfde pool, op hetzelfde volume, op dezelfde server. Een defect volume of een zpool destroy neemt de snapshots mee samen met de gegevens. Snapshots beschermen u tegen uw eigen rm en tegen een mislukte upgrade, wat een groot deel van de werkelijke incidenten dekt, maar ze bieden geen bescherming tegen gebeurtenissen die de pool zelf treffen. De volledige onderbouwing vindt u hier: waarom een VPS-snapshot geen back-up is.

Verzenden en ontvangen: replicatie in één commando

zfs send zet een snapshot om in een bytestream op de standaarduitvoer, en zfs receive zet die stream weer terug naar een dataset. De eerste kopie is een volledige verzending (full send).

sudo zfs snapshot tank/data@daily-2026-08-11
sudo zfs send tank/data@daily-2026-08-11 | ssh backup.example.com "sudo zfs recv -F backup/data"

Verzend daarna alleen de wijzigingen tussen twee snapshots.

sudo zfs snapshot tank/data@daily-2026-08-12
sudo zfs send -i tank/data@daily-2026-08-11 tank/data@daily-2026-08-12 | ssh backup.example.com "sudo zfs recv backup/data"

De ontvangende kant moet nog steeds beschikken over het snapshot van waaruit u verzendt. Wanneer dit niet het geval is, stopt de ontvangst met cannot receive incremental stream: most recent snapshot of backup/data does not match incremental source, omdat ZFS geen basis heeft om het verschil op toe te passen. Verzend vanaf een snapshot dat beide kanten bezitten, of begin opnieuw met een volledige verzending.

Verleen rechten op de doelserver in plaats van remote root te gebruiken: sudo zfs allow -u backupuser create,mount,receive backup/data.

Dit is een echte off-site back-up met één voorwaarde. De ontvangende kant moet een ZFS-pool zijn, aangezien object storage geen stream kan ontvangen. Wanneer uw doel S3-compatibele opslag of een standaard Linux-host is, gebruik dan een tool die daarmee communiceert, en restic back-ups vanaf een VPS behandelt die methode.

Waarom gebruikt ZFS zoveel RAM? De ARC

De ARC (adaptive replacement cache) is de read-cache van ZFS. Deze bevindt zich in het kernelgeheugen in plaats van in de normale Linux page cache, waardoor free -h deze niet rapporteert onder buff/cache. Het wordt weergegeven als in gebruik zijnd geheugen. Een ZFS-server die bijna vol lijkt, heeft meestal een warme cache; dit verklaart de meeste meldingen over "ZFS heeft mijn RAM opgegeten".

De standaardlimiet is bewust ruim gekozen. OpenZFS 2.3 stelt de maximale ARC-grootte in op het grootste van de twee waarden: RAM minus 1 GiB of 5/8 van het RAM. OpenZFS 2.2 en ouder gebruikten op Linux de helft van het RAM, terwijl FreeBSD de nieuwere regel al hanteerde. Voer zfs version uit om te zien welke regel voor u van toepassing is.

ChartDefault maximum ARC size by instance RAM, from the OpenZFS default rule (GiB)
The data behind this chart
[
  {
    "label": "2 GB VPS",
    "openzfs_2_2_linux_gib": 1,
    "openzfs_2_3_gib": 1.25
  },
  {
    "label": "4 GB VPS",
    "openzfs_2_2_linux_gib": 2,
    "openzfs_2_3_gib": 3
  },
  {
    "label": "8 GB VPS",
    "openzfs_2_2_linux_gib": 4,
    "openzfs_2_3_gib": 7
  },
  {
    "label": "16 GB VPS",
    "openzfs_2_2_linux_gib": 8,
    "openzfs_2_3_gib": 15
  }
]

Deze cijfers zijn de gedocumenteerde standaardregels voor gangbare instance-groottes, geen metingen van een draaiende server. Op een 4 GB instance staat de 2.3-regel een ARC toe van 3 GiB. Dezelfde server op 2.2 stopt bij 2 GiB. Een 2 GB instance onder de 2.3-regel staat nog steeds 1.25 GiB toe. Uw applicatie krijgt wat er overblijft.

Lees de werkelijke getallen af van uw eigen server in plaats van op de tabel te vertrouwen:

grep -E '^(size|c_max) ' /proc/spl/kstat/zfs/arcstats
arc_summary | head -n 20

De derde kolom bevat bytes. c_max is het momenteel geldende maximum en size is de huidige omvang van de ARC.

De ARC geeft geheugen wel degelijk vrij. De kernel signaleert geheugendruk en de ARC krimpt. Het probleem is de timing, omdat de krimp wordt aangestuurd door die druk. Een proces dat in één keer enkele honderden MiB aanvraagt, kan daarom de OOM (out of memory) killer tegenkomen terwijl de ARC nog bezig is met vrijgeven. Op een 2 GB server die een database en een webserver draait, is dat geen zeldzaamheid. De OpenZFS-handleiding stelt hetzelfde over handmatige wijzigingen: het verlagen van de limiet "zal de ARC niet doen krimpen zonder dat geheugendruk de krimp induceert".

De ARC beperken op een kleine VPS

Bepaal eerst het geheugengebruik van de workload. Tel op wat de database en de applicatie nodig hebben, houd een marge aan voor het besturingssysteem en wijs de rest toe aan de ARC. Op een 4 GB instance met Postgres en één webapplicatie is 512 MiB tot 1 GiB aan ARC een verstandig uitgangspunt.

Stel de limiet live in, in bytes. Dit voorbeeld is voor 1 GiB.

echo 1073741824 | sudo tee /sys/module/zfs/parameters/zfs_arc_max

Zorg dat de instelling een herstart overleeft.

echo 'options zfs zfs_arc_max=1073741824' | sudo tee /etc/modprobe.d/zfs.conf
sudo update-initramfs -u

De stap met initramfs is van belang omdat de module kan laden vanuit de initramfs voordat het root-bestandssysteem is aangekoppeld; in dat geval zou het bestand dat u zojuist heeft aangemaakt niet worden ingelezen. Controleer na de herstart met de c_max regel uit arcstats.

Er zijn twee kanttekeningen uit de handleiding zelf. U kunt de waarde niet terugzetten naar 0 terwijl het systeem draait; dit ongedaan maken vereist het bewerken van het bestand en een herstart. Daarnaast zorgt het verlagen van het getal er niet voor dat een grote ARC direct krimpt.

Op FreeBSD is dezelfde limiet een sysctl onder vfs.zfs.arc. Voer sysctl vfs.zfs.arc uit om de huidige waarden en de exacte naam die uw versie gebruikt te zien, en schrijf vervolgens het maximum naar /boot/loader.conf.

Nog twee geheugenregels voor een kleine server. Laat deduplicatie uitgeschakeld, omdat de dedup-tabel in het geheugen leeft en de algemeen gehanteerde vuistregel 1 tot 3 GB RAM per TB aan unieke data is. Plaats swap bovendien niet op een zvol (een block device dat uit de pool is gesneden), omdat swappen via het bestandssysteem dat probeert geheugen vrij te maken tot een deadlock van de machine kan leiden. Houd swap op een standaard partitie of een swap-bestand buiten de pool.

Wanneer ext4 of XFS in combinatie met restic de betere keuze is

ZFS bewijst zijn waarde op een server met voldoende werkgeheugen en een tweede volume. Buiten die scenario's is een standaard bestandssysteem in combinatie met een volwaardige back-uptool de betere optie. Kies voor ext4 of XFS wanneer:

  • De instantie over 2 GB of 4 GB RAM beschikt en de werklast al het geheugen vereist.
  • Er slechts één virtuele schijf aanwezig is zonder tweede kopie, waardoor ZFS wel corruptie detecteert, maar niet kan herstellen.
  • Uw back-updoel object storage of een standaard Linux-host is, waardoor de bestemming geen zfs send-stream kan ontvangen.
  • U Debian met DKMS gebruikt en u zich geen kernel-upgrade kunt veroorloven waarbij de module niet wordt gecompileerd.
  • U ZFS op het root-bestandssysteem nodig heeft, maar de images van de provider alleen ext4 ondersteunen.

Blijf ZFS gebruiken wanneer u een apart datavolume heeft, over extra werkgeheugen beschikt (8 GB en meer is comfortabel) en een plan heeft voor het gebruik van snapshots en zfs send, in plaats van ze alleen in te schakelen. Voor alle andere gevallen biedt ext4 in combinatie met restic, dat versleutelde en gededupliceerde back-ups schrijft naar opslag die niet door de server zelf wordt beheerd, vrijwel dezelfde voordelen zonder het hoge geheugengebruik.

Foutmodi en de bijbehorende meldingen

De pool is verdwenen na een herstart. zpool status geeft no pools available weer. De import-service leest /etc/zfs/zpool.cache; een pool die niet in dat bestand staat, wordt bij het opstarten niet geïmporteerd. sudo zpool import toont wat er geïmporteerd kan worden, sudo zpool import tank herstelt de pool en sudo zpool set cachefile=/etc/zfs/zpool.cache tank zorgt dat dit behouden blijft. Een pool die niet correct is geëxporteerd vanaf een ander systeem geeft de melding cannot import 'tank': pool may be in use from other system; sudo zpool import -f tank forceert de import zodra u zeker weet dat geen andere host de pool gebruikt.

modprobe: FATAL: Module zfs not found in directory /lib/modules/6.12.0-... op Debian na een kernel-upgrade. DKMS is niet gebouwd voor de nieuwe kernel, meestal omdat de bijbehorende headers niet zijn geïnstalleerd. dkms status toont wat er voor welke kernel is gebouwd. sudo apt install -y linux-headers-$(uname -r) gevolgd door sudo dkms autoinstall herbouwt de module en sudo zpool import tank herstelt de pool.

De pool is vol, maar u heeft bestanden verwijderd. Verwijderde data blijft op de schijf staan zolang een snapshot ernaar verwijst, waardoor du en df verschillende waarden tonen. zfs list -o space -r tank splitst het gebruik in USEDDS en USEDSNAP; een hoge waarde bij USEDSNAP is de oorzaak. Verwijder de oude snapshots met sudo zfs destroy tank/data@2026-06-01 om de ruimte vrij te maken.

CKSUM-tellers lopen op in zpool status. Een component onder ZFS heeft corrupte data geretourneerd. Bij een mirror is de teller een waarschuwing en is het blok hersteld. Bij een pool met één schijf is het bestand verloren; zpool status -v toont de naam van het bestand. U dient dit specifieke bestand terug te zetten vanaf een back-up die zich niet op deze pool bevindt.

De server is traag en gebruikt swap. Begrens de ARC zoals hierboven beschreven en voer arc_summary uit om de hit ratio te controleren. Als de ARC te klein is voor de actieve dataset, moet elke leesactie naar de schijf. Op dat punt presteert een standaard bestandssysteem dat gebruikmaakt van de page cache doorgaans beter.

FAQ

Hoeveel RAM heeft ZFS nodig op een VPS?

ZFS draait op een instance met 2 GB RAM. De werkelijke vraag is hoeveel er overblijft voor uw applicatie. Zonder optimalisatie staat OpenZFS 2.3 toe dat de ARC groeit tot de grootste waarde van RAM minus 1 GiB en 5/8 van het RAM-geheugen. Een server met 4 GB kan dus 3 GiB toewijzen aan de cache. Stel zfs_arc_max in op een waarde die uw workload kan missen en controleer dit door de regel c_max uit /proc/spl/kstat/zfs/arcstats te lezen.

Is een ZFS-snapshot een back-up?

Nee. Een snapshot bevindt zich in dezelfde pool als de data. Het overleeft een slechte rm en een mislukte upgrade, maar gaat verloren als de pool of de instance verdwijnt. Maak er een back-up van door deze naar een andere machine te sturen met zfs send, of door een back-uptool te gebruiken die schrijft naar opslag die deze server niet beheert.

Werkt ZFS hetzelfde op FreeBSD en Linux?

Sinds OpenZFS 2.0 in december 2020 is de codebase gelijk, zijn de commando's identiek, is het on-disk formaat hetzelfde en kunnen pools tussen beide systemen worden uitgewisseld. Het verschil zit in de verpakking. FreeBSD levert ZFS mee in het basissysteem. Op Linux bepaalt elke distributie dit zelf: Ubuntu bouwt de module in zijn kernelpakketten, terwijl Debian deze op uw machine bouwt met DKMS. Hierdoor kan een kernel-upgrade ertoe leiden dat u tijdelijk zonder module zit totdat de herbouw is geslaagd.

Kan ZFS corruptie herstellen op een VPS met één schijf?

Het detecteert de corruptie en benoemt het bestand, maar kan het niet herstellen omdat voor herstel een tweede kopie van het blok nodig is. zfs set copies=2 op een dataset geeft u die tweede kopie tegen dubbel ruimtegebruik; dit vangt een slecht blok op, maar geen verloren volume. Een mirror over twee volumes is de oplossing die daadwerkelijk herstelt.

Vertraagt compressie de server?

lz4 maakt het doorgaans sneller. Gecomprimeerde blokken betekenen minder bytes schrijven en minder bytes lezen, en de CPU-belasting per blok is klein in vergelijking met de schijfruimte die het bespaart. Stel compression=lz4 in op de root van de pool zodat elke dataset dit overerft, en controleer vervolgens zfs get compressratio tank zodra er echte data is geschreven.