diff --git a/roles/core/sysctl/files/sysctl.conf b/roles/core/sysctl/files/sysctl.conf
--- a/roles/core/sysctl/files/sysctl.conf
+++ b/roles/core/sysctl/files/sysctl.conf
@@ -20,3 +20,16 @@
 
 # Allow user to mount disks (required by FUSE or PEFS)
 vfs.usermount=1
+
+{% if use_zfs %}
+
+{% if mem < 4096 %}
+# Maximum size of the Adaptive Replacement Cache (ARC).
+vfs.zfs.arc_max = 2147483648
+{% endif %}
+
+# Keep prefetch: this works by reading larger blocks than were requested
+# into the ARC in hopes that the data will be needed soon.
+vfs.zfs.prefetch_disable=0
+
+{% endif %}
diff --git a/roles/core/sysctl/init.sls b/roles/core/sysctl/init.sls
--- a/roles/core/sysctl/init.sls
+++ b/roles/core/sysctl/init.sls
@@ -9,8 +9,14 @@
 
 {% if grains['os'] == 'FreeBSD' %}
 
+{% set use_zfs = salt['node.has']('zfs:pool') %}
+
 /etc/sysctl.conf:
   file.managed:
     - source: salt://roles/core/sysctl/files/sysctl.conf
+    - template: jinja
+    - context:
+        use_zfs: {{ use_zfs }}
+        mem: {{ grains['mem_total'] }}
 
 {% endif %}