> For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

<!--
Tab options on this page. Append to the .md URL to filter:
  ?tabs=<id,...>   select specific tabs (e.g. ?tabs=nodejs,shell)
  ?allTabs=true    include every tab
  (no param)       default: one tab per tabset

Available tabs:
  other tabs: systemd-systemctl, initd-service
-->

# TCMalloc Performance Optimization for a Self-Managed Deployment

**Changed in version 8.0**

Starting in MongoDB 8.0, MongoDB uses an upgraded version of TCMalloc that uses [per-CPU caches](https://www.mongodb.com/docs/manual/reference/glossary.md#std-term-per-CPU-cache), instead of [per-thread caches](https://www.mongodb.com/docs/manual/reference/glossary.md#std-term-per-thread-cache), to reduce memory fragmentation and make your database more resilient to high-stress workloads.

To use the new TCMalloc version:

- Use a [supported architecture.](https://www.mongodb.com/docs/manual/administration/tcmalloc-performance.md#std-label-tcmalloc-new-platform-support)

- [Enable THP.](https://www.mongodb.com/docs/manual/administration/tcmalloc-performance.md#std-label-tcmalloc-new-enable-thp)

- [Enable per-CPU caches.](https://www.mongodb.com/docs/manual/administration/tcmalloc-performance.md#std-label-tcmalloc-new-per-cpu-caches)

## Platform Support

Support for the updated TCMalloc depends on CPU architecture. Linux systems that support MongoDB 8.0 support the updated TCMalloc on the [x86\_64](https://www.mongodb.com/docs/manual/administration/production-notes.md#std-label-prod-notes-supported-platforms-x86_64) and [ARM64](https://www.mongodb.com/docs/manual/administration/production-notes.md#std-label-prod-notes-supported-platforms-ARM64) architectures only.

MongoDB uses the legacy TCMalloc version on the [PPC64LE](https://www.mongodb.com/docs/manual/administration/production-notes.md#std-label-prod-notes-supported-platforms-PPC64LE) and [s390x](https://www.mongodb.com/docs/manual/administration/production-notes.md#std-label-prod-notes-supported-platforms-s390x) architectures, regardless of operating system version. If you use one of these architectures, [disable THP.](https://www.mongodb.com/docs/manual/tutorial/disable-transparent-huge-pages.md#std-label-disable-thp)

Windows uses the legacy TCMalloc version and does not support the updated TCMalloc.

## Enable Transparent Hugepages (THP)

Transparent Hugepages (THP) is a Linux memory management system that reduces the overhead of Translation Lookaside Buffer (TLB) lookups. THP achieves this by combining small pages and making them appear as larger memory pages to the application.

In MongoDB 8.0 and later, ensure that THP is enabled before [`mongod`](https://www.mongodb.com/docs/manual/reference/program/mongod.md#mongodb-binary-bin.mongod) starts by creating a service file for your platform's initialization system. If you are using MongoDB 7.0 or earlier, [disable THP.](https://www.mongodb.com/docs/manual/tutorial/disable-transparent-huge-pages.md#std-label-disable-thp)

**Note:**

THP operates at a system level, so it applies to all processes under the system. You cannot enable or disable THP per-process level.

Additionally, for RHEL (Red Hat Enterprise Linux) and CentOS systems that use `ktune` and `tuned` performance profiles, you must also create a custom `tuned` profile.

### Create a Service File

To create a service file that enables THP, use the built-in initialization system for your platform. Recent versions of Linux typically use **systemd**, which uses the `systemctl` command. Older versions of Linux tend to use **System V init**, which uses the `service` command. For more information, see the documentation for your operating system.

Use the initialization system for your platform:

### systemd (systemctl)

1. Create the `systemd` unit file

   Create the following file and save it at `/etc/systemd/system/enable-transparent-huge-pages.service`:

   ```sh
   [Unit]
   Description=Enable Transparent Hugepages (THP)
   DefaultDependencies=no
   After=sysinit.target local-fs.target
   Before=mongod.service

   [Service]
   Type=oneshot
   ExecStart=/bin/sh -c 'echo always | tee /sys/kernel/mm/transparent_hugepage/enabled > /dev/null && echo defer+madvise | tee /sys/kernel/mm/transparent_hugepage/defrag > /dev/null && echo 0 | tee /sys/kernel/mm/transparent_hugepage/khugepaged/max_ptes_none > /dev/null && echo 1 | tee /proc/sys/vm/overcommit_memory > /dev/null'

   [Install]
   WantedBy=basic.target
   ```

   **Note:**

   Some versions of Red Hat Enterprise Linux, and potentially other Red Hat-based derivatives, use a different path for the THP `enabled` file:

   ```bash
   /sys/kernel/mm/redhat_transparent_hugepage/enabled
   ```

   Verify which path is in use on your system and update the `enable-transparent-huge-pages.service` file accordingly.

2. Reload `systemd` unit files

   To reload the `systemd` unit files and make `enable-transparent-huge-pages.service` available for use, run the following command :

   ```sh
   sudo systemctl daemon-reload
   ```

3. Start the service

   Run:

   ```sh
   sudo systemctl start enable-transparent-huge-pages
   ```

   To verify that the relevant THP settings have changed, run the following command:

   ```sh
   cat /sys/kernel/mm/transparent_hugepage/enabled && cat /sys/kernel/mm/transparent_hugepage/defrag && cat /sys/kernel/mm/transparent_hugepage/khugepaged/max_ptes_none && cat /proc/sys/vm/overcommit_memory
   ```

   On Red Hat Enterprise Linux and potentially other Red Hat-based derivatives, you may instead need to use the following:

   ```sh
   cat /sys/kernel/mm/redhat_transparent_hugepage/enabled && cat /sys/kernel/mm/redhat_transparent_hugepage/defrag && cat /sys/kernel/mm/redhat_transparent_hugepage/khugepaged/max_ptes_none && cat /proc/sys/vm/overcommit_memory
   ```

   The output should resemble the following:

   ```bash
   always
   defer+madvise
   0
   1
   ```

4. Configure your operating system to run it on boot.

   To ensure that this setting is applied each time the operating system starts, run the following command:

   ```sh
   sudo systemctl enable enable-transparent-huge-pages
   ```

5. (*Optional*) Customize tuned or ktune profile

   If you use `tuned` or `ktune` proffiles on RHEL (Red Hat Enterprise Linux)/ CentOS, you must also create a custom `tuned` profile.

### Using `tuned` and `ktune`

**Important:**

If you use `tuned` or `ktune`, perform the steps in this section after creating the service file.

`tuned` and `ktune` are kernel tuning utilities that can affect the Transparent Hugepages setting on your system. If you are using `tuned` or `ktune` on your RHEL (Red Hat Enterprise Linux) or CentOS system while running `mongod`, you must create a custom `tuned` profile to ensure that THP stays enabled.

1. Create a new profile

   Create a new directory to store the custom `tuned` profile. The following example inherits from the existing `virtual-guest` profile, and uses `virtual-guest-thp` as the new profile:

   ```sh
   sudo mkdir /etc/tuned/virtual-guest-thp
   ```

2. Edit `tuned.conf`

   Create and edit `/etc/tuned/virtual-guest-thp/tuned.conf`. Add the following text:

   ```ini
   [main]
   include=virtual-guest

   [vm]
   transparent_hugepages=always
   ```

   This example inherits from the existing `virtual-guest` profile. Select the appropriate profile for your system.

3. Enable the new profile

   Run:

   ```sh
   sudo tuned-adm profile virtual-guest-thp
   ```

## Enable Per-CPU Caches

To verify that TCMalloc is running with per-CPU caches, ensure that:

- [`tcmalloc.usingPerCPUCaches`](https://www.mongodb.com/docs/manual/reference/command/serverstatus.md#mongodb-serverstatus-serverstatus.tcmalloc.usingPerCPUCaches) is `true`.

- [`tcmalloc.tcmalloc.cpu_free`](https://www.mongodb.com/docs/manual/reference/command/serverstatus.md#mongodb-serverstatus-serverstatus.tcmalloc.tcmalloc.cpu_free) is greater than `0`.

If per-CPU caches aren't enabled, ensure that:

- You disable glibc rseq.

- You're using Linux kernel version 4.18 or later.

### Disable glibc rseq

The new TCMalloc requires [Restartable Sequences (rseq)](https://github.com/google/tcmalloc/blob/master/docs/design.md#restartable-sequences-and-per-cpu-tcmalloc) to implement per-CPU caches. If another application, such as the glibc library, registers an rseq structure before TCMalloc, TCMalloc can't use rseq. Without rseq, TCMalloc uses per-thread caches, which are used by the legacy TCMalloc version.

To enable per-CPU caches, disable glibc’s rseq registration by setting the following environment variable before you start `mongod`:

```sh
GLIBC_TUNABLES=glibc.pthread.rseq=0
export GLIBC_TUNABLES
```

### Check Kernel Version

If per-CPU caches are still not enabled after disabling glibc rseq, verify that you're using Linux kernel 4.18 or later:

```sh
uname -r
```

## Learn More

- [Upgraded TCMalloc](https://www.mongodb.com/docs/manual/release-notes/8.0.md#std-label-8.0-tcmalloc-upgrade)

- [Google's TCMalloc Tuning Guide](https://google.github.io/tcmalloc/tuning.html)

- [tcmalloc serverStatus metrics](https://www.mongodb.com/docs/manual/reference/command/serverstatus.md#std-label-server-status-tcmalloc)
