Skip to content

Fix high CPU usage in case AmqpNetLite.Core 2.4.8+ - #102

Merged
Havret merged 1 commit into
apache:mainfrom
fbarresi:develop
Jun 2, 2026
Merged

Havret merged 1 commit into
apache:mainfrom
fbarresi:develop

Conversation

@fbarresi

@fbarresi fbarresi commented Apr 20, 2026 •

Copy link
Copy Markdown
Contributor

Since AMQPNetLite v2.4.8 the IdleTimeOut supports negative values.
The new default value is -1.
If the timeout of -1 get casted to uint it becames uint.MaxValue.
This lead to wrong working heartbeat and high CPU usage.

Below a detailled explaination about the issue and how to reproduce it.

How to reproduce the issue

This issue occurs every time you attempt to use a newer version of the AmqpNetLite.Core. The Nuget package for ApacheNMS.AMQP requires AMQPNetLite.Core >= 2.4.3 .
Up to version 2.4.7, there is no meaningful difference in the behavior of the library.
Starting on the version 2.4.8 and newer, I detected an high CPU consumption during idle.

This can be easily reproduced in this way:

  1. Create an empty project and reference the AMQPNetLite.Core explicitly.

example.csproj

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="AMQPNetLite.Core" Version="2.4.7" />
        <PackageReference Include="Apache.NMS" Version="2.2.0" />
        <PackageReference Include="Apache.NMS.AMQP" Version="2.4.0" />
    </ItemGroup>

</Project>

Program.cs

using Apache.NMS;

var connectionString = new Uri(Environment.GetEnvironmentVariable("ConnectionString")!);

var username = Environment.GetEnvironmentVariable("Username");
var password = Environment.GetEnvironmentVariable("Password");

var connection = new NMSConnectionFactory(connectionString, Array.Empty<object>())
    .CreateConnection(username, password);
var session = connection.CreateSession();

connection.Start();

Console.WriteLine("Press enter to exit...");
Console.ReadLine();
  1. Check the Performance differences between AMQPNetLite.Core 2.4.7 and 2.4.8.
  • 2.4.7
    Apart of some initial activity, you see 0% CPU usage
image
  • 2.4.8
    The CPU goes high up to 20% while the program is actually be in idle the whole time (no producers neither consumers)
image In a containerized application with low memory and CPU quota grant, it goes even higher.

How/why this occurs

The apache.nsm.amqp library performs a casting from the default value (if not overriden):
image

this lead to an unintended value in case of -1, the new default value fo this setting:
image

Proposed solution

Since the underlaying library AmqpNetLite.Core changed the default value and its behavior in this matter, I think the apache.nsm.amqp should perfom a casting only if the IdleTimeOut is not negative and pass 0 elsewhere. This will allow to keep a low dependency requirement, remain backward capable and also fit newer version of AMQPNetLite.Core.

@cshannon
cshannon requested a review from Havret May 14, 2026 16:07
@davidvoit

Copy link
Copy Markdown
Contributor

Maybe this pull request can be combined with an upgrade to amqpnetlite 2.5.x? @Havret is this something which would make sense or is this something which should be a different pull request?

Comment thread src/NMS.AMQP/Provider/Amqp/AmqpConnection.cs Outdated
@Havret

Havret commented May 22, 2026

Copy link
Copy Markdown
Contributor

Maybe this pull request can be combined with an upgrade to amqpnetlite 2.5.x? @Havret is this something which would make sense or is this something which should be a different pull request?

I think it would make better sense to bump amqpnetlite in a separate PR.

@Havret
Havret requested a review from Copilot May 22, 2026 22:08

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adjusts AMQP Open handshake negotiation to avoid overflowing IdleTimeOut when using AMQPNetLite.Core >= 2.4.8 (where the default IdleTimeout can be -1), preventing incorrect heartbeat scheduling that can lead to high CPU usage during idle periods.

Changes:

  • Guarded the Open.IdleTimeOut assignment to only cast positive values to uint, otherwise send 0.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/NMS.AMQP/Provider/Amqp/AmqpConnection.cs Outdated
Since AmqpNetLite v2.4.8 the IdleTimeOut supports negative values.
The new default value is -1.
If the timeout of -1 get casted to uint it becames uint.MaxValue.
This lead to wrong working heartbeat and high CPU usage.
@fbarresi

Copy link
Copy Markdown
Contributor Author

Dear @Havret , thank you for your review. I applied the changes and updated the PR.

@Havret Havret left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Will need some follow up work. But I will take care of it with a separate PR.

@Havret
Havret merged commit 35a804e into apache:main Jun 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants