quarta-feira, 3 de junho de 2026

Are ZRAM or ZSWAP really necessary?


Summary


CONFIGURING ZSWAP + ZRAM


INTRODUCTION


Level: Intermediate
There will be no basic explanations of the commands.

We'll start with some technical jargon, but it's necessary, so I've tried to simplify it into accessible language.

If you're looking for a magic formula to turbocharge your Linux and push your machine's hardware to its limits, I'm sorry, that doesn't exist, but here's a suggestion for everyone who has a computer for normal use (server or desktop):

DON'T CHANGE ANYTHING, LEAVE IT AT DEFAULT!

I will mention some specific cases where it is necessary to make changes.

A "system" is called a "system" because it is a "system," that is, a set of elements, concrete or abstract, intellectually organized, or even more so, when you change one part of the system you may end up damaging another part or the whole system.

This leads us to that good old modern maxim: "don't mess with the system if you don't know what you're doing." And if you don't know, go study or ask someone who does!

No swap replaces adding more RAM to your computer; zRAM and/or zSWAP do not replace adding more RAM.

The kernel was designed to work with swap. The use of swap is necessary, especially if you frequently use hibernation.

From now on, we will begin to understand why you shouldn't create ZRAM or ZSWAP interchangeably.



SWAP


Swap in English; trocar in Portuguese - Swap Space, Exchange Space; it's called Exchange Space because there is an exchange of files, file addresses, and memory pages of programs between the system and RAM, between the system and the HD/SD, etc. The Kernel takes care of this.

Swap, broadly speaking, is a reserved physical space on the computer's HD or SD card, used for exchanging files, pages, etc. The processor's access to the computer's physical RAM is extremely more efficient and effective than access to the HD or SD card, which is obvious.

Pages stored in swap space are not moved back to RAM unless they are accessed/requested. This is why many counters show pages in swap, even though the system may already be in a state where no active swapping is occurring.

The swap partition is falling into disuse and, over time, will only be used in special circumstances, but the concept of swap remains and will continue to be very much alive.

Nowadays, by default, the Ubuntu automatic installer, for example, no longer creates a Swap Partition. Instead, it creates a Swap File (/swapfile) located directly on the root partition ( / ), just as Windows always did.

Fedora and Pop!_OS are already coming with ZRAM limited to a maximum limit, such as 4GB or 8GB, depending on the version, usually with a swapfile (zram-on-swap).

Let's go to the official Linux Kernel documentation, in a free translation (although old, it's still valid because it preserves the basic concepts):

"Just as Linux uses free memory for purposes such as buffering data from disk, there eventually is a need to free up private or anonymous pages used by a process. These pages, unlike those backed by a file on disk, cannot be simply discarded to be read in later. Instead they have to be carefully copied to backing storage, sometimes called the swap area. This chapter details how Linux uses and manages its backing storage.

Strictly speaking, Linux does not swap as “swapping” refers to coping an entire process address space to disk and “paging” to copying out individual pages. Linux actually implements paging as modern hardware supports it, but traditionally has called it swapping in discussions and documentation. To be consistent with the Linux usage of the word, we too will refer to it as swapping."

We see that the second paragraph lays the foundation for all the confusion generated in discussions and forums.

Pages, in this context, are not like pages in a book or text; they are fixed-size blocks into which virtual memory and physical memory (RAM) are divided.

What the Linux Kernel does is "paging," but it calls it "swapping" because it has become wrongly popularized. So, the "dumb" part won over the technical part, which, supposedly, should be the intelligent part.

How will laypeople learn if technicians try to adapt to lay language?
It should be the other way around!
The minority doesn't always have to adapt to the majority; the basic question is right and wrong.

This causes a lot of confusion, because some will say that "it's just a matter of terminology," but if it's just a matter of terminology, why does the wrong term prevail?!?
Furthermore, it's not just a matter of terminology: paging is one thing (it's the copying of individual pages, that is, page by page and not by process), swapping is another thing (it's the copying of the entire address space of a process to disk, that is, it moves an entire process from RAM to disk to free up space and then brings it back whole when it needs to run).
And, as we have seen, the Linux Kernel uses swap (swap space) to do paging.
When you enable "swap," you are simply telling the Kernel: "Here is the piece of disk you can use to do paging when you need it."

The names of things are important, and you can't just change the names of things without a basis in reality.
You, whose name is John, for example, would you like me to call you Mary or to call you a son of a bitch every time?

After all, it's just a matter of terminology!

Furthermore, scientific language is, by definition, objective. Each term must have a single meaning and sense, which is obvious.
When we start changing the names of things, the interpretation becomes subjective and the language, consequently, ceases to be technical-scientific and becomes literary language (philosophical, poetic, etc.) where the terms have their meanings according to the context.

Scientific language is, therefore, the easiest to understand because each term has and must necessarily have a single meaning and a single sense, otherwise, I repeat, it is not scientific language.

After this cultural interlude, let's move on.

Here, "swap" refers to "swap space," so it's "the swap."
It's normal and beneficial for systems (both Linux and others) to use some swap (swap space, whether for paging or swapping), even if there is still physical RAM available.

If you are using zRAM, there is no need for a swap partition or a swapfile, unless you are using hibernation, as we will see later.
If it's a regular desktop, opt for a swap file (swapfile) configured after the system is installed.
Even if you create the file manually later, it will still be 100% managed by the Kernel and not by the user's space.
In terms of performance, it's about the same, as the Linux Kernel manages it efficiently and effectively.

Efficiency: achieving the best performance in the necessary time with the minimum of errors and/or expenses.

Effectiveness: perfectly completing a given task.

What size?

This depends on how much physical RAM the machine has, the processor's performance, etc.

ZRAM doesn't need a hard drive or SD card behind it to function. It works completely isolated within RAM.

ZSWAP, on the other hand, is a write cache. It absolutely needs a real swap space on the disk (a partition or a swap file) to function as an "escape valve". If ZSWAP fills up, it throws the excess space onto the disk.

We will see ZRAM and ZSWAP in more detail later.

Both the swap partition and the swap file are managed by the Kernel. From the moment the swap file, for example, is active, the Linux Kernel completely "ignores" the file system and also "ignores" the user space to read and write to the swap file or swap partition.

Users, when they read or hear the word "swap," generally think of a swap partition. However, this paradigm will change because the swap partition is becoming less widely used, and the swapfile is becoming the most common option.

The advantage of a swapfile, as it is a regular file within your main file system, is that it inherits Linux permissions. You can (and should) apply the chmod 600 permission, meaning that only the root user can read or write to it.

A swap partition is a raw disk block (example: /dev/sdb1). Although it also requires root privileges to be accessed directly, it does not benefit from the operating system's file permission structure.

Discussions revolve around the level of security this represents, although both can be encrypted.

Creating a swapfile instead of a swap partition is being adopted by distributions because of the flexibility of management, since messing with a swap partition means messing with practically the entire system partitioning.



The general rule applied, without hibernation, is:

Systems with little RAM (Less than 2 GB)
The created swap will have twice the RAM (e.g., if you have 1 GB of RAM, the swap will be 2 GB).
Systems with intermediate RAM (Between 2 GB and 8 GB)
The created swap will have exactly the same size as the RAM (e.g., if you have 4 GB of RAM, the swap will be 4 GB).
Systems with a lot of RAM (More than 8 GB)
A safe limit is adopted, and generally the swap is fixed at 11 GB or a rule of $11 GB + \text{square root of RAM}$ is applied, not exceeding much beyond that. It is understood that with so much physical RAM, you will rarely need a gigantic swap, saving your HDD/SD card.

According to Red Hat, the swap size depends on the desired system behavior, but configuring 20% ​​of the RAM as swap is generally a good idea.
Swap, Virtual Memory and OOM Killer

If you choose not to use zRAM, the main reason to create swap (partition or file, never both at the same time) is because when physical RAM reaches 100% system usage and there is no swap to exchange the data, the Kernel activates an emergency mechanism called OOM Killer (Out of Memory Killer).

However, the kernel tries several strategies before killing processes:

Page cache reclaim: removes file data from RAM that can be reread from disk.
Dentry and inode reclaim: releases cached file system metadata.
Memory compaction: reorganizes pages to create contiguous blocks.
KSM (if enabled): combines identical pages between processes.
OOM Killer: only when there is no more recoverable memory.

It's important to understand that "100% system usage" doesn't necessarily mean all physical RAM in the sense of "zero free bytes," but rather all the RAM that the Kernel considers available to processes; it means 100% of the usable and allocable memory is exhausted.

The Kernel maintains an emergency physical memory reserve (controlled by a parameter called vm.min_free_kbytes).

This reserve allows the Kernel itself to continue functioning and process basic system commands.

If a user program tries to use up every last byte of RAM, the Kernel blocks access to this reserve.

For user programs, the memory is exhausted (100%), but there is still physical RAM securely stored by the Kernel.

When the total amount of what programs are actually writing reaches the limit of what the physical RAM can handle (excluding the Kernel's reserve), the system crashes.

Since there's no swap space to divert data and relieve pressure, the kernel has no choice but to "kill" someone to immediately free up space (OOM). In other words, the kernel acts in user space to preserve the sanity of the system as a whole.

With the existence of swap, the system starts to slow down, giving the kernel, or the user themselves, time to resolve the consequences without having to abruptly close a program and/or without the system crashing.

The Linux kernel moves rarely used memory pages to swap to ensure that even more cache space is available in memory for more frequently used memory pages (a page is a block of memory, usually 4KB). The use of swap becomes a performance problem when the kernel is pressured to continuously move memory pages between physical RAM and swap. This happens when a user manipulates the swappines parameter without knowing what they are doing.

Swap does not change the amount of RAM required for a healthy computer, whether server or desktop. It was designed to complement the performance of healthy systems.

It's like a food supplement; the name itself says it: it's a supplement, but in the sense of "what is added to a whole to expand or improve it"; and not in the sense of "what serves to supply some lack".

Swap can even supply a possible lack of physical RAM, but that's not why it was created.

The only and most appropriate way to supply a lack of physical RAM is by adding more physical RAM.

The linux/swap.h file is a central header of the Linux Kernel, located in the kernel sources at include/linux/swap.h. It should not be confused with sys/swap.h, which is the userspace header used for system calls like swapon and swapoff.

It expands the amount of memory a process can use. "Virtual memory" and "swap space" allow a large process to run even if it is only partially allocated in memory. Because "old" pages can be swapped, the amount of memory addressed can easily exceed RAM, since demand paging ensures that pages are reloaded when needed.


Difference and Relationship Between Virtual Memory and Swap


Virtual memory is a memory management technique that makes the operating system see RAM and a portion of the hard drive (HDD or SD card) as a single large, contiguous block of memory.

It creates an "illusion" for programs that they have much more RAM available than actually exists physically.

Each process gets its own virtual address space, isolated from others, which increases system security and stability.

Virtual memory is divided into small blocks called pages (usually 4 KB).

Swap (swap space), in relation to virtual memory, is the physical mechanism that virtual memory uses to function when real RAM becomes full.

When RAM is full and a new program needs space, the operating system takes data from programs that are open but not currently in use and "swaps" them into a reserved space (swap) on the hard drive.

"Swap space" can be an entire disk partition (common in Linux) or a specific file (such as pagefile.sys in Windows or swapfile in Linux).

Since hard drives and SD cards are slower than RAM, when the system needs to use swap space intensively, the computer starts to slow down (a phenomenon known as thrashing).




Free Memory and Available Memory


Don't be fooled by the "free" memory (using the `free` command) on your Linux system and jump to conclusions, as you must also consider available memory, which includes buffers/caches and other factors.

I won't elaborate further on this topic to avoid making the text too long.

In addition to the `free` command, you can also use the following commands to check your Linux system's memory usage:

`top` - Displays a system overview.
`htop` - Interactive process viewer and manager.
`atop` - For performance analysis of Linux servers.
`Glances` and `nmon` - alternatives to `top` and `htop`.
`vmstat` - Displays information about system memory, processes, interrupts, paging, block I/O, and CPU.
`cat /proc/meminfo` and others.

I repeat: The swap partition is becoming obsolete and, over time, will only be used in very rare circumstances, but the concept of swap remains and will continue to be very much alive.

On servers that require maximum predictability, a swap partition is advantageous because it eliminates fragmentation, eliminates file system dependencies, simplifies boot and recovery and some administrators prefer a separately encrypted swap partition.


Swap Partition vs. Swapfile


In the past, in Linux kernels from the 2.4 series and earlier, swap partitions were significantly faster for two reasons:

Direct block access: the kernel wrote data to the swap partition, completely bypassing the filesystem layer, such as Ext3 and Ext4. It was direct access to the raw disk.

File fragmentation: a swapfile resides within a filesystem. If the disk was too full or fragmented when the file was created, the swapfile would be scattered across the disk. On mechanical hard drives, this meant that the disk needle had to physically move to several different locations, destroying performance.

Starting with Linux Kernel 2.6, and fully consolidated in modern versions 6.x and 7.x, file management changed drastically thanks to a technique called block mapping.

When you activate a swap file (swapon /swapfile), Linux consults the file system, such as Ext4 or XFS, only once, at the moment of activation. It maps exactly which physical sectors of the disk that file is located in. Then the kernel creates a mental map of these blocks and, from that moment on, ignores the file system. When the Linux kernel needs to perform paging, it sends the data directly to the physical blocks of the disk, exactly the same way it would in a dedicated partition. The file system layer generates no overhead during use.

The performance difference between a swap partition and a swap file is currently irrelevant.


The Hardware Factor: HDs versus SD/NVMe Drives

The performance discussion has become even more irrelevant with the popularization of SD and NVMe drives. Without mechanical parts in an SD card, there's no needle to move. Access time to any block on the disk is practically instantaneous, regardless of whether the file is fragmented or not.

Systems like Ext4 allocate the blocks of a large file, such as a swap file created with `dd` or `fallocate`, contiguously by default, minimizing any fragmentation from the start.

However, there are specific scenarios related to the type of file system in your root directory (/). For example, Btrfs and ZFS.

Btrfs uses Copy-on-Write. To use a swap file in Btrfs, you need to explicitly disable CoW on that file with `chattr +C /swapfile`.

In ZFS, it's recommended to create a dedicated ZVOL within your pool to function as your swap partition. It's still simpler and safer in terms of performance than a swap file. Today, there are configurations that allow swapping over ZFS, but they still require specific care related to compression, snapshots, and memory management.


ZRAM vs. ZSWAP


The difference in choice is basically architectural.

In Fedora and Pop!_OS, for example, zswap became impractical for the standard of these distributions. ZRAM fit perfectly because it solves the problem of lack of memory without needing to touch the disk.

Anaconda and Fedora IoT have used swap-on-zRAM by default for years.

Basic Functions

The zRAM device, usually /dev/zram0, has a size defined at the time of creation, during system initialization, by the zram-generator, according to its configuration file. The memory used is not pre-allocated. It is allocated and deallocated dynamically, on demand. Due to compression, a fully populated /dev/zram0 uses half the memory corresponding to its size.

The `/dev/zram0` device behaves like any other block device. It can be formatted with a filesystem or with the `mkswap` command, which is the intention of this proposed change.

The system will use RAM normally until it is full, and then it will start using virtual memory, just like conventional disk swap. The zram driver starts allocating memory at approximately half the paging rate, due to compression. But, as the saying goes, there's no such thing as a free lunch. This means that swap-on-zram is not as efficient at removing pages as disk swap, with a removal rate of about 50% instead of 100%. Even so, it is at least ten times faster than disk-based swap.

ZRAM memory has an overhead of about 0.1%, or approximately 1 MiB per 1 GiB. If the workload never accesses swap memory, this overhead will be the only cost. In practice, when not in use, swap memory has an overhead of approximately 0.04%.

Example: A system has 16 GiB of RAM. The default settings suggest that the /dev/zram0 device will have 4 GiB. If the workload completely fills the swap area with 4 GiB of anonymous pages, what happens? The zramctl command will display the actual compression ratio. If a ratio of 2:1 is obtained, it means that 4 GiB of swap data were compressed to 2 GiB. Therefore, 2 GiB is the actual RAM usage and also the effective net removal. That is, 4 GiB of anonymous pages are removed, but are compressed and allocated to 2 GiB of RAM, resulting in a net memory saving of 2 GiB.


Zswap is a similar idea, aiming to accelerate page swapping, but with a different implementation. It requires a disk-based swap area and uses a compressed memory cache to store recently used pages, while less frequently used pages are moved to the swap area.

Swap-on-zram relies only on volatile storage. This is simpler and safer. However, removing pages to swap-on-drive via zswap can leak user data. Some workloads may perform better with zswap, and this is a valid future feature for this generator. One idea is for the generator to prioritize zswap configuration when swap-on-drive is already configured and, in case of failure, use swap-on-zram as an alternative.


General Guidelines for Distributions


ZRAM via distribution: This is advisable. The block size, compression algorithm, kernel aggressiveness, and security rules against crashes have been exhaustively tested by engineers and adapt to a wide variety of RAM, processor, and disk sizes, as they are enabled during installation, adapting to the hardware.

ZRAM via "RAM Optimizer" or magic script: This is Russian roulette. They focus on displaying nice numbers of free RAM in the system monitor, but break the kernel's internal logic, generating instability, processor wear, and sudden crashes.

They talk so much about freedom and system control, but they end up using programs whose creators, origins, and under-the-hood capabilities they don't even know.

If you want to create ZRAM or ZSWAP with the system already installed, always choose to install and configure the official package from the distribution itself, such as zram-generator in Fedora, Red Hat, and Arch, or zram-tools in Debian and Ubuntu, and let the official tools manage the hardware along with the kernel.

The zram module, zram.ko, present in the kernel since 2014, is used exclusively for ZRAM.

If you enable ZSWAP, the kernel will use completely different modules. Although both perform memory compression, they are separate technologies, written by different developers and operating in distinct ways within the Linux Kernel. ZSWAP does not create any virtual disk device. It intercepts memory pages that are on their way to a real swap on the HDD or SD card and compresses them into a hidden cache. Therefore, it does not use zram.ko.

ZSWAP is not a module that you load with modprobe. It is already compiled within the kernel. You enable or disable it by passing parameters directly to the system boot command line, such as `zswap.enabled=1`, or by modifying files in the kernel's virtual filesystem, such as `/sys/module/zswap/parameters/enabled`.

In 2013, Google released Android 4.4 KitKat. The main goal of that version of Android was to run smoothly on inexpensive phones with only 512 MB of RAM. To make this happen, Google enabled the zram module, which was still in the final testing phase in the Linux Kernel, by default in Android.

The resounding success of Android KitKat's memory management served as the final proof of concept that the Linux community needed to stabilize zram in Kernel 3.14 the following year.

If you are running Fedora, Pop!_OS, or Ubuntu, you can see the exact values ​​your kernel is currently using with these commands in the terminal:

$ sysctl vm.swappiness
$ sysctl vm.vfs_cache_pressure
$ sysctl vm.page-cluster

ZSWAP is a write cache, meaning it needs to mirror the behavior of physical swap.

If the swap partition is on the SD card, performance will be excellent. ZSWAP will retain most of the compressed data in RAM. If the ZSWAP cache fills up, it will dump the excess onto the SD card, which is a fast process due to the speed of the silicon.

If the swap partition is on the hard drive, ZSWAP becomes a lifesaver. Without it, when Linux needs to use the hard drive or SD card for swap, the computer simply freezes and crashes. With ZSWAP enabled, it holds almost all heavy swap traffic in compressed RAM. The slow hard drive or SD card will only suffer write traffic if you actually exhaust both RAM and ZSWAP at the same time.

If you have both a hard drive and an SD card in your machine and are configuring it manually, always place the physical swap partition or swap file on the SD card, because when ZSWAP needs to empty the cache, it will do so instantly, without crashing its interface.


SETTING UP ZRAM


Using zramen in Void
We will use the zramen tool from the Void repositories. It's quite simple.

$ sudo xbps-install -Syu
$ sudo xbps-install -S zramen
$ sudo vim /etc/sv/zramen/conf

Here I have 32 GB of physical RAM, so I left the configurations like this:

export ZRAM_COMP_ALGORITHM=zstd
#export ZRAM_COMP_ALGORITHM=lz4
export ZRAM_PRIORITY=32767
export ZRAM_SIZE=50
#export ZRAM_SIZE=25
export ZRAM_MAX_SIZE=16384
#export ZRAM_MAX_SIZE=4096
#export ZRAM_STREAMS=1
export ZRAMEN_SWAPON_DISCARD=both
#export ZRAMEN_QUIET=0

Save and exit.

ZRAM_COMP_ALGORITHM=zstd: I changed from lz4 to zstd, which compresses memory much more while using practically the same processing power, in my case.

ZRAM_SIZE=50: Defines that the zRAM size will be 50% of the physical RAM size (if you have 8GB of RAM, the zRAM will be 4GB). I left it at 30.

ZRAM_MAX_SIZE=16384: I increased the maximum limit to 16GB (16384 MB).

For example, if you have:

ZRAM_SIZE=50
ZRAM_MAX_SIZE=8192

and the computer has 32 GB of RAM:

50% of 32 GB = 16 GB.

But the maximum limit is 8 GB (8192 MB).

Therefore, the zRAM will be created with 8 GB, not 16 GB.

Another example:

export ZRAM_SIZE=30

30% of 32 GB = approximately 9.6 GB
ZRAM_MAX_SIZE=16384 = 16 GB
Since 9.6 GB is less than 16 GB, the maximum limit does not come into play.

The zram device will be created with approximately 9.6 GB.

In practice, ZRAM_MAX_SIZE=16384 will not make a difference.

On machines with plenty of memory (in this case, a desktop with 32 GB), zRAM changes its role: it ceases to be a "lifesaver" to prevent crashes and becomes a performance optimization tool, allowing the system to keep much more in cache (such as files and programs open in the background) without ever touching the SD/HD for traditional swapping, especially since I don't have a swap partition or swapfile.

At this point, an explanation is necessary.

Since I don't use hibernation, I haven't created a swap partition or swapfile, and the file system is BTRFS. If you use hibernation, it necessarily depends on a physical swap (on disk). Create a swap file the size of your physical RAM. If you have 16GB of physical RAM, create a 16GB swap file and point hibernation to it.

You will have two active swap areas with very different priorities:

zRAM (/dev/zram0) -> Maximum priority (32767)
Swapfile (/swapfile) -> Low priority (e.g., -2 or 10)

In normal use, the Kernel would only use zRAM. However, since its priority is extremely higher, the disk swap file remains idle almost all the time (close to 0% usage), preserving the lifespan of your HDD/SD card and maintaining maximum system speed.

When hibernating, if you click "Hibernate," the system will take everything in your physical RAM (and zRAM), decompress it, and dump that image directly into the swapfile on the HDD/SD card. The computer will then shut down completely.

When you turn the PC back on, the Kernel will read the swapfile on the HDD/SD card, pull the system state back into RAM, and you will continue exactly where you left off.

The Suspend/Sleep function, which puts the computer into a low-power state without turning off the memory power, continues to work perfectly and instantly with zRAM alone.

For a 32 GB scenario, setting zRAM to 100% (generating a 32 GB compressed block) is overkill in most common use cases, unless you work with dozens of virtual machines, 8K video editing, and compiling large software projects (like the Linux Kernel itself), which is not my case, so I left it at 50%.

Now we see why it's dangerous to use one of those "RAM Optimizers" or one of those "Magic Scripts" that promise to give your PC super-mega-blaster power, capable of even reaching Super Saiyan Blue God level and performing a Kamehameha that will destroy the universe.

These optimizations depend on several individual hardware factors and, as already mentioned, operating systems that come with these optimizations do so during installation and have been extensively tested, because no distribution wants to "ruin its reputation" by releasing a system that risks, instead of optimizing, having the opposite effect: constantly slow and/or crashing.

$ sudo mkdir -p /etc/sysctl.d
$ sudo vim /etc/sysctl.d/99-zram.conf

Place it inside, adapting it to your settings:

vm.vfs_cache_pressure=100
vm.swappiness=100
vm.dirty_background_ratio=1
vm.dirty_ratio=50
vm.page-cluster=0

Save and exit.

vm.vfs_cache_pressure=500 – Increases cache pressure, which increases the kernel's tendency to reclaim memory used for directory and inode object caching. You will use less memory for a longer period. The disadvantage of using swap earlier is offset by the performance loss.

The default is 100, 500 is quite aggressive, as it avoids storing file and directory cache (VFS) in memory as much as possible and makes the kernel clear this cache as soon as possible.

vm.swappiness=100 – Increases the aggressiveness with which the kernel will swap memory pages, as it uses ZRAM first.

I want the kernel to move inactive data there as soon as possible to keep real RAM always clean and full of useful file cache, so I left it at 100.

vm.dirty_background_ratio=1 – Background processes will start writing immediately when they reach the 1% limit.

vm.dirty_ratio=50 – The system will not force synchronous I/O until it reaches 50% dirty_ratio.

vm.page-cluster=0 – This parameter controls how many memory pages the Linux Kernel reads from or writes to Swap at once, in a single block. The calculation is done in powers of 2. When it is at 3, for example (2 to the power of 3 = 8), the Kernel processes 8 pages at a time (which gives 32 KB of data) and the Kernel will attempt to read/write in 32 KB blocks.

When changed to 0 (2 to the power of 0 = 1), the Kernel processes only 1 page at a time (4 KB of data).

Furthermore, since zRAM is inside the RAM itself, there is no physical seek latency.

$ sudo ln -s /etc/sv/zramen /var/service/
$ sudo sysctl --system
$ sudo sv restart zramen

Checking:
$ zramctl

Output:

NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 zstd 15.5G 4K 64B 20K [SWAP]

An interesting detail to observe is the compression in practice; even with the system almost unused, it took 4K of data from memory, compressed it to a mere 64B (an absurd compression rate!), and the total cost in physical RAM was only 20K of metadata.

$ free -h

Output:
                total      used      free      shared      buff/cache     available
Mem.:     31Gi      2,5Gi    24Gi      61Mi          4,3Gi          28Gi
Swap:     15Gi       0B        15Gi

$ swapon --show

Output:
NAME                    TYPE                  SIZE              USED          PRIO
/dev/zram0   partition   15,5G     0B     32767


SETTING UP ZSWAP


I have a 10 GB swap partition and 24 GB of physical RAM.

In Void Linux, zswap is already part of the Linux kernel. Unlike zram, it doesn't require creating a compressed swap device, as zswap acts as a compressed cache in RAM for pages that would otherwise be written to your actual swap, in this case, the 10 GB partition.

Checking if the kernel has zSWAP:
$  zgrep ZSWAP /proc/config.gz

CONFIG_ZSWAP=y
# CONFIG_ZSWAP_DEFAULT_ON is not set
# CONFIG_ZSWAP_SHRINKER_DEFAULT_ON is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set
CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO=y
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4 is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD is not set
CONFIG_ZSWAP_COMPRESSOR_DEFAULT="lzo"

Checking the compressor being used:
$ cat /sys/module/zswap/parameters/compressor

Output:
lzo

Checking compressors support:
$ grep -E 'name|driver' /proc/crypto | grep -A1 -B1 'zstd\|lz4\|lzo'

Output:
driver : pkcs1(rsa-generic,sha512) name : zstd driver : zstd-generic name : jitterentropy_rng -- driver : drbg_pr_hmac_sha384 name : lzo-rle driver : lzo-rle-scomp name : lzo driver : lzo-scomp name : deflate


Temporarily changing to zstd:
$ sudo sh -c 'echo zstd > /sys/module/zswap/parameters/compressor'
$ cat /sys/module/zswap/parameters/compressor

Output:
zstd

Checking if zSWAP is active:
$ cat /sys/module/zswap/parameters/enabled

Output:
N

Temporarily activating:
$ sudo sh -c 'echo 1 > /sys/module/zswap/parameters/enabled'
$ cat /sys/module/zswap/parameters/enabled
Y

Testing:
$ cat /sys/module/zswap/parameters/enabled
$ cat /sys/module/zswap/parameters/compressor
$ cat /sys/module/zswap/parameters/max_pool_percent

Y
zstd
20

Monitoring:
$ watch -n1 "grep -E 'stored_pages|pool_total_size' /sys/kernel/debug/zswap/* 2>/dev/null"

When stored_pages starts to increase, zswap will be working. If the compressor is set to zstd, you'll be taking advantage of a generally better compression ratio than lzo, at the cost of slightly more CPU—something that's usually not a problem on modern machines with 24 GB of RAM.


Making it permanent


Since I use Grub, I'll make the changes there. If you use a different boot manager, make the changes there. You can also create a startup script, but in that case, it only works if zswap is a loadable module, and it will only start working from that point on. Any previous swap activity will not have passed through zswap. Some zswap options are safer to set before it starts storing pages, so a startup script is not advisable in this case.

$ sudo vim /etc/default/grub

Here, the line ended up like this, respecting what was already in place by default:

GRUB_CMDLINE_LINUX_DEFAULT="loglevel=4 zswap.enabled=1 zswap.compressor=zstd zswap.max_pool_percent=20"

Save and exit.

$ sudo grub-mkconfig -o /boot/grub/grub.cfg

Reboot.

Testing:
$ cat /sys/module/zswap/parameters/enabled
$ cat /sys/module/zswap/parameters/compressor
$ cat /sys/module/zswap/parameters/max_pool_percent

Y
zstd
20

Monitoring:
$ watch -n1 "grep -E 'stored_pages|pool_total_size' /sys/kernel/debug/zswap/* 2>/dev/null"


CONFIGURING ZSWAP + ZRAM


It is not advisable to use zSWAP + zRAM if you have 16 GB or more of RAM and an SD/NVMe drive. In that case, it's better to use only one of them to avoid redundancy, extra latency, and unnecessary contention.

In this scenario, we have a 10 GB swap partition, zSWAP, and zRAM, plus 24 GB of RAM, which will be used to demonstrate the configuration.

$ sudo xbps-install -Syu
$ sudo xbps-install -S zramen
$ sudo vim /etc/sv/zramen/conf

With 24 GB of physical RAM, the specifications were as follows:

export ZRAM_COMP_ALGORITHM=zstd
#export ZRAM_COMP_ALGORITHM=lz4
export ZRAM_PRIORITY=20
export ZRAM_SIZE=30
#export ZRAM_SIZE=25
export ZRAM_MAX_SIZE=7168
#export ZRAM_MAX_SIZE=4096
#export ZRAM_STREAMS=1
export ZRAMEN_SWAPON_DISCARD=both
#export ZRAMEN_QUIET=0

$ sudo mkdir -p /etc/sysctl.d
$ sudo vim /etc/sysctl.d/99-zram.conf

vm.vfs_cache_pressure=100
vm.swappiness=5
vm.dirty_background_ratio=5
vm.dirty_ratio=25
vm.page-cluster=0

$ sudo ln -s /etc/sv/zramen /var/service/
$ sudo sysctl --system
$ sudo sv restart zramen

$ sudo vim /etc/fstab

UUID=d8ec1c2f-c80e-4f93-b812-16b6e3f27a56 / btrfs defaults 0 0
UUID=0243b5bc-f07f-4f36-b324-7ed3c589737c none swap sw,pri=80 0 0 <<< adjustment
UUID=175A-E049 /boot/efi vfat defaults 0 2
tmpfs /tmp tmpfs defaults,nosuid,nodev 0 0

Reboot the machine:

$ cat /proc/swaps

Filename     Type             Size         Used     Priority
/dev/sdb6     partition     10528764     0             80
/dev/zram0  partition     7282684        0            20


If it were a swapfile instead of a swap partition, you would do this in /etc/fstab:

/swapfile none swap sw,pri=80 0 0


with the following settings:
$ sudo truncate -s 0 /swapfile

Remember that with BTRFS, CoW must be disabled.
$ sudo chattr +C /swapfile

$ sudo fallocate -l 8G /swapfile
$ sudo chmod 600 /swapfile<br/>
$ sudo mkswap /swapfile<br/>
$ sudo swapon -p 100 /swapfile

Here's a suggestion for /etc/fstab with a swap partition and swapfile, if you want to go all out:

$ swapon --show
UUID=SSD_SWAP none swap sw,pri=100 0 0
/swapfile none swap sw,pri=80 0 0


Reading statistics and monitoring conflicts:
$ sudo mount -t debugfs none /sys/kernel/debug
$ sudo grep -r . /sys/kernel/debug/zswap/

/sys/kernel/debug/zswap/stored_incompressible_pages:0
/sys/kernel/debug/zswap/stored_pages:0
/sys/kernel/debug/zswap/pool_total_size:0
/sys/kernel/debug/zswap/written_back_pages:0
/sys/kernel/debug/zswap/decompress_fail:0
/sys/kernel/debug/zswap/reject_compress_poor:0
/sys/kernel/debug/zswap/reject_compress_fail:0
/sys/kernel/debug/zswap/reject_kmemcache_fail:0
/sys/kernel/debug/zswap/reject_alloc_fail:0
/sys/kernel/debug/zswap/reject_reclaim_fail:0
/sys/kernel/debug/zswap/pool_limit_hit:0

No data passed through zswap because all metrics are zero (0), meaning the system hasn't needed to use swap yet (USED 0B).

Monitoring:
$ 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

$ sudo xbps-install sysstat
$ iostat -x 1

Linux 6.18.33_1 (cservidor) 01/06/2026 _x86_64_ (4 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle
3,21 0,00 1,68 0,15 0,00 94,96

Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
sda 0,03 0,41 0,00 0,00 1,58 13,52 0,00 0,00 0,00 0,00 3,33 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 3,33 0,00 0,00
sdb 4,95 870,91 0,44 8,11 1,04 175,90 9,12 241,44 3,95 30,24 1,06 26,48 0,19 226,70 0,00 0,00 0,26 1223,79 0,58 0,96 0,02 0,43
zram0 0,01 0,13 0,00 0,00 0,00 17,42 0,00 0,00 0,00 0,00 0,00 4,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00

avg-cpu: %user %nice %system %iowait %steal %idle
2,01 0,00 1,00 0,00 0,00 96,99

$ vmstat 1

procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
r b swpd free buff cache si so bi bo in cs us sy id wa st gu
1 0 0 17382204 2340 5781140 0 0 856 242 1264 4 3 2 95 0 0 0
0 0 0 17381888 2340 5781204 0 0 0 788 1223 2131 6 2 93 0 0 0
1 0 0 17381888 2340 5781204 0 0 0 0 3156 4369 7 5 88 0 0 0

SCHEME


It is not advisable to use zRAM together if you have 16 GB or more of RAM and an SD/NVMe card. In that case, it is better to use only zSWAP or zRAM to avoid redundancy, extra latency and unnecessary contention.


CONCLUSION

Are ZRAM or ZSWAP really necessary?

The kernel was designed to work with swap.

Don't be afraid to experiment with zRAM and/or zSWAP. Both can function as a performance optimization tool, but they aren't necessary. Usually you choose one or the other.

While it's possible to combine the two, this usually increases complexity without bringing much benefit to a typical desktop, although this is the trend: prioritize configuring zswap when swap-on-drive is already configured and, in case of failure, use swap-on-zram as an alternative, thus achieving the best possible outcome.

Monitor swap usage (swapon --show, free -h), try different pool sizes and compressors, and – most importantly – don't forget the easiest solution of all: add more physical RAM.

If your only storage is a 5400 rpm HDD or an old/slow SATA SD card, the cost of writing uncompressed pages to the disk is high.

zram can prevent these writes completely until the compressed drive is full.

In a system with 2 to 4 GB of RAM, which rarely swaps more than one or two gigabytes of disk space, zram will be faster than zswap.

For transient workloads that require temporary RAM disk space, zram is more suitable because it creates block devices; you can format them as ext4 or XFS and use them as /tmp or /var/cache to speed up builds and tests. The kernel documentation also mentions this.


ZRAM, a technology that compresses and stores memory pages in RAM instead of transferring them to disk or SSD, is a valuable tool in situations where memory is limited.

Swap is necessary even when RAM is available. The Linux kernel intelligently uses swap space to manage memory pages efficiently, ensuring that frequently used pages remain in memory, while less frequently used ones are moved to swap. Now we see why it's dangerous to use one of those "RAM Optimizers" or one of those "Magic Scripts" that promise to give your PC super-mega-blaster power, capable of reaching Super Saiyan Blue God level and performing a Kamehameha that will destroy the universe.

ZRAM via "RAM Optimizer" or Magic Script is Russian roulette. They focus on showing "nice numbers" of free RAM in the system monitor, but they break the internal logic of the Kernel, generating instability, processor wear, and sudden crashes.

The problem with many of these "RAM optimizers" is that they end up harming the system. In tests, I had the unpleasant experience of, upon uninstalling one of these "RAM optimizers" and restarting, it broke the system; that is, it passed the first phase of initialization and Grub, but, in addition to not entering the system, it shut down the computer.

They talk so much about "freedom" and "control of the system," but they end up using programs without even knowing who made them, where they came from, or what's under the hood.

No swap program replaces adding more RAM to your computer; zRAM and/or zSWAP do not replace adding more RAM.

REFERENCES




domingo, 17 de maio de 2026

Imaginação


Imaginação vem do Latim imaginatìo[ónis] 'imagem, representação, visão; pensamento, ideia; ilusão', cuja raiz vem do Latim imágo (semelhança, representação, retrato).

Imago também foi um conceito utilizado por Jung e Freud para descrever estruturas como Imago Paterna ou Materna. Na psicanálise, Imago é uma representação inconsciente e idealizada de pessoas formada na infância, indica uma "imagem inconsciente" construída cedo na vida e investida de energia pulsional.

Imago, em outro sentido, pode ser "imagem mental abstrata", ou seja, aquilo que conhecemos como "conceito".

Quando você faz um conceito de algo e/ou alguém, você está criando uma imagem mental abstrata na sua mente que pode ou não estar em harmonia com a realidade. "Abstrata" aqui, no sentido de que não é concreto, que resulta da abstração (situação temporária na qual o indivíduo retira sua atenção de tudo que o cerca e volta-se para seus próprios pensamentos nos quais o objeto de reflexão pode ser ou não isolado de fatores que comumente lhe estão relacionados na realidade).

Se estiver em harmonia com a realidade chama-se Imaginação, se não estiver em harmonia com a realidade chama-se Adivinhação.

Toda imaginação vem de algum conhecimento gerando um ciclo onde não se sabe quem veio primeiro.

Não confunda Imaginação com Adivinhação. Esta não vem do conhecimento, Adivinhação é puramente uma ilusão muitas vezes confundida com Imaginação e a Imaginação é que acaba levando a culpa.

Adivinhação vem de "adivinhar" (descobrir ou desvendar por supostos meios sobrenaturais, supranormais ou por engenhosos artifícios), muitas vezes confundimos Adivinhação com Imaginação.

Por exemplo: muitas vezes a imagem na mente (como a do sujeito traído em relação à esposa "fiel"), nesse sentido, a Adivinhação pregou uma peça nele, pois ele criou uma Adivinhação na mente (desarmonia com a realidade) e não uma Imaginação, posto que esta vem de algum conhecimento prévio.

O processo de Adivinhar não envolve conhecimento, o processo de Imaginar envolve conhecimento.

Quando Einstein [supostamente?] disse: A imaginação é mais importante do que o conhecimento, ele não quis excluir uma do outro, pois se sabe que Imaginação e Conhecimento são equiparáveis (a sua importância depende da situação), uma não vive sem o outro, são inseparáveis.

Quando dizem: "você está imaginando coisas..." é uma expressão correta, porém, geralmente estão querendo dizer que você está adivinhando coisas, ou seja, exprimem-se incorretamente.

Em construção...


sábado, 28 de março de 2026

POR QUE SEU __DIR__ FALHOU OU O "INFERNO" DOS CAMINHOS NO PHP

POR QUE SEU __DIR__ FALHOU?

O que ganharei lendo este artigo?

Domínio de Escopo: Aprenderás que diretórios (pastas) e subdiretórios mudam a percepção do PHP.
Segurança com Constantes: Aprenderás a "travar" o caminho real do projeto para não depender tanto de onde o script está rodando.

Warning: fopen(leitura.txt): Failed to open stream: No such file or directory in/caminho/da/mente/do/ledor/inteligencia.php on line 0
Caro ledor, caso não quiser ler, na Conclusão tem um resumo (receitinha de bolo)!

No desenvolvimento web, existem três "raízes" diferentes acontecendo ao mesmo tempo no teu projeto|site|aplicativo, etc:

1- A Raiz do servidor web (DocumentRoot):
Depende de como você instala, geralmente, no Apache, é o /var/www/html no Linux e C:\Apache24\htdocs no Windows.
No Nginx geralmente é C:\nginx\html e /var/www/html ou /usr/share/nginx/html.
São o popular e famoso "localhost".
O Apache, Nginx, etc, olha para lá para saber onde o projeto|site|aplicativo começa.

2- A Raiz do Navegador (URL):
Quando você coloca barra (/) no HTML (ex.: <img src="/foto.jpg">), o navegador busca na raiz do domínio(localhost/foto.jpg), ignorando as pastas do site.

3- A "Raiz" do Script PHP (__DIR__):
É onde está o arquivo físico no SD|HD naquele momento, ou seja, para o PHP, a raiz é o diretório onde está o arquivo|script e é a partir deste diretório que o PHP vai procurar os arquivos chamados.

Parece complicado, mas confunde-se pela simplicidade.

Em vez de se fazer sempre essa pergunta programando em PHP: "onde estou para chamar os arquivos que quero?", veremos a maneira correta, bem mais simples.

Se estou no arquivo.php no caminho /pasta1/pasta2/arquivo.php então a raiz (__DIR__) para o PHP é a pasta2.

Se mudar o arquivo.php para a pasta1, então a raiz agora para o PHP é a pasta1.
É aquele negócio de ir e voltar diretórios|pastas (../../).

A bússola que te dava o norte era: onde estou? ...quem sou eu... de onde viemos, para onde vamos? Essa última parte foram apenas divagações minhas!
Tinha de se raciocinar a partir da pasta|diretório no qual está o arquivo onde se chamaria outros arquivos.

Então, o problema não é a constante __DIR__ em si, mas onde ela é definida.
Se tu cria e define, por exemplo, a constante RAIZ_SIS dentro do diretório /pasta3/, ela "nasce" com o DNA dessa pasta, ou seja, para o PHP essa é a "pasta raiz" a partir de onde ele vai procurar os arquivos.
Se tu usar essa mesma lógica em outro arquivo que não esteja dentro dessa mesma pasta, a constante terá outro valor.
Isso é o que causava e causa a confusão.

Por exemplo:
if (!defined('RAIZ_SIS')) {
define('RAIZ_SIS', __DIR__ . DIRECTORY_SEPARATOR);
}
sendo que RAIZ_SIS é o caminho real /opt/apache24/htdocs/pasta1/pasta2/, pois pasta2 é a "raiz" do projeto, do site, do aplicativo, etc.

Poderia ser /opt/apache24/htdocs/pasta1/ e daí pasta1 seria a "raiz", o diretório principal (__DIR__) do teu projeto, do teu site, do teu aplicativo, etc, és tu quem decides, pois o projeto é teu, bem como a culpa se tu errar, ela é tua, porém, justamente por ser tua, depois tu atribui esse parâmetro (a culpa) para quem tu quiser, mas vamos usar a estrutura pasta1/pasta2 para exemplificar.

EXEMPLOS

Lembrando que, em vez de /opt/apache24/htdocs/pasta1/pasta2/ pode ser /var/www/html/pasta1/pasta2 ou C:\Apache24\htdocs\pasta1\pasta2\ ou onde tu quiser de acordo com o que o sistema operacional permitir.

Lembrando também que:

DIRECTORY_SEPARATOR Janelas = \
DIRECTORY_SEPARATOR Linux|MacOS = /

Crio um diretório chamado "api" dentro de pasta2 que é a "raiz" (o diretório principal) do projeto.
O caminho para "api" é /opt/apache24/htdocs/pasta1/pasta2/api.

A partir de agora colocarei somente /pasta1/pasta2/, mas entenda que o localhost está antes.

Lembrando que /opt/apache24/htdocs e C:\Apache24\htdocs e /var/www/html são, por padrão, o famoso localhost no Linux e no Janelas, aquele que, quando tu digita localhost na barra de endereços, o Apache grita It works! porque encontrou o arquivo index.html (C:\Apache24\htdocs\index.html) e dentro dele tem escrito It works e se fica todo feliz porque conseguiu fazer o Apache funcionar.

No Linux, o localhost na instalação padrão é /var/www/html (a não ser que tu mude, mas ai é problema teu, não meu).

Você, caro leitor, se for uma pessoa inteligente, deve ter percebido a diferença do Linux para o Janelas do "detalhe" das barras separadoras que formam o caminho para os diretórios e arquivos.
Já veremos esse "detalhe" também.

Antes, caro leitor, veremos uma coisa chamada Estratégia do "Ponto de Entrada Único", do conceito de estratégia, em grego strateegia, em latim strategi, em francês stratégie... os senhores estão anotando?

Nessa estratégia profissional utilizamos um arquivo central chamado config.php ou autoload.php oude_o_nome_que_quiser.php na raiz real do projeto, ou seja, no nosso caso:/pasta1/pasta2/de_o_nome_que_quiser.php.

Neste arquivo definimos as constantes com seus caminhos que utilizaremos no projeto|site|aplicação, etc.

Define-se, por exemplo, a constante RAIZ_SIS (ou DE_O_NOME_QUE_QUISER, agora na versão maiúscula) uma única vez nesse arquivo de configuração.

Segue um exemplo:

<?php
// Este arquivo autoload.php fica na RAIZ do projeto|site|aplicativo...
// __DIR__ aqui SEMPRE serah a raiz.
// dirname(__DIR__) recua um nivel na estrutura de pastas (Funcao Nativa).
// Exemplo: dirname(__DIR__) . DIRECTORY_SEPARATOR . "autoload.php";
// __DIR__ . DIRECTORY_SEPARATOR; = C:\Apache24\htdocs\pasta1\pasta2\
// Janelas - RAIZ_SIS (ou PATH_ROOT) = C:\Apache24\htdocs\pasta1\pasta2\
// Linux - RAIZ_SIS (ou PATH_ROOT) = /opt/apache24/htdocs/pasta1/pasta2/
// Define a URL base do site:
// define('URL_BASE', 'http://localhost/pasta1/pasta2');
// PATH_ROOT: Caminho absoluto no disco (para utilizar com file_put_contents, require, include, etc).
// URL_BASE: Caminho do navegador (para utilizar com href, src de imagens, etc).
// DIRECTORY_SEPARATOR Janelas = \
// DIRECTORY_SEPARATOR Linux|MacOS = /
if (!defined('RAIZ_SIS')) {
    define('RAIZ_SIS', __DIR__ . DIRECTORY_SEPARATOR);
}
if (!defined('PASTA_API')) {
    define('PASTA_API', RAIZ_SIS . 'api' . DIRECTORY_SEPARATOR);
}

Aproveitamos e já definimos, também, uma constante para o diretório api chamada PASTA_API, cujo caminho é /opt/apache24/htdocs/pasta1/pasta2/api/.

Repare, vivente, que no final da tripa tem uma barra (/ ou \), essa é a constante predefinida DIRECTORY_SEPARATOR agindo.
O PHP identifica o sistema operacional e essa constante, se for chamada, finca no final da tripa a barra de acordo com o sistema operacional.

E assim tu vai, alegremente, definindo e/ou utilizando as constantes necessárias.

Lembrando que __DIR__ é uma das constantes mágicas do PHP.

Da página do PHP:

__DIR__ - "O diretório do arquivo. Se usada dentro de um include, o diretório do arquivo incluído será retornado.
Isso é equivalente a dirname(__FILE__).
O nome do diretório não possui barra no final, a menos que seja o diretório raiz."
Explica nada e diz coisa nenhuma.

Exemplo Real

Nesse exemplo real tenho essas chamadas aos arquivos:

require_once __DIR__ . DIRECTORY_SEPARATOR . 'autoload.php';
require_once PASTA_API . 'proc_criar.php';

E dentro do arquivo proc_criar.php tenho estas definições:

$arquivoCursos = RAIZ_SIS . 'cursos.txt';
$arquivoBkpExtra = $pastaExtra . DIRECTORY_SEPARATOR . 'cursos_bkp_extra.txt';
Criei um arquivo "teste.php", coloquei dentro o conteúdo abaixo para solucionar essa bagunça:

require_once  __DIR__ . DIRECTORY_SEPARATOR . "autoload.php";
$arquivoCursos = RAIZ_SIS . 'cursos.txt';
$pastaExtra = RAIZ_SIS . 'copiados';
$arquivoBkpExtra = $pastaExtra . DIRECTORY_SEPARATOR . 'cursos_bkp_extra.txt';
die("Caminho Real: " . realpath($arquivoBkpExtra));

Executei o arquivo e na saída auto-explicativa apareceu:

Caminho Real: C:\Apache24\htdocs\pasta1\pasta2\copiados\cursos_bkp_extra.txt
e
Caminho Real: /opt/apache24/htdocs/pasta1/pasta2/copiados/cursos_bkp_extra.txt

E executei também:

require_once  __DIR__ . DIRECTORY_SEPARATOR . "autoload.php";
$arquivoCursos = RAIZ_SIS . 'cursos.txt';
die("Caminho Real: " . realpath($arquivoCursos));
$pastaExtra = RAIZ_SIS . 'copiados';
$arquivoBkpExtra = $pastaExtra . DIRECTORY_SEPARATOR . 'cursos_bkp_extra.txt';

Saída:
Caminho Real: C:\Apache24\htdocs\pasta1\pasta2\cursos.txt
e
Caminho Real: /opt/apache24/htdocs/pasta1/pasta2/cursos.txt

Se tu mudar o nome da pasta "pasta2" para "projeto_final", não precisa mexer em nada porque o __DIR__ no arquivo central se atualiza sozinho.

RAIZ_SIS será exatamente a mesma string em qualquer lugar do sistema.
Se tu escrever "require_once RAIZ_SIS . 'cursos.txt'", o PHP sempre buscará o arquivo na pasta principal, esteja você no diretório /api/, /admin/ ou no index.php ou na casa do ... .

Se o arquivo ficasse dentro da pasta api, você usaria a constante que definiu no arquivo central: include_once PASTA_API . 'arquivo'.

Obs.: Ao usar a função realpath, o script em execução deve ter permissões de executável em todos os diretórios na hierarquia, caso contrário realpath() retornará false.

Liberdade total.
O PHP é o Linux das linguagens de programação!

CAMINHOS ABSOLUTOS E CAMINHOS RELATIVOS

Evitando o Inferno e Indo para o Céu

Não tem necessidade de usar explicitamente caminhos absolutos e/ou relativos em PHP.
No HTML, se você está em api/proc_criar.php e quer voltar para a raiz, você usa ../.
No PHP, se você usa __DIR__, ele te entrega o caminho completo do Windows/Linux/MacOS até aquela pasta específica.

Imagine que você tem o arquivo "processa.php" dentro da pasta api.

No Servidor (Linux): __DIR__ é /var/www/html/projeto/api
No seu PC (Windows): __DIR__ é C:\Apache24\htdocs\projeto\api

Temos esses arquivos nesses caminhos:
/var/www/html/projeto/api/processa.php;
/var/www/html/projeto/api/fincao.php;
/var/www/html/projeto/autoload.php;
ou
C:\Apache24\htdocs\projeto\api\processa.php
C:\Apache24\htdocs\projeto\api\fincao.php
C:\Apache24\htdocs\projeto\autoload.php

Quando você escreve no topo do arquivo processa.php:
require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . "autoload.php";
require_once "fincao.php";
o PHP resolve isso "em tempo de execução".

A função nativa dirname retorna o caminho para o diretório pai, sendo que o diretório pai é um diretório acima.
O PHP não tem uma função nativa, por exemplo, childname, que avançasse para um diretório abaixo e nem precisa ter.

Ele (e você) não precisam mais ficar calculando onde estão e para onde ir.
O caminho do arquivo e as instruções estão ali, explícitos: mais explícitos do que um site pornográfico!
Isso funciona em qualquer sistema operacional e em qualquer pasta, desde que a estrutura de pastas do seu projeto continue a mesma.
Tu só teria de atualizar as chamadas se resolvesse mudar a estrutura de pastas do teu projeto, por exemplo, tirar um arquivo de dentro da pasta api e colocar ele na raiz.

Se a estrutura interna (diretórios e arquivos) for mantida, o código é 100% portátil.

Se um dia tu resolver atirar teu site do Janelas para Linux ou vice-versa, precisa fazer absolutamente nada, pois:

DIRECTORY_SEPARATOR Janelas = \
DIRECTORY_SEPARATOR Linux|MacOS = /

O próprio PHP se encarrega do trabalho.

Não coloque barras junto ao nome do arquivo chamado no require|include, coloque a constante predefinida DIRECTORY_SEPARATOR separada por um espaço e um ponto de cada lado, além de ser o jeito certo, a sintaxe fica linda de morrer! Fica um must!!!

Contudo, porém, todavia, entretanto, sempre dá para melhorar!

Imagine que teu projeto|site|aplicação cresceu e agora tu tem:

projeto/modulos/financeiro/scripts/processar.php

Em vez de escrever:

$arquivo = "../../../../cursos.txt"; (onde é fácil errar a quantidade de pontos e barras)

tu apenas faz:

$arquivo = RAIZ_SIS . 'cursos.txt';
É mais fino, elegante e sincero!

Pare de usar essa coisa pré-histórica de código morse: ../../.

Utilize constantes definidas por você junto com DIRECTORY_SEPARATOR (constante predefinida) E SEUSPROBLEMAS ACABARAM!!!

Repare vivente:

require_once __DIR__ . '/../arquivo.php';
Caminho Real: /opt/apache24/htdocs/pasta1/pasta2/pasta3/arquivo.php

Fica:
require_once RAIZ_SIS . 'pasta3'. DIRECTORY_SEPARATOR . 'arquivo.php';
Caminho Real: /opt/apache24/htdocs/pasta1/pasta2/pasta3/arquivo.php

O caminho do arquivo e as instruções estão ali, mais explícitos do que um site pornográfico!
Isso funciona em qualquer sistema operacional e em qualquer pasta, desde que a estrutura de pastas do seu projeto continue a mesma.
Lembrando que RAIZ_SIS = /opt/apache24/htdocs/pasta1/pasta2.

Caso um determinado diretório seja bastante utilizado, crie uma constante para ele dentro do autoload.php(ou config.php ou de_o_nome_que_quiser.php).

Com a constante DIR_PASTA3, o "include_once RAIZ_SIS . 'pasta3'. DIRECTORY_SEPARATOR .'arquivo.php';" transforma-se em:

include_once DIR_PASTA3 . 'arquivo.php';
É muito mais fino, mais elegante e mais sincero ainda!
Nem vou falar da facilidade, porque é óbvio.

O caminho real é, por exemplo,
/opt/apache24/htdocs/projeto/modulos/api/arquivo.php, pois DIR_PASTA3 é /var/www/html/projeto/modulos/api/, já com a barra (/) no final, pois ela foi definida junto com a constante no arquivo central.

Sem o arquivo central autoload|config|de_o_nome_que_quiser.php, em cada diretório do teu sistema (no/api, no /admin, no /relatorios, etc), você tem de calcular manual e mentalmente onde está cada arquivo a ser chamado.
Se você mudar o arquivo de lugar, tem que editar todos os arquivos referenciados.
Com o arquivo central só precisa acertar o arquivo central, por isso se chama arquivo central, porque centraliza centralizando a centralização.

Uma vez que o arquivo central de constantes foi carregado, todas as variáveis de caminho ($arquivoCursos, $arquivoBackup, $arquivoseilaoque, etc) funcionam magicamente com o mesmo nome em qualquer lugar, sem precisar calcular manual e mentalmente.

Com isso evita o inferno e vai para o céu.

Liberdade total.
O PHP é o Linux das linguagens de programação!

CONCLUSÃO

Utilize a constante mágica __DIR__ do PHP para chamar arquivos.
Utilize a propriedade do PHP de criar constantes.
Utilize as constantes predefiniddas do PHP.
Utilize, em especial, as constantes predefinidas DIRECTORY_SEPARATOR e dirname.

DIRECTORY_SEPARATOR Windows = \
DIRECTORY_SEPARATORLinux|MacOS = /

Em vez de escrever:
$arquivo = "../../../../cursos.txt"; (onde é fácil errar a quantidade de pontos e barras).

Faça:
$arquivo = dirname(RAIZ_SIS, 3) . DIRECTORY_SEPARATOR . 'cursos.txt';

A função dirname aceita o formato acima onde RAIZ_SIS é a constante criada por você e 3 é o número de diretórios para retornar e buscar o arquivo desejado.

Utilize constantes definidas por você junto com DIRECTORY_SEPARATOR e dirname.

Exemplo:
require_once __DIR__ . '/../arquivo.php';
Caminho Real: /opt/apache24/htdocs/pasta1/pasta2/pasta3/arquivo.php

Defina a constante no arquivo central:
if (!defined('RAIZ_SIS')) {
    define('RAIZ_SIS', __DIR__ . DIRECTORY_SEPARATOR); }

Faça:
require_once RAIZ_SIS . 'pasta3'. DIRECTORY_SEPARATOR . 'arquivo.php';
Caminho Real: /opt/apache24/htdocs/pasta1/pasta2/pasta3/arquivo.php

ou melhor ainda:
arquivo = dirname(RAIZ_SIS, 1) . DIRECTORY_SEPARATOR . 'cursos.txt';
A função dirname aceita o formato acima onde RAIZ_SIS é a constante criada por você e 1 é o número de diretórios para retornar e buscar o arquivo desejado.

O caminho do arquivo e as instruções estão ali explicitamente.
Isso funciona em qualquer sistema operacional e em qualquer pasta, desde que a estrutura de pastas do seuprojeto continue a mesma.
Com o arquivo central com as constantes predefinidas e criadas/definidas por você (autoload.php,config.php, de_o_nome_que_quiser.php) só precisa acertar o arquivo central sem mexer em mais nada.

Uma vez que o arquivo central de constantes foi carregado, todas as variáveis de caminho ($arquivoCursos,$arquivoBackup, $arquivoseilaoque, etc) funcionam magicamente com o mesmo nome em qualquer lugar, sem precisar calcular manual e mentalmente.

Você só precisa ter o cuidado ao chamar o arquivo central de acordo com o arquivo que o chama.

Em um arquivo que está no mesmo diretório (diretório principal) do arquivo autoload.php:

require_once __DIR__ . DIRECTORY_SEPARATOR . "autoload.php";

Em um arquivo que está um diretório abaixo do diretório "raiz" onde está o arquivo autoload.php (dirnameretorna um nível):
require_once __DIR__ . DIRECTORY_SEPARATOR . "autoload.php";

Receita de Bolo

Levando-se em conta que o arquivo "carretel.php" esteja em um diretório abaixo do diretório "raiz" do site|projeto|aplicação, etc, o diretório principal, no caso, é a pasta2, ou seja, o arquivo está no caminho real:

/var/www/html/pasta1/pasta2/pasta3/carretel.php.

Para chamar outros arquivos no topo do arquivo "carretel.php":
require_once __DIR__ . DIRECTORY_SEPARATOR . "bagoal.php"; <<< aqui tu caça um bagoal no mesmo diretório;
require_ONCE DIRNAME(__dir__) . DIRECTORY_SEPARATOR . 'fincao.php' <<< aqui tu encontra um fincao um diretório acima;
require_once RAIZ_SIS . 'api' . DIRECTORY_SEPARATOR . 'proc_criar.php'; <<< aqui tu deseja proc_criar um diretório abaixo;
$arquivoCursos = RAIZ_SIS . 'texticulo.txt'; <<< aqui tu pega o texticulo no mesmo nível e introduz o barbante numa variável.

Mais realmente e seriamente:
require_once __DIR__ . DIRECTORY_SEPARATOR . 'autoload.php'; <<< aqui busca autoload.php no mesmo diretório;
require_ONCE DIRNAME(__dir__) . DIRECTORY_SEPARATOR . 'funcao.php' <<< aqui busca funcao.php um diretório acima;
require_once RAIZ_SIS . 'api' . DIRECTORY_SEPARATOR . 'processa.php'; <<< aqui busca processa.php um diretório abaixo;
$arquivoCursos = RAIZ_SIS . 'cursos.txt'; <<< aqui busca cursos.txt no mesmo diretório e salva a string numa variável.

Liberdade total.
O PHP é o Linux das linguagens de programação!