Working zswap configuration (different from zram)

Could anyone please share their configuration if they managed to get zswap working. Feel free to suggest any other work arounds as well. Will greatly appreciate it :slight_smile:

There’s a nixos module for that, which works perfectly for me, I just have this in my config:

zramSwap = {
  enable = true;
  algorithm = "zstd";
  # This refers to the uncompressed size, actual memory usage will be lower.
  memoryPercent = 80;
};
1 Like

@R-VdP Thanks for th reply, zram is different from zswap :smiley: . While zram configuration is readily available as you have correctly given there is no such variable for zswap :smiley:

Oh right, I wasn’t aware of zswap, so I just assumed that they were the same. I’m reading up on it now.

Yeah, I don’t know then, let’s see if someone else comes along :slight_smile:

1 Like

There is actually an open ticket to modularize zswap as well similarly to zram:

I did a quick read on the arch wiki, and checked the nixos kernel, and we have zswap enabled in the kernel but not turned on by default. As I understand it, you should be able to simply do

boot.kernelParams = [
  "zswap.enabled=1"
];

to have it enabled on startup.
You can enable it on a running system with

echo 1 | sudo tee /sys/module/zswap/parameters/enabled

There are some other settings that can be controlled from the kernel command line that are listed in the documentation. Others are configured through sysfs, for which you could use systemd-tmpfiles.

I hope I’m not repeating what you already knew, I’m just trying to show how you can easily use this on nixos by using the basic system config primitives (kernel command line options, systemd-tmpfiles, etc) without necessarily needing a dedicated nixos option. (But it could be nice to still have such an option eventually of course.)

@R-VdP not at all, really appreciate the information you shared. The entry (Module request: config.zswap · Issue #119244 · NixOS/nixpkgs · GitHub) here seems to suggest that certain modules that zswap depends on are not readily available in the nixos kernel and hence need to be loaded and we may even need to create a custom kernel patch to include these missing modules that zswap depends on.

You are right in stating that we can use basic systemd configs, one of the users at the end recommend a systemd script that I tested and is working. I have yet to test adding the modules into boot.kernalParams though:

systemd.services.zswap = {
  description = "Enable ZSwap, set to LZ4 and Z3FOLD";
  enable = true;
  wantedBy = [ "basic.target" ];
  path = [ pkgs.bash ];
  serviceConfig = {
    ExecStart = ''${pkgs.bash}/bin/bash -c 'cd /sys/module/zswap/parameters&& \
    echo 1 > enabled&& \
    echo 20 > max_pool_percent&& \
    echo zstd > compressor&& \
    echo z3fold > zpool'
    '';
  Type = "simple";
  };
};

relevant snaps from Issues · NixOS/nixpkgs · GitHub


There’s a couple of issues with that systemd service though (its type should be oneshot, and in general I think its functionality could be achieved with kernel command line options and systemd-tmpfiles).

For the kernel config changes, do any other distros enable these settings by default? If so, you could make a case for enabling them also for the nixos kernel builds. I’d do that as a separate PR.

1 Like

nice catch you are right since we only want it executing once and exit. Thanks.

I very much agree with you that we should use kernel command line since its suitable. As for other distros im not sure if that is that :frowning: but i will research further and maybe create a new PR :slight_smile:

I reordered @uzi 's code so that writing to enabled is the last thing done:

  systemd.services.zswap = {
    description = "Enable zswap, set to zstd and Z3FOLD";
    enable = true;
    wantedBy = ["basic.target"];
    path = [ pkgs.bash ];
    serviceConfig = {
      ExecStart = ''${pkgs.bash}/bin/bash -c 'cd /sys/module/zswap/parameters && \
        echo zstd > compressor && echo z3fold > zpool && echo 20 > max_pool_percent && \
        echo 1 > enabled'
        '';
      Type = "oneshot";
    };
  };

FYI: Using kernel parameters for this does not work as expected because the modules for the things you configure must be built into the kernel for that to function.

systemd-tmpfilesd would probably be the best solution as the kernel should be able to load those module automatically once booted and you don’t really care about zswap in the initrd.

I now do it like this: