Recently I came across Lunduke post about some mysterious Vendefoul Wolf Linux distribution that uses 217 MB RAM with Devuan as base (no systemd(1) here) and XLibre X11 server along with IceWM window manager.

For the record – the Lunduke post states 200 MB RAM but XLibreDev quotes a post where exactly 217 MB RAM is reported.
Later Lunduke even posted a video about it.
As I use similarly low resource setup with Openbox/Tint2/Dzen2 setup (documented FreeBSD Desktop here) I was wondering … how low can I go with FreeBSD RAM usage.

Lets try …
The Table of Contents is as follows.
- Install
- Configuration
- /boot/loader.conf
- /etc/rc.conf
- /etc/sysctl.conf
- /etc/devfs.rules
- Installed Packages
- Login Manager
- ~/.xinitrc
- Startup
- RAM Usage
- End Session
- Comparison
- Summary
I wanted to use most recent FreeBSD so I used 15.0-RELEASE version – including the Tech Preview PKGBASE setup for FreeBSD Base System.
As Xorg X11 implementation is currently intentionally crippled by some Red Hat employees and some people from FreeDesktop.org I decided to use actively developed and maintained XLibre X11 server instead.
Example of such behavior below.

More on that tragic Xorg story where open source spirit died long time ago is available here:
A lot has also been explained in this message:

As the Vendefoul Wolf Linux did not used ZFS I also decided to fight fair and used UFS with Soft Updates Journaling mode that minimizes fsck(8) time to minimum. For the record Netflix also uses FreeBSD with UFS filesystem.
Using UFS would mean loosing great FreeBSD feature called ZFS Boot Environments … but fortunately you can use UFS Boot Environments as replacement on UFS filesystems.
After install I created my vermaden user with membership in these groups.
FreeBSD $ id | tr ', ' '\n'
uid=1000(vermaden)
gid=1000(vermaden)
groups=0(wheel)
5(operator)
44(video)
48(idletime)
69(network)
1000(vermaden)
Later I disabled additional virtual terminals that I would not use anyway in the /etc/ttys file.

/boot/loader.conf
Next used /boot/loader.conf file.
# CONSOLE COMMON loader_logo=none loader_menu_frame=none screen.font="6x12" # CONSOLE RESOLUTION kern.vt.fb.default.mode="1920x1080" efi_max_resolution="1920x1080" vbe_max_resolution="1920x1080" # ENABLE SYNAPTICS hw.psm.synaptics_support=1 # DISABLE /dev/diskid/* AND /dev/gptid/* ENTRIES FOR DISKS kern.geom.label.disk_ident.enable=0 kern.geom.label.gptid.enable=0 # POWER MANAGEMENT POWER OFF DEVICES WITHOUT ATTACHED DRIVER hw.pci.do_power_nodriver=3 # POWER MANAGEMENT FOR EVERY USED AHCI CHANNEL (ahcich 0-3) hint.ahcich.0.pm_level=5 hint.ahcich.1.pm_level=5 hint.ahcich.2.pm_level=5 hint.ahcich.3.pm_level=5 # MAX SEND QUEUE SIZE net.link.ifqmaxlen=2048 # DISABLE USB PACKET FILTERING hw.usb.no_pf=1 # NO USB DEVICE ENUMERATE WAITING AT BOOT AND SHUTDOWN hw.usb.no_boot_wait=1 hw.usb.no_shutdown_wait=1 # DISABLE hwpstate_intel(4) DRIVER hint.hwpstate_intel.0.disabled=1
/etc/rc.conf
Now the main FreeBSD /etc/rc.conf configuration file.
# SILENCE rc_startmsgs=NO rc_info=NO # NETWORK hostname=minimal defaultroute_delay=3 defaultroute_carrier_delay=3 ifconfig_vtnet0="inet 10.1.1.71/24 up" defaultrouter="10.1.1.1" gateway_enable=YES harvest_mask=351 rtsol_flags="-i" rtsold_flags="-a -i" # POWER performance_cx_lowest=C1 economy_cx_lowest=Cmax # DAEMONS update_motd=NO local_unbound_enable="NO" dbus_enable=YES syslogd_flags='-s -s' sendmail_enable=NO sendmail_submit_enable=YES sendmail_outbound_enable=NO sendmail_msp_queue_enable=NO # FS fsck_y_enable=YES clear_tmp_enable=NO clear_tmp_X=YES # OTHER keyrate=fast virecover_enable=NO devfs_system_ruleset=desktop entropy_file=NO savecore_enable=NO dumpdev=AUTO
/etc/sysctl.conf
Now FreeBSD system settings in the /etc/sysctl.conf file.
# HARVEST MASK FOR random(4) kern.random.harvest.mask=33119 # SECURITY security.bsd.see_jail_proc=0 security.bsd.unprivileged_proc_debug=0 # SECURITY/RANDOM PID kern.randompid=1 # DISABLE ANNOYING THINGS vfs.usermount=1 kern.coredump=0 hw.syscons.bell=0 kern.vt.enable_bell=0 # DO NOT WAIT FOR USB DEVICES ON SUSPEND/SHUTDOWN hw.usb.no_suspend_wait=1 hw.usb.no_shutdown_wait=1 # DESKTOP/INTERACTIVITY kern.sched.preempt_thresh=224 # DESKTOP QUANTUM FOR TIMESHARE THREADS IN stathz TICKS kern.sched.slice=3 # DESKTOP/IRIDIUM/CHROMIUM kern.ipc.shm_allow_removed=1 # ALLOW idprio(8) USE BY REGULAR USER security.bsd.unprivileged_idprio=1 # PREVENT SHARED MEMORY FROM BEING SWAPPED TO DISK kern.ipc.shm_use_phys=1 # DO NOT SWITCH VIRTUAL CONSOLES BACK AND FORTH ON SUSPEND kern.vt.suspendswitch=0 # MAKE FUSEFS DO NOT USE WIRED MEMORY vfs.fusefs.data_cache_mode=0
/etc/devfs.rules
The devfs_system_ruleset specified desktop in the /etc/devfs.rules file.
[desktop=10]
add path 'acd*' mode 0660 group operator
add path 'cd*' mode 0660 group operator
add path 'da*' mode 0660 group operator
add path 'pass*' mode 0660 group operator
add path 'xpt*' mode 0660 group operator
add path 'fd*' mode 0660 group operator
add path 'md*' mode 0660 group operator
add path 'uscanner*' mode 0660 group operator
add path 'ugen*' mode 0660 group operator
add path 'usb/*' mode 0660 group operator
add path 'video*' mode 0660 group operator
add path 'cuse*' mode 0660 group operator
Installed Packages
Only a few … with few hundred dependencies 🙂
FreeBSD # pkg install xlibre openbox tint2 dzen2 xterm htop ifstat doas \
gnome-icons-faenza adwaita-icon-theme mate-icon-theme
What I really loved is that XLibre X11 packages DOES NOT CONFLICT with Xorg packages. You just install xlibre instead of xorg and everything works … even better then with Xorg 🙂
Login Manager
I did not used login manager such as xdm(1) as its not needed in the setup.
I just start X11 directly with xinit(1) command like that.
FreeBSD % xinit -- -dpi 75 -nolisten tcp
If you would like to add xdm(1) to the mix then it would add additional 12 MB to RAM usage.
FreeBSD # ps aux -o user,rss,command | grep -e xdm -e RSS | cut -c 59-
USER RSS COMMAND
root 8824 xdm: :0 (xdm)
root 4596 /usr/local/bin/xdm -server :0 local /usr/local/bin/X :0 vt05
~/.xinitrc
Now the details what is being set and started for this minimalistic yet powerful desktop.
# PATH export PATH=${PATH}:~/scripts # SET PROPER locale(1) export LC_ALL=en_US.UTF-8 export LANG=en_US.UTF-8 # fontconfig export FREETYPE_PROPERTIES="cff:no-stem-darkening=0 autofitter:no-stem-darkening=0" # MODIFY QT FONT DPI export QT_FONT_DPI=75 # DISABLE OVERLAY SCROLLBARS export GTK_OVERLAY_SCROLLING=0 # XDG export DESKTOP_SESSION=openbox export XDG_SESSION_DESKTOP=openbox export XDG_CURRENT_DESKTOP=openbox export XDG_SESSION_CLASS=user export XDG_SESSION_TYPE=x11 # DISABLE GVFS FUSE ~/.gvfs MOUNT export GVFS_DISABLE_FUSE=1 # QT MUST KNOW WHERE IS GTK2 CONFIG export GTK2_RC_FILES="${HOME}/.gtkrc-2.0" # QT5 qt5ct export QT_QPA_PLATFORMTHEME=qt5ct # GTK/QT ANTIALIASING export QT_XFT=1 export GDK_USE_XFT=1 # FORCE LIBREOFFICE TO USE GTK2 THEME export OOO_FORCE_DESKTOP=gnome # WM exec dbus-launch --exit-with-session openbox-session 1> /dev/null 2> /dev/null & WM=${!} # DAEMONS/TOOLS/TASKBARS/BACKGROUND ( sleep 1 && ~/scripts/__openbox_restart_dzen2.sh 1> /dev/null 2> /dev/null ) & ( sleep 1 && ~/scripts/__openbox_restart_tint2.sh 1> /dev/null 2> /dev/null ) & xbindkeys 1> /dev/null 2> /dev/null & setxkbmap -option terminate:ctrl_alt_bksp,caps:none pl & ( sleep 5 && xmodmap ~/.xmodmaprc ) & # WAIT FOR openbox(1) WM PID wait ${WM} # LOGOUT WHEN X11 STARTED FROM PLAIN login(1) CONSOLE XINIT=$( ps -o pid,comm | awk '/xinit/ {print $1}' ) SHELL=$( ps -o ppid -p ${XINIT} | grep -v PPID ) LOGIN=$( ps -o ppid -p ${SHELL} | grep -v PPID ) kill -9 ${XINIT} ${SHELL} ${LOGIN} 2> /dev/null # EXIT exit 0
For the record … this section at the end makes sure that after X11 will end its process my user will be securely and automatically logged out.
# LOGOUT WHEN X11 STARTED FROM PLAIN login(1) CONSOLE
XINIT=$( ps -o pid,comm | awk '/xinit/ {print $1}' )
SHELL=$( ps -o ppid -p ${XINIT} | grep -v PPID )
LOGIN=$( ps -o ppid -p ${SHELL} | grep -v PPID )
kill -9 ${XINIT} ${SHELL} ${LOGIN} 2> /dev/null
This is how the system looks after its booted.

After executing the xinit -- -dpi 75 -nolisten tcp command Openbox window manager awaits our commands with Tint2 and Dzen2 bars on the top.

The kld.sh script converts FreeBSD kernel (and its modules) RAM usage display into MB units and its talked in depth in the Part 6 – Learn Shell Scripting of the Ghost in the Shell series.
After starting xterm(1) terminal and then htop(1) inside to measure RAM usage the number stops at 230 MB … but as we started these only to measure the usage the real RAM usage of such FreeBSD desktop without any applications is 206 MB RAM.
I subtracted:
– 19 MB for xterm(1) terminal.
– 5 MB for htop(1) process viewer.
Math.
230 - 19 - 5 = 206
As calculated in the terminal.

After stopping X11 server this is how console looks like (and safely logged out).

I was also positively surprised how cleanly and without any errors Xlibre servers ends its work.
You can compare these 200 MB RAM to other desktop environments and window managers in one of my older articles – Desktop Environments Resource Usage Comparison – here.

As I used GENERIC FreeBSD kernel its possible to use even smaller amount of RAM with kernel recompilation.
UPDATE 1 – Hard 220 MB Limit
The tests I have done above were done on a FreeBSD Bhyve virtual machine with 6 GB RAM. That means plenty of space for buffers and cache – and the FreeBSD motto is that – “Free memory is wasted memory.” – I decided to try with smallest VM I can start in UEFI mode.
That means 220 MB of RAM.
The results I got surprised me more then I expected.
Plain FreeBSD
When VM had 6 GB RAM plain FreeBSD used about 115 MB RAM – but when I limited the physical memory to 220 MB RAM for that virtual machine only 82 MB RAM were used.

Openbox
Here the results are also better.
My complete Openbox/Tint2/Dzen2 desktop uses only 134 MB RAM!
The calculations are: 142 (ram) + 14 (swap) – 18 (xterm) – 4 (htop)

Hope that helps.
EOF
