We are pleased to share the news of a recent fix, tracked as PSMDB-1824/SMDB-1868, that has delivered significant, quantifiable performance enhancements for Percona Server for MongoDB instances, particularly when running in containerized environments like Docker.
Percona Server for MongoDB version 8.0.16-5, featuring this improvement, was made available on December 2, 2025.
Investigation
The initial issue was identified when our QA team noticed the failure of the tcmalloc_set_parameters_test unit test. The test succeeded in the native environment but failed in the Docker container. The QA team also identified a workaround: starting a container with a hard memory limit (docker run –memory=16g) solves the issue.
The VerifyCacheSize test has failed, leaving the following line in the log:
|
1 |
{"t":{"$date":"2025-10-07T14:12:40.933Z"},"s":"I", "c":"TEST", "id":23065, "ctx":"main","msg":"Totals","attr":{"totals":{"name":"TOTALS","tests":13,"fails":1,"asserts":0,"time":{"durationMillis":9},"failures":[{"test":"VerifyCacheSize","type":"TestAssertionFailureException","error":"Expected std::abs((tcmallocCapacity) - (targetSize)) <= 1024 * 10 (1073741824 <= 10240) @src/mongo/util/tcmalloc_set_parameter_test.cpp:380"}]}},"truncated":{"totals":{"truncated":{"failures":{"truncated":{"0":{"truncated":{"extra":{"type":"string","size":16451}},"omitted":1}}}}}},"size":{"totals":16790}} |
The essential part of that line is the actual error message:
|
1 |
Expected std::abs((tcmallocCapacity) - (targetSize)) <= 1024 * 10 (1073741824 <= 10240) @src/mongo/util/tcmalloc_set_parameter_test.cpp:380 |
Which tells us that for some reason, reported tcmalloc capacity is zero instead of the expected 1 GB. Long story short, we followed the clues from that error message and arrived at the getMemorySizeLimitInBytes function in the src/third_party/tcmalloc/dist/tcmalloc/cpu_cache.cc. This function returned zero available memory when it was executed in a Docker container. At first, it might seem that we encountered a bug in the well-known and ubiquitous tcmalloc library. Wow!
As you might guess, that was not the case. In fact, the getMemorySizeLimitInBytes function was in the section of the source file bracketed by START MONGO HACK/END MONGO HACK comments. Additional comment stated that:
Code is copied from processinfo_linux.cpp and modified to not depend on MongoDB C++ code.
Indeed there is an almost identical getMemorySizeLimit function in the processinfo_linux.cpp. The difference is that the original function in the processinfo_linux.cpp uses the NumberParser class and the copied function replaces NumberParser with atoll from the standard library to get rid of MongoDB C++ code dependency as stated in the aforementioned comment.
Along the way we identified that in a Docker container string value to be converted to number was string “max”, meaning that OS does not restrict memory usage by application.
While replacing the NumberParser with atoll , the author of the code overlooked the difference in semantics between two: original code relied on NumberParser’s ability to detect such non-numeric strings but the copied (and modified) code just used the value returned from atoll without any additional checks. If the input string was “max” then atoll just returned zero which was interpreted as “no memory available at all”.
Performance Metrics: Before and After
After fixing the handling of the “max” string in context of cgroups limits the unittests succeeded in the containerized environment.
The original issue was fixed but our QA team executed a test to check if the fix affected server performance.
The impact of the fix has been significant, positively surprising us. The following table summarizes the observed improvements.
| ycsb configdocker image | Before the fix | After the fix | ||
|---|---|---|---|---|
| RunTime(ms) | Throughput(ops/sec) | RunTime(ms) | Throughput(ops/sec) | |
| ycsb workloada
recordcount=1000000 threads 100 |
13751 | 72721.98 | 8739 (-36%) | 114429.57 (+57%) |
| ycsb workloadb
recordcount=1000000 threads 100 |
14149 | 70676.37 | 8858 (-37%) | 112892.30 (+60%) |
| ycsb workloada
recordcount=10000000 threads 100 |
144021 | 69434.32 | 100804 (-30%) | 99202.41 (+43%) |
| ycsb workloadb recordcount=10000000 threads 100 |
144359 | 69271.75 | 105809 (-27%) | 94509.92 (+36%) |
What This Means for Our Users
Before we fixed this issue tcmalloc was misconfigured in a bad way and thus it was underperforming significantly.
For all users running Percona Server for MongoDB in containerized environments, these performance gains translate directly into a better experience:
- Dramatic Speed Boosts: Up to 37% Faster Runtime: Users will experience a substantial reduction in query and operation execution time, with runtimes cut by up to 37% across various standard workloads.
- Significantly Higher Capacity: Up to 60% Increased Throughput: The fix has unlocked the capacity for your database to handle more work, with observed throughput increases of up to 60%. This improved efficiency means your containerized MongoDB instance can process a much higher volume of operations per second.
- Improved hardware utilization: Reduced infrastructure costs per workload
We remain committed to open source so we created a bug report SERVER-119885 and the pull request with our fix for the MongoDB Community repository here: https://github.com/mongodb/mongo/pull/1632