Skip to content

High number of connections due to Mongo health indicator#50734

Open
seonwooj0810 wants to merge 2 commits into
spring-projects:mainfrom
seonwooj0810:fix/issue-50727-mongo-health-single-hello
Open

High number of connections due to Mongo health indicator#50734
seonwooj0810 wants to merge 2 commits into
spring-projects:mainfrom
seonwooj0810:fix/issue-50727-mongo-health-single-hello

Conversation

@seonwooj0810

Copy link
Copy Markdown

Fixes gh-50727

Problem

MongoHealthIndicator and MongoReactiveHealthIndicator run the hello command against every database returned by listDatabaseNames(). For the reactive indicator the per-database commands are issued in parallel via flatMap, so on each health check a deployment with many databases reachable through the connection opens roughly one connection per database. As reported in gh-50727, this caused a large increase in connection usage after upgrading to Spring Boot 4 (e.g. ~200 → ~1300 connections across a fleet of services that share a Mongo user and therefore see many databases).

Fix

hello (formerly isMaster) is a server-level command whose response (including maxWireVersion) is independent of the database it is addressed to, so there is no need to run it more than once. This change runs it a single time against the admin database, which restores the single-command behavior of the previous Spring Data based implementation while keeping the current Spring-Data-free indicator.

The reported health details are unchanged: both indicators still report databases (via a single listDatabaseNames() call) and maxWireVersion.

I kept the databases detail because it is asserted by the existing *IntegrationTests. If the team would prefer to drop it and report only maxWireVersion (matching the 3.x output exactly), I'm happy to update the PR.

Test evidence

./gradlew :module:spring-boot-mongodb:test :module:spring-boot-mongodb:checkstyleMain :module:spring-boot-mongodb:checkstyleTest :module:spring-boot-mongodb:checkFormatMain :module:spring-boot-mongodb:checkFormatTest — all pass. compileDockerTestJava also passes (the Testcontainers-based *IntegrationTests were not run here as Docker was unavailable, but they compile and their existing assertions on databases/maxWireVersion still hold). The unit tests were updated to verify the hello command is only addressed to admin and never to a listed database.

Verification done: confirmed both .java indicators still contained the per-database runCommand loop on current main; no in-flight PR (searched open PRs for MongoHealthIndicator/MongoReactiveHealthIndicator/mongo health/50727); no claim comments on the issue; issue carries type: regression (not status: waiting-for-triage); compared against the Spring Boot 3.5.x MongoReactiveHealthIndicator to confirm the single-command intent.

The MongoDB health indicators ran the `hello` command against every
database returned by `listDatabaseNames()`. For the reactive indicator
these commands were issued in parallel via `flatMap`, so a deployment
with many databases per connection could open a connection per database
on each health check, dramatically increasing connection usage (a
regression from the Spring Data based implementation used previously).

Since `hello` is a server-level command whose result is independent of
the target database, run it only once against the `admin` database. The
`databases` and `maxWireVersion` details are preserved.

See spring-projectsgh-50727

Signed-off-by: seonwoo_jung <79202163+seonwooj0810@users.noreply.github.com>
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 10, 2026
@wilkinsona wilkinsona changed the title Run a single hello command in MongoDB health indicators High number of connections due to Mongo health indicator Jun 10, 2026
@wilkinsona wilkinsona added type: regression A regression from a previous release and removed status: waiting-for-triage An issue we've not yet triaged labels Jun 10, 2026
@wilkinsona wilkinsona added this to the 4.0.x milestone Jun 10, 2026

@wilkinsona wilkinsona left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, @seonwooj0810. I've left a comment for your consideration.

});
builder.up().withDetails(details);
this.mongoClient.listDatabaseNames().forEach(databases::add);
Document result = this.mongoClient.getDatabase(ADMIN_DATABASE).runCommand(HELLO_COMMAND);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that the user associated with the mongoClient won't be able to see the admin database? If so, I think this will fail. Perhaps admin should be used only if it's in the list returned from listDatabaseNames()? If it's not present, the first database in the list could be used instead.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, good catch. I updated both the blocking and reactive health indicators to choose admin only when it is visible in listDatabaseNames(), otherwise they fall back to the first visible database (or admin only if the list is empty). I also added sync and reactive regression tests for the non-admin-visible case. Pushed as bc374ae.

Signed-off-by: seonwooj0810 <seonwooj0810@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: regression A regression from a previous release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

High number of connections due to mongo health indicator

3 participants