I have noticed that my home server is strangely using lots of swap (~5 GB), despite having only a few lightweight processes running and loads of RAM installed (32 GB).

Upon configuring Grafana + Prometheus, I noticed a trend where cache + buffer will progressively increase until swap starts to be used. My system and services combined will use ~8 GB RAM. Upon rebooting, the cache + buffer will start anywhere from 3–10 GB, progressively ramp up to ~25 GB in 1–2h, where swap will start to be needed (~3 GB). See the image attached for reference.

My swap filesystem is on an expensive (to me) SSD, and I would like to reduce its wear by as much as possible. I understand that swap can introduce only minimal wear on SSDs depending on its nature and that it can be harmless, but I am still not sure what is causing this behavior (and why) and whether I should worry about it or not. So I figured I should investigate what is happening here.

My main question is, how can I figure out what is causing this behavior? Is it expected? I am looking for guidance from others who are more experienced than me in the topic.

A little bit about my system:

I am running Debian 12 on an NVMe SSD containing the root partition (btrfs) and docker services. I also have two HDDs, one with persistent data (ext4), and the other with backups (ext4). This is majoritarily a single-user machine. I tried using the following kernel parameters, but it hasn’t helped:

vm.swappiness=10
vm.vfs_cache_pressure=200

My docker services are:

  • *arr stack
  • jellyfin
  • nextcloud
  • immich
  • open-webui + ollama
  • pi-hole
  • invidious
  • romm
  • nginx proxy manager
  • grafana + prometheus
  • other minor services that I don’t think are doing much (uptime-kuma, stirlingpdf, vaultwarden, etc)
  • brucethemoose@lemmy.world
    link
    fedilink
    English
    arrow-up
    3
    arrow-down
    3
    ·
    edit-2
    3 hours ago

    I disagree with most here.

    You need to reduce swappiness even more, and tweak some other variables (like the memory “threshold” Linux starts to swap, and disk cache aggressiveness) to stop Linux from swapping so opportunistically under such a light load.

    IMO, Linux is configured for “old” systems by default: slow HDDs, and constrained RAM pools, where disk IO really, really needs caching, and where idle background processes take a large fraction of RAM.

    You have superfluous RAM for your workload. And very fast disk IO that isn’t such a hindrance to apps anyway. And a disk you don’t want to wear. This is the opposite scenario: you don’t want Linux to swap unless it absolutely has to.

    For reference, this is part of my config. It’s rather niche and you probably shouldn’t use it, but you should consider looking up the variables:

    # Keep min reserve reasonable for 8GB usable space
    vm.min_free_kbytes = 262144        # Lower absolute minimum to 256MB
    
    vm.watermark_scale_factor = 10     # Lower to 0.1% (which is ~128MB on 128GB)
    
    # Disable watermark boosting completely
    vm.watermark_boost_factor = 0
    
    # Normal-ish metadata pressure so desktop doesn't stutter on disk reads
    vm.vfs_cache_pressure = 120
    
    # Allow reasonable swapping of inactive anonymous desktop pages, could be lower
    vm.swappiness = 10
    
    # Dirty bytes limits to limit caching
    vm.dirty_background_bytes = 67108864
    vm.dirty_bytes = 268435456
    
    # Disable compaction & proactive scans to stop freezing with large portions of RAM mlocked
    vm.compaction_proactiveness = 0
    vm.compact_unevictable_allowed = 0
    
    vm.page-cluster = 0 # 4kb pages for SSD
    

    My system still uses RAM as disk cache with this config, it just won’t go out of its way to swap just to keep that cache, especially I lower swappiness to 1-3.

    I also have a 1GB zram pool, prioritized over ssd swap. But you should make yours even larger (maybe 4GB?). This will intercept anything that does swap first.

    I also start some applications with systemd-run and specify memory caps and swap limits (often forbidding them from swapping entirely).

    It makes a night-and-day difference for some workloads on my system, that would otherwise swap pointlessly, just tank performance and even de-stabilize the system.

    • non_burglar@lemmy.world
      link
      fedilink
      English
      arrow-up
      4
      ·
      2 hours ago

      I agree that hitting swap is not ideal, but messing with swappiness sysctl is almost never the answer and very often leads to more problems than it solves.

      If you want to tune for workload without needing fairly deep understanding of how Linux manages memory, use a sysctl that sets a whole system behaviour like CPU governor presets.

      IMO, Linux is configured for “old” systems by default: slow HDDs, and constrained RAM pools, where disk IO really, really needs caching, and where idle background processes take a large fraction of RAM.

      Not really a matter of opinion, and not true since kernel 5.1 when ssds became first class citizens.