Skip to content

Optimistic allocation for Count and Set metrics#308

Merged
remeh merged 1 commit intoDataDog:masterfrom
opsengine:optimistic-allocation
Nov 21, 2025
Merged

Optimistic allocation for Count and Set metrics#308
remeh merged 1 commit intoDataDog:masterfrom
opsengine:optimistic-allocation

Conversation

@opsengine
Copy link
Copy Markdown

@opsengine opsengine commented Jun 2, 2024

This PR optimizes the count() and set() aggregator methods by moving the allocation of new metric objects outside of the critical section (write lock).

Previously, the new metric structure was allocated while holding the write lock. This change instantiates the metric optimistically after releasing the read lock but before acquiring the write lock. Rationale: if the metric could not be found while holding the read lock, it's unlikely to be found after a few ns, so it will have to be created anyway. Occasionally this assumption will be incorrect and the effect will be one unnecessary allocation.

Note that this optimization is already present in gauge() but for some reason it's missing in the other two functions.

Changes

  • statsd/aggregator.go:
    • In count(): newCountMetric is now called before acquiring a.countsM.Lock().
    • In set(): newSetMetric is now called before acquiring a.setsM.Lock().

Motivation

Reduce Lock Contention under memory pressure: Memory allocation is relatively expensive compared to map insertion. By moving newCountMetric and newSetMetric outside the write lock, we significantly shorten the critical section where the lock is held.

How we found this

The profiler revealed lock contention in this critical section while an application was under load. The application is using datadog-go v4.8.3 but the issue would affect the latest version as well.

Mutex Contention Time
Screenshot 2025-11-19 at 18 26 13

Block Time
Screenshot 2025-11-19 at 18 34 52

Goroutines
Screenshot 2025-11-19 at 21 23 17

@opsengine opsengine marked this pull request as ready for review June 3, 2024 18:41
@opsengine opsengine requested a review from a team June 3, 2024 18:41
@opsengine opsengine force-pushed the optimistic-allocation branch from 5b9f70b to 993d798 Compare November 20, 2025 02:05
@opsengine opsengine requested a review from a team as a code owner November 20, 2025 02:05
@opsengine opsengine changed the title Optimistic metric allocation Optimistic allocation for Count and Set metrics Nov 20, 2025
Copy link
Copy Markdown
Contributor

@remeh remeh left a comment

Choose a reason for hiding this comment

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

Hey @opsengine,
Thank you for the contribution, it looks good I'm merging this one in!
I'll do some internals validation as well and then work on releasing it in a new version of the lib.

@remeh
Copy link
Copy Markdown
Contributor

remeh commented Nov 21, 2025

We can only merge signed commits. Any chance you could push force a signed commit instead?

@remeh remeh merged commit 5d6607c into DataDog:master Nov 21, 2025
35 checks passed
@opsengine
Copy link
Copy Markdown
Author

@remeh thank you for merging. Can you please cut a new release?

We can only merge signed commits. Any chance you could push force a signed commit instead?

do you still need this?

@remeh
Copy link
Copy Markdown
Contributor

remeh commented Dec 1, 2025

@opsengine Sorry, validating internally is taking me longer than expected, but I'm on top of it this week. I'll start a new release once that's done

Your commit got in, please make sure to sign next ones (I see you have an opened draft PR 🙇 !)

@remeh remeh mentioned this pull request Dec 3, 2025
@remeh
Copy link
Copy Markdown
Contributor

remeh commented Dec 8, 2025

@opsengine it's now released part of 5.8.2, thanks for the contribution.

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.

3 participants