, as they directed me here.
Do we know the current ZRAM settings? The only discussion I can find is from 2014, and suggests that they just set it to expose 1.5 times the physical RAM as a swap area.
ZRAM has a setting (mem_limit) to constrict how much memory to use, e.g. if you tell it to create a 4 terrabyte swap device but only use 200MB of RAM, then it will swap out 600MB at an average 3:1 compression rate and simply report to the kernel that it can't write new data (it behaves as if the device is full). Thus you'll only end up using that maximum value.
In general, ZRAM gets between 3:1 and 4:1 compression—closer to 3:1. ZRAM incurs overhead when swapping in or out, and so the performance impact depends on how many passes you make in a working set before swapping it back out (or invalidating it, if it's not been altered).
It can take 10,000 or 40,000 cycles to decompress a page of RAM, depending on how redundant the data is and what algorithm is used. For example: Lempil-Ziv decompression such as LZ4 reads a token, then copies a string of some arbitrary length, and so spends roughly 1 cycle per byte of output depending on the length of the entry. It's the cycles to decide what dictionary entry to copy, followed by a loop of 1-cycle MOV instructions, divided by the number of bytes. 10 cycles and 100 bytes to copy means 1.1 cycles per byte output. Likewise, this is fed by a Huffman decoder, which adds a few extra cycles.
All this means that spending a lot of time in one area of RAM diminishes the impact of ZRAM (or any swap), and ZRAM is quite cheap. As you start swapping more, it suddenly gets *expensive*. With sufficiently-low memory pressure, the performance impact of ZRAM can be fractions of a percent even if the system is swapping quite-frequently in real-time (something about having 6 billion cycles per second does that). Likewise, with multi-core systems and read-ahead prediction (or madvise(), if your application is smart enough), the Linux kernel can decompress ZRAM pages to a swap cache area a few microseconds before your application actually needs them, incurring a 0% performance hit.
So that's fascinating, but we've already been sold ZRAM.
Here's the point: eating a significant amount of RAM with a compressed ZRAM area will increase the rate of actual swapping, causing performance issues. When dealing with the general case, that's the only metric that matters.
The settings I've seen used in major distros currently allow ZRAM to use an unlimited amount of RAM, and restrict how much uncompressed memory you can swap in. That means if you (somehow) get 1.25:1 compression and they give you an area 1.5x the size of RAM, ZRAM can and will consume 100% of your memory.
I usually consider 4:1 compression a practical upper limit, and 3:1 the average case. Thus I set mem_limit to 0.5 times physical RAM, and disksize to 2 times physical ram size. Theoretically, zram will always hit mem_limit before you swap out the full disksize.
I haven't done any performance measuring and tweaking, beyond noting that 50% works and 90% strains the system. To do so, you would need to deploy at higher mem_limit and disksize values, with a disksize up to 4 times physical RAM and a mem_limit between 50% and 100% of physical RAM. You'd then have to gather metrics when ZRAM (kswapd) consumes significant average amounts of non-idle CPU, identifying what percentage of RAM is currently occupied by ZRAM (mem_used_total / total physical RAM). Automatic adjustment based on CPU consumption is also possible, albeit most likely at the driver level.
So, tl;dr: ZRAM should be restricted by mem_limit, with disksize set to about 4x that. I haven't been able to determine if that's what ChromeOS does at the moment; all Linux distributions I've examined just set disksize to about 1.5x or 2x RAM size and hope for the best.