Skip to content

MongoDBContainer consumes excessive CPU after #1070 #1145

@CodingCanuck

Description

@CodingCanuck

Expected Behaviour
MongoDBContainer should not consume excessive amounts of CPU

Actual Behaviour
After starting MongoDBContainer, it consumes 50-100% of 1 CPU core, due to repeated replicaset re-initialization

Testcontainer Logs

2025-09-25T09:08:34.162Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.161+00:00"},"s":"I",  "c":"NETWORK",  "id":6788700, "ctx":"conn80","msg":"Received first command on ingress connection since session start or auth handshake","attr":{"elapsedMillis":2}}
2025-09-25T09:08:34.162Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.162+00:00"},"s":"I",  "c":"COMMAND",  "id":21577,   "ctx":"conn80","msg":"Initiate: no configuration specified. Using a default configuration for the set"}
2025-09-25T09:08:34.162Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.162+00:00"},"s":"I",  "c":"COMMAND",  "id":21578,   "ctx":"conn80","msg":"Created configuration for initiation","attr":{"config":{"_id":"rs0","version":1,"members":[{"_id":0,"host":"666818ea5142:27017"}]}}}
2025-09-25T09:08:34.162Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.162+00:00"},"s":"I",  "c":"REPL",     "id":21356,   "ctx":"conn80","msg":"replSetInitiate admin command received from client"}

stdout | packages/modules/mongodb/src/mongodb-container.test.ts > MongoDBContainer > should have low CPU usage
2025-09-25T09:08:34.167Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.166+00:00"},"s":"I",  "c":"NETWORK",  "id":22944,   "ctx":"conn79","msg":"Connection ended","attr":{"remote":"127.0.0.1:43720","isLoadBalanced":false,"uuid":{"uuid":{"$uuid":"a9480a47-939b-4d5a-978f-fc8fe7a08165"}},"connectionId":79,"connectionCount":4}}
2025-09-25T09:08:34.167Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.166+00:00"},"s":"I",  "c":"NETWORK",  "id":22944,   "ctx":"conn76","msg":"Connection ended","attr":{"remote":"127.0.0.1:43686","isLoadBalanced":false,"uuid":{"uuid":{"$uuid":"35b13d63-89b3-4bab-b36d-f6e961a21092"}},"connectionId":76,"connectionCount":3}}

stdout | packages/modules/mongodb/src/mongodb-container.test.ts > MongoDBContainer > should have low CPU usage
2025-09-25T09:08:34.167Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.166+00:00"},"s":"I",  "c":"NETWORK",  "id":22944,   "ctx":"conn78","msg":"Connection ended","attr":{"remote":"127.0.0.1:43714","isLoadBalanced":false,"uuid":{"uuid":{"$uuid":"5dfa454c-6f50-44f0-bdb1-b168ae7b0229"}},"connectionId":78,"connectionCount":2}}
2025-09-25T09:08:34.167Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.166+00:00"},"s":"I",  "c":"NETWORK",  "id":22944,   "ctx":"conn80","msg":"Connection ended","attr":{"remote":"127.0.0.1:43732","isLoadBalanced":false,"uuid":{"uuid":{"$uuid":"f5463634-b201-4a16-9013-264168499a7c"}},"connectionId":80,"connectionCount":1}}
2025-09-25T09:08:34.167Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.166+00:00"},"s":"I",  "c":"NETWORK",  "id":22944,   "ctx":"conn77","msg":"Connection ended","attr":{"remote":"127.0.0.1:43698","isLoadBalanced":false,"uuid":{"uuid":{"$uuid":"873968be-b359-4e74-b8bb-7e00dddc898d"}},"connectionId":77,"connectionCount":0}}

stdout | packages/modules/mongodb/src/mongodb-container.test.ts > MongoDBContainer > should have low CPU usage
2025-09-25T09:08:34.677Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.676+00:00"},"s":"I",  "c":"NETWORK",  "id":22943,   "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:43738","isLoadBalanced":false,"uuid":{"uuid":{"$uuid":"5396470b-fb96-4f02-87fa-cbdbd35c005c"}},"connectionId":81,"connectionCount":1}}

stdout | packages/modules/mongodb/src/mongodb-container.test.ts > MongoDBContainer > should have low CPU usage
2025-09-25T09:08:34.679Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.678+00:00"},"s":"I",  "c":"NETWORK",  "id":51800,   "ctx":"conn81","msg":"client metadata","attr":{"remote":"127.0.0.1:43738","client":"conn81","negotiatedCompressors":[],"doc":{"application":{"name":"mongosh 2.5.6"},"driver":{"name":"nodejs|mongosh","version":"6.16.0|2.5.6"},"platform":"Node.js v20.19.4, LE","os":{"name":"linux","architecture":"arm64","version":"4.14.209-160.339.amzn2.aarch64","type":"Linux"},"env":{"container":{"runtime":"docker"}}}}}

stdout | packages/modules/mongodb/src/mongodb-container.test.ts > MongoDBContainer > should have low CPU usage
2025-09-25T09:08:34.720Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.719+00:00"},"s":"I",  "c":"NETWORK",  "id":22943,   "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:43754","isLoadBalanced":false,"uuid":{"uuid":{"$uuid":"b491bb8a-927b-4dfc-9aaf-f8b2d06b72ee"}},"connectionId":82,"connectionCount":2}}
2025-09-25T09:08:34.720Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.719+00:00"},"s":"I",  "c":"NETWORK",  "id":22943,   "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:43760","isLoadBalanced":false,"uuid":{"uuid":{"$uuid":"a179462c-6131-42e1-a5da-cafd8d6c4f22"}},"connectionId":83,"connectionCount":3}}

stdout | packages/modules/mongodb/src/mongodb-container.test.ts > MongoDBContainer > should have low CPU usage
2025-09-25T09:08:34.720Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.719+00:00"},"s":"I",  "c":"NETWORK",  "id":51800,   "ctx":"conn82","msg":"client metadata","attr":{"remote":"127.0.0.1:43754","client":"conn82","negotiatedCompressors":[],"doc":{"application":{"name":"mongosh 2.5.6"},"driver":{"name":"nodejs|mongosh","version":"6.16.0|2.5.6"},"platform":"Node.js v20.19.4, LE","os":{"name":"linux","architecture":"arm64","version":"4.14.209-160.339.amzn2.aarch64","type":"Linux"},"env":{"container":{"runtime":"docker"}}}}}

stdout | packages/modules/mongodb/src/mongodb-container.test.ts > MongoDBContainer > should have low CPU usage
2025-09-25T09:08:34.721Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.720+00:00"},"s":"I",  "c":"NETWORK",  "id":51800,   "ctx":"conn83","msg":"client metadata","attr":{"remote":"127.0.0.1:43760","client":"conn83","negotiatedCompressors":[],"doc":{"application":{"name":"mongosh 2.5.6"},"driver":{"name":"nodejs|mongosh","version":"6.16.0|2.5.6"},"platform":"Node.js v20.19.4, LE","os":{"name":"linux","architecture":"arm64","version":"4.14.209-160.339.amzn2.aarch64","type":"Linux"},"env":{"container":{"runtime":"docker"}}}}}

stdout | packages/modules/mongodb/src/mongodb-container.test.ts > MongoDBContainer > should have low CPU usage
2025-09-25T09:08:34.722Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.722+00:00"},"s":"I",  "c":"NETWORK",  "id":6788700, "ctx":"conn82","msg":"Received first command on ingress connection since session start or auth handshake","attr":{"elapsedMillis":2}}

stdout | packages/modules/mongodb/src/mongodb-container.test.ts > MongoDBContainer > should have low CPU usage
2025-09-25T09:08:34.723Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.722+00:00"},"s":"I",  "c":"NETWORK",  "id":22943,   "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:43762","isLoadBalanced":false,"uuid":{"uuid":{"$uuid":"0a3db8a0-36fa-492b-ae7e-ead0ced31d85"}},"connectionId":84,"connectionCount":4}}

stdout | packages/modules/mongodb/src/mongodb-container.test.ts > MongoDBContainer > should have low CPU usage
2025-09-25T09:08:34.723Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.723+00:00"},"s":"I",  "c":"NETWORK",  "id":22943,   "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:43770","isLoadBalanced":false,"uuid":{"uuid":{"$uuid":"08528504-3252-40c7-89fa-7439b1bbe6b9"}},"connectionId":85,"connectionCount":5}}

stdout | packages/modules/mongodb/src/mongodb-container.test.ts > MongoDBContainer > should have low CPU usage
2025-09-25T09:08:34.724Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.723+00:00"},"s":"I",  "c":"COMMAND",  "id":21577,   "ctx":"conn82","msg":"Initiate: no configuration specified. Using a default configuration for the set"}
2025-09-25T09:08:34.724Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.723+00:00"},"s":"I",  "c":"COMMAND",  "id":21578,   "ctx":"conn82","msg":"Created configuration for initiation","attr":{"config":{"_id":"rs0","version":1,"members":[{"_id":0,"host":"666818ea5142:27017"}]}}}
2025-09-25T09:08:34.724Z testcontainers:containers [666818ea5142] {"t":{"$date":"2025-09-25T09:08:34.723+00:00"},"s":"I",  "c":"REPL",     "id":21356,   "ctx":"conn82","msg":"replSetInitiate admin command received from client"}

Steps to Reproduce

  1. Add a test to mongodb-container.test.ts like the following, which waits for the mongo container to start, then repeatedly prints out docker stats to show container CPU usage (but isn't actually asserting correct CPU usage):
// New imports and methods
import { exec } from "node:child_process";
import { promisify } from "node:util";
const execAsync = promisify(exec);

describe("MongoDBContainer", { timeout: 240_000 }, () => {
  // Add this test after existing tests

  it("should have low CPU usage", async () => {
    const image = "mongo:8.0.12";
    await using container = await new MongoDBContainer(image).start();

    const seconds = 10;
    console.log(`Sleeping for ${seconds} seconds...`);
    await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
    console.log("Done sleeping");

    for (let i = 0; i < 5; i++) {
      const { stdout } = await execAsync("docker stats --no-stream");
      let output = `Docker stats ${i}: \n${stdout}`;
      // Prepend a unique string to each line of stdout so it can be grepped
      output = output.replaceAll("\n", "\n======");

      console.log(output);
    }
  });
});
  1. Run this test, and grep for relevant console output to just see the Mongo docker container's CPU usage:

npx vitest run packages/modules/mongodb/src/mongodb-container.test.ts -t "should have low CPU usage" --silent=false |& grep "======" | grep -v "testcontainers-"

  1. Run this test before and after Add support for MongoDBContainer credentials #1070 , which introduced this CPU-usage regression.

Sample CPU usage stats, after that change (run git checkout c0571da):

======CONTAINER ID   NAME                               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O     PIDS
======ef5b48a8e8fe   focused_greider                    51.46%    123.5MiB / 7.654GiB   1.58%     1.11kB / 126B   0B / 1.03MB   76
======
======CONTAINER ID   NAME                               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O     PIDS
======ef5b48a8e8fe   focused_greider                    53.41%    266.1MiB / 7.654GiB   3.40%     1.11kB / 126B   0B / 1.03MB   89
======
======CONTAINER ID   NAME                               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O     PIDS
======ef5b48a8e8fe   focused_greider                    46.68%    181.4MiB / 7.654GiB   2.31%     1.11kB / 126B   0B / 1.33MB   83
======
======CONTAINER ID   NAME                               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O     PIDS
======ef5b48a8e8fe   focused_greider                    52.25%    123.3MiB / 7.654GiB   1.57%     1.11kB / 126B   0B / 1.33MB   76
======
======CONTAINER ID   NAME                               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O     PIDS
======ef5b48a8e8fe   focused_greider                    48.96%    262.9MiB / 7.654GiB   3.36%     1.11kB / 126B   0B / 1.34MB   88
======

Sample CPU usage stats, before that change (git checkout c0571da^):

======CONTAINER ID   NAME                               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O     PIDS
======d3d4c9762170   blissful_satoshi                   2.47%     120.6MiB / 7.654GiB   1.54%     1.11kB / 126B   0B / 1.04MB   76
======
======CONTAINER ID   NAME                               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O     PIDS
======d3d4c9762170   blissful_satoshi                   1.44%     120.5MiB / 7.654GiB   1.54%     1.11kB / 126B   0B / 1.04MB   76
======
======CONTAINER ID   NAME                               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O     PIDS
======d3d4c9762170   blissful_satoshi                   1.82%     120.8MiB / 7.654GiB   1.54%     1.11kB / 126B   0B / 1.13MB   76
======
======CONTAINER ID   NAME                               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O     PIDS
======d3d4c9762170   blissful_satoshi                   1.84%     120.5MiB / 7.654GiB   1.54%     1.11kB / 126B   0B / 1.13MB   76
======
======CONTAINER ID   NAME                               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O     PIDS
======d3d4c9762170   blissful_satoshi                   1.37%     120.3MiB / 7.654GiB   1.53%     1.11kB / 126B   0B / 1.13MB   76
======

Environment Information

  • Operating System: Mac OS X Sequoia 15.6.1
  • Docker Version: Docker Desktop 4.46.0,204649, Docker version 28.4.0, build d8eb465
  • Node version: v24.8.0 or v20.18.3
  • Testcontainers version: v11.4.0 or higher (regression occurred in Add support for MongoDBContainer credentials #1070 )

(Note, environment / architecture likely doesn't matter to reproduce this issue)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions