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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions