Reading "free: 180MB" on an 8GB server alarms people every day, and it is almost always fine. Linux uses spare memory as disk cache and hands it back the instant something needs it. The number to read is available, not free.

free -h\n#               total   used   free   shared  buff/cache   available\n# Mem:           7.8Gi  2.1Gi  180Mi   120Mi      5.5Gi       5.3Gi

5.3Gi available means there is 5.3Gi to be had. The cache is not lost memory; it is memory doing something useful until it is needed.

Swap is the number that matters

Swap being USED is not the problem. Swap being actively written and read is: the machine is moving pages to disk to make room, and disk is thousands of times slower than memory. Everything is slow and nothing in the application explains it.
vmstat 2 5\n# watch the si and so columns - sustained non-zero is thrashing

Find what is holding it

ps aux --sort=-%mem | head -10
smem -rs uss 2>/dev/null | head -10

uss is the memory a process would actually free if it exited, which is the honest figure. rss double-counts shared libraries and makes every PHP worker look enormous.

The usual answer

  • Too many PHP workers. pm.max_children set from a tutorial rather than from your RAM. Divide available memory by the average worker and be conservative.
  • innodb_buffer_pool_size too large. A database told to cache more than the machine has.
  • A leak in a long-running worker. Restart it periodically; php-fpm does this with pm.max_requests.
Some swap is healthy - it lets the kernel move genuinely idle pages out of the way. A server with swap disabled entirely has no cushion and is killed outright when it runs short.