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)
  • jet@hackertalks.com
    link
    fedilink
    English
    arrow-up
    2
    ·
    3 hours ago

    In my production systems, and in my home systems, and in my gaming computers, I turn swap off. There’s no good reason to wear out disc writes. In production systems, I’d rather have something fail hard, then get slower and slower and slower falling behind.

    Quite frankly, there’s no good reason to have swap on anymore, memory is huge. Most programs don’t need as much as they use. You can set memory pressure in systemd, telling programs to reduce their usage, and giving them individual hard cutoffs, so something like Prometheus can’t take down your whole system just because it’s got a memory leak.

  • Jul@piefed.blahaj.zone
    link
    fedilink
    English
    arrow-up
    4
    ·
    10 hours ago

    I didn’t look too closely at details, but generally that’s relatively normal the more individual applications you have running, especially with the overhead of them all being virtualized. Often the overhead of running that many virtualized operating systems can be problematic depending on how the container author chose and configured the container’s OS. A lot of people seem to just randomly pick an OS for their containers just so they can distribute their application with docker as easily as possible, without considering the consequences.

    Here are the options off the top of my head if disk wear is your primary concern:

    1. Turn swap off at the host level. Note, though, that you may end up in bottlenecks if multiple of them do very memory intensive tasks at the same time, like image and video processing, and docker can’t swap out the VMs that are idle to the disk and be able to use the RAM fully for those active tasks. For some of those apps you can configure when they do maintenance tasks and reduce the likelihood.

    2. Look at each individual VM in docker and see which are using the most swap and force docker to limit their allowed resources. You can even tell docker to make an application not use swap by setting the memory and memory-swap values to the same value or reduce their swap usage by setting memory-swapiness to a low number, or you can install those applications to the host system and configure the host to reduce swap or disallow swap usage through systemd or whatever rather than running them in docker. You may also find one of the applications you’re running has a memory leak issue. Good OSs often handle that, but who knows what IS the container is running and the docker layer is concealing from the host kernel and not handling quite as well as it being installed on “bare metal” might. Virtualization adds a lot of variables for these kinds of low level resource control scenarios. So just trying it on the host directly might reveal something if you’re interested in digging like I usually am, lol.

    3. Get a second, small, inexpensive drive and set that up as the swap partition for the host.

    4. Look into what database systems these are using. Often if they each are running their own separate DBMS containers, the DBMS maintenance overhead can cause some additional churn. I have a single instance of PostgreSQL and one of MariaDB running on a separate server that all of my applications connect to. Some of these applications may be not only spinning up a whole VM for the application, but an entirely other VM for their database server. Though I think some of these probably use sqlite which is just a file, I think manynof these use PostgreSQL and/or MySQL/MariaDB by default. This also helps because I only need a single backup for all of my databases. The negative is that if that DB server goes down, then all the apps go down too, but if you already have everything on one server that might not be as big of a deal. I have a lot of smaller servers running smaller subsets of applications based on their resource needs. Helps me conserve electricity rather than running one or two big servers that are almost always highly active. But I enjoy optimizing that kind of stuff, it’s tedious.

    • Terrasque@infosec.pub
      link
      fedilink
      English
      arrow-up
      2
      ·
      edit-2
      9 hours ago

      Just a small detail, docker containers aren’t vm’s and not running their own os. They run inside a jail under the host kernel. Docker containers are very lightweight.

  • notabot@piefed.social
    link
    fedilink
    English
    arrow-up
    25
    ·
    16 hours ago

    Seeing high cache and buffer numbers is usually a good sign, as it means the system is making full use of the memory you have. It’ll automatically deallocate it if something actually needs the memory, but until then it’s using it to store data you might need.

    Swap’s a funny one, and whilst you can tune it to an astonishing degree, the decisions the kernel makes aren’t always what you’d want. With this little actual memory usage, compared to the installed RAM, you might be able to run without swap at all, unless you want something like hibernate. If you want to test that, you can run (as root) swapoff -a, which should disable all swap devices, pushing needed pages back in to RAM, but only until you reboot. If it’s stable, you can consider removing the swap partition(s) later.

    • A9nWGzYt@lemmy.dbzer0.comOP
      link
      fedilink
      English
      arrow-up
      3
      ·
      13 hours ago

      I agree with you that my server specs are a little bit excessive for my usual workload. I have disabled swap in the past with swapoff -a and removed the partition from /etc/fstab under a similar usage, and no issues were observed.

      I am just leaving it there now for the rare instance when I run the occasional lightweight local LLM model (on CPU) for light tasks such as spell checking, which might need some RAM and I don’t risk crashing due to OOM issues.

      However, I still want to understand what is happening here to learn a little bit about my system. My intuition can be wrong here, but I find it strange that my laptop with similar specs and the same OS (but reasonably distinct workloads, to be fair) almost never swaps nor reaches those ridiculous levels of buffer + cache usage, so I think I might find one “offender” container to blame.

      • noahm@lemmy.world
        link
        fedilink
        English
        arrow-up
        6
        ·
        12 hours ago

        Very basically, what’s happening is that every file that is read (including the binaries and libraries that make up the services you run, etc) is loaded into memory and stays there until that memory needs to be reclaimed for something else. It’s a good thing. It means that the next time that file is needed, it can be accessed directly in RAM rather than reaching out to the filesystem.

      • notabot@piefed.social
        link
        fedilink
        English
        arrow-up
        2
        ·
        12 hours ago

        The cache usage being higher on a server than a laptop seems fairly likely as more disk accesses are occurring. When data is loaded from disk, the linux kernel will keep it in memory even after the original requester is done with it, on the principal that it might need it again. This is the cache you’re seeing. If the kernel detects high memory utilisation it will free cache pages before anything else, so you actually want to see near 100% memory utilisation all the time, as it means fewer accesses to disk.

        The swap usage is harder to diagnose without more detailed diagnostic work, but you can see from the graph you posted that, even what swap is being used, you have a little free memory. This may well be the kernel preemptively moving little used memory pages to the swap cache so tgat they can be evicted from memory quickly if needed. You could investigate thus by adjusting the ‘swapiness’ value closer to 0, to see if that delays the swap usage and reduces the peak.

  • thelittleblackbird@lemmy.world
    link
    fedilink
    English
    arrow-up
    30
    ·
    18 hours ago

    The amount of swap used is not a good indicative, you need to check if there is a big exchange of data per second/minute. This is the only indicative of an out of memory system.

    Sometimes, some regions of data memory “age” in ram without any access for a long periods of time, the the kernel here has two options, it could destroy the region knowing it could recreate it when needed (with some cpu overhead) or moved this to a swap file when the ram structure already in the swap file and release than section.

    Which regions are good candidates for this? Buffers, specially in the fs, code region used for processes or even data sections of a long sleeping process…

    Checking your data, if those 5gb are created over a long period of time I would not care a lot about it. Remeber how big the swap is, isn’t that important vs real traffic (in or out) to it

  • Overspark@piefed.social
    link
    fedilink
    English
    arrow-up
    16
    ·
    edit-2
    18 hours ago

    Yeah that’s completely normal, looks absolutely fine to me. For more info on how linux uses memory I suggest reading https://www.linuxatemyram.com/

    To add: that link suggests looking if your swap usage is changing. Linux is quite happy to stuff some memory that isn’t actually used in swap. If it was right about it not being used you should see the swap usage not changing much, so your SSD isn’t really being used either apart from the initial swap-out. If your swap usage keeps fluctuating wildly there is more going on which might warrant further investigation.

  • marcos@lemmy.world
    link
    fedilink
    English
    arrow-up
    4
    ·
    14 hours ago

    IMO, the easiest way to make your system not swap into some disk you don’t want it to is to not enable any swap partition on that disk.

    If it’s using that much RAM for cache, it will survive not having a swap with a minimum impact on performance.

  • frongt@lemmy.zip
    link
    fedilink
    English
    arrow-up
    6
    ·
    17 hours ago

    That’s low utilization. If your ram was fully used and stuff was being frequently stopped, that’s when I would be concerned (and when you would experience wear on your SSD).

    Right now you have less than a quarter used, and a couple things the kernel decided to swap out. Perfectly normal.

  • Shimitar@downonthestreet.eu
    link
    fedilink
    English
    arrow-up
    4
    ·
    17 hours ago

    As a suggestion, ditch ollama and setup llama.cpp. it will work fine with openwebui and it’s much more efficient. (Unrelated to the ram/swap issue)

    • A9nWGzYt@lemmy.dbzer0.comOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      13 hours ago

      Thanks for the tip. I have been looking into commenting out the ollama portion of the docker-compose.yml file and setting up llama.cpp instead for some time now. I suspect I don’t usually use features such as ollama pull to justify a fully-featured application.

      • slazer2au@lemmy.world
        link
        fedilink
        English
        arrow-up
        1
        ·
        15 hours ago

        It has been a while since I looked but Ollama use to be llama.CCP with a cloud wrapper before they forked it and rewrote it. In the same way postman is curl with a cloud wrapper.

        Tossing the extra bit will make it use less resources and support the actual project not someone forking oss, slapping on a paint job, rewriting a core function and still calling it oss.

  • Shimitar@downonthestreet.eu
    link
    fedilink
    English
    arrow-up
    3
    ·
    17 hours ago

    That is expected and a good thing.

    Free ram is wasted ram, so every file touched by any service will be cached and cache will stay there until ram is needed. This means that over time cache and buffers will always grow, because any subsequent access to those will be faster. The moment more ram is needed by programs, those buffers and cache will be freed immediately.

    This is also the reason why some swap will be used even if there is free ram. Some stuff and pages can be swapped out without impact on performance.

    Look at it this way: free ram is a wasted opportunity to increase performance by caching some file from disk.

    • brucethemoose@lemmy.world
      link
      fedilink
      English
      arrow-up
      4
      arrow-down
      1
      ·
      17 hours ago

      It’s “free ram” until stuff actually goes in swap.

      It depends on the scenario, of course. Maybe you have huge, totally idle processes, and active ones working from an HDD that need cache desperately, in which case this is good.

      But my experience with Linux is that is waaay to aggressive with this, in most configs, and I get far better performance from configs that avoid swap until it absolutely has to be used.

  • Eager Eagle@lemmy.world
    link
    fedilink
    English
    arrow-up
    3
    arrow-down
    1
    ·
    edit-2
    16 hours ago

    No point in messing with swappiness settings, trust me. You want to address the reason this happens in the first place, not disable to reduce swap.

    I’ve had a nearly identical scenario at work. The reason? A data verification process that went through 100s of thousands of files to run their checksums and check integrity. This was working as intended, but the system alerts were firing because of that high buffer/cache utilization. So check which processes have highest IO and you might find the answer. Swap is just a side effect.

  • irmadlad@lemmy.world
    link
    fedilink
    English
    arrow-up
    4
    arrow-down
    1
    ·
    18 hours ago

    Huh…

    
      System load:  1.26                Temperature:           57.0 C
      Usage of /:   20.4% of 454.86GB   Processes:             527
      Memory usage: 44%                 Users logged in:       1
      Swap usage:   0%                  IPv4 address for eno1: 192.168.1.190
    

    Ubuntu 22.04.5 - 32 GB RAM - 53 total containers

    cat /proc/sys/vm/swappiness: 60 (pretty much default)
    
    cat /proc/pressure/cpu: some avg10=0.68 avg60=0.62 avg300=0.67 total=960097774
    full avg10=0.00 avg60=0.00 avg300=0.00 total=0
    cat /proc/pressure/memory: some avg10=0.00 avg60=0.00 avg300=0.00 total=0
    full avg10=0.00 avg60=0.00 avg300=0.00 total=0
    cat /proc/pressure/io: some avg10=1.16 avg60=4.88 avg300=3.85 total=2831425045
    full avg10=1.11 avg60=4.54 avg300=3.58 total=2653626377
    
    • A9nWGzYt@lemmy.dbzer0.comOP
      link
      fedilink
      English
      arrow-up
      3
      ·
      13 hours ago

      Well, here I have 41 containers and:

      free -hm
                     total        used        free      shared  buff/cache   available
      Mem:            31Gi       5.7Gi       426Mi       207Mi        25Gi        25Gi
      Swap:           31Gi       3.7Gi        28Gi
      

      As well as

      cat /proc/sys/vm/swappiness: 10
      

      and

      $ cat /proc/pressure/cpu
      some avg10=0.00 avg60=0.00 avg300=0.00 total=302436406
      full avg10=0.00 avg60=0.00 avg300=0.00 total=0
      
      $ cat /proc/pressure/memory
      some avg10=0.00 avg60=0.00 avg300=0.00 total=64263542
      full avg10=0.00 avg60=0.00 avg300=0.00 total=63043120
      
      $ cat /proc/pressure/io
      some avg10=1.99 avg60=1.67 avg300=1.61 total=1844790000
      full avg10=1.90 avg60=1.59 avg300=1.56 total=1788451770
      
      • irmadlad@lemmy.world
        link
        fedilink
        English
        arrow-up
        2
        ·
        12 hours ago

        41 containers:

        Are you noticing any stalling or stuttering when running apps or using multiple apps? If ‘no’ then I’d agree with the ones that are telling you it’s fine. Dats how Linux do. I’ve always been told to let Linux handle that unless it’s causing problems for you. And even then, after exhausting all other things that may cause this. Now whether that is sage advice, I couldn’t comment to that, however and anecdotally, it’s served me well.

  • brucethemoose@lemmy.world
    link
    fedilink
    English
    arrow-up
    5
    arrow-down
    5
    ·
    edit-2
    17 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
      6
      ·
      16 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.

      • brucethemoose@lemmy.world
        link
        fedilink
        English
        arrow-up
        2
        ·
        edit-2
        11 hours ago

        I mean… it’s an issue. OP’s system is swapping the SSD when it clearly should not be doing it. My system had horrible usability issues in some scenarios without a lot of reconfiguration, and thrashed my SSD for no benefit.

        The default heuristic is not good for our systems, and OP’s situation is a pretty common scenario. That’s a fact. How is that not an issue?

        And support for TRIM and whatever else was added for SSD support is not really the issue, here. That’s working fine.

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

          when it clearly should not be doing it.

          No, sorry. We don’t know enough to say this. What were the options when configuring ext4? What record size is grafana using? Mariadb or postgres? Is there contention with another db? Is there a mounted NFS path in the same ext4 partition with weird block settings? There are lots of legitimate config reasons for op’s problem, but there are so many parts of op’s setup we don’t know, we similarly can’t possibly know what the issue is.

          Swappiness works as intended in most default scheduler configurations and seeing high swap is a symptom, not an issue. It is almost always more productive to find out why the swapping is happening.

          Not sure what you’re getting at with TRIM.