Skip to content

fix(metrics): enforce dimension limits per-array#5229

Open
vishwakt wants to merge 5 commits into
aws-powertools:mainfrom
vishwakt:fix/set-default-dimensions-limit-check
Open

fix(metrics): enforce dimension limits per-array#5229
vishwakt wants to merge 5 commits into
aws-powertools:mainfrom
vishwakt:fix/set-default-dimensions-limit-check

Conversation

@vishwakt
Copy link
Copy Markdown
Contributor

@vishwakt vishwakt commented May 8, 2026

Summary

Changes

This PR fundamentally fixes how dimension limits (MAX_DIMENSION_COUNT) are enforced across the Metrics class. It resolves the issue where valid dimension updates were incorrectly rejected near the limit due to overlapping keys being double-counted.

What is this PR solving?
Previously, limit checks relied on this.#dimensionsStore.getDimensionCount(), which naively summed the sizes of dimensions, defaultDimensions, and all dimensionSets. This approach was flawed for a few reasons:

  1. CloudWatch EMF Constraints: CloudWatch publishes each dimensionSet as a completely separate array of dimensions. The CloudWatch limit of 30 dimensions applies to the maximum size of any individual array, not the sum of all dimensions defined across all sets.
  2. Double Counting: Using simple arithmetic (currentCount + newCount) meant that updating an existing key would incorrectly inflate the dimension count, causing a RangeError (issue Bug: setDefaultDimensions() double-counts overlapping keys, rejecting valid updates near the limit #5205).
  3. Off-by-one Inconsistencies: addDimension allowed 29 dimensions, whereas addDimensions and setDefaultDimensions only allowed 28 due to a >= vs > discrepancy.

Fix Details:

  • Replaced naive sums with projected array sizes: We now use Javascript Set to calculate the exact maximum size of the specific dimension arrays that will actually be published to CloudWatch EMF.
  • Natively Handles Updates: Because Set automatically deduplicates overlapping keys, updating existing dimensions inherently evaluates to a size of 0 new dimensions—fixing Bug: setDefaultDimensions() double-counts overlapping keys, rejecting valid updates near the limit #5205 automatically.
  • Fixed off-by-one bug: The limit checks now uniformly use projectedSize > MAX_DIMENSION_COUNT so exactly 29 custom dimensions are permitted across all methods (accommodating the 30th reserved service dimension).
  • Added comprehensive edge-case tests: Added tests proving that overlapping keys at the limit threshold behave correctly, and added a regression test proving that adding multiple valid dimension sets no longer incorrectly hits the global dimension limit.

Issue number: closes #5205


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

@powertools-for-aws-oss-automation powertools-for-aws-oss-automation Bot added the size/L PRs between 100-499 LOC label May 8, 2026
@vishwakt vishwakt force-pushed the fix/set-default-dimensions-limit-check branch from 2e0cfa3 to 704fcf3 Compare May 8, 2026 03:50
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation Bot added size/L PRs between 100-499 LOC and removed size/L PRs between 100-499 LOC labels May 8, 2026
This resolves double counting and limit discrepancies. Closes aws-powertools#5205
@vishwakt vishwakt force-pushed the fix/set-default-dimensions-limit-check branch from 704fcf3 to 7f91fb0 Compare May 8, 2026 03:53
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation Bot added size/L PRs between 100-499 LOC and removed size/L PRs between 100-499 LOC labels May 8, 2026
@vishwakt vishwakt changed the title Fix/set default dimensions limit check fix(metrics): enforce dimension limits per-array May 8, 2026
Comment thread packages/metrics/tests/unit/dimensions.test.ts Outdated
Comment thread packages/metrics/src/Metrics.ts
Copy link
Copy Markdown
Contributor

@dreamorosi dreamorosi left a comment

Choose a reason for hiding this comment

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

Validated the approach against the EMF specification: the spec defines the 30-dimension cap per DimensionSet, not as an aggregate across all sets, and the outer Dimensions array has no upper bound in the schema. The new Set-based projected-size check correctly mirrors what serializeMetrics actually emits (each set merged with defaultDimensions as its own array, see Metrics.ts:733-738), which makes the validation match runtime behaviour. The off-by-one unification on projectedSize > MAX_DIMENSION_COUNT is also a nice cleanup. Left a few minor observations inline — none are blockers.

Comment thread packages/metrics/src/Metrics.ts
Comment thread packages/metrics/src/Metrics.ts
Comment thread packages/metrics/tests/unit/dimensions.test.ts
Adds explanatory comments, guards against phantom dimension arrays, and clarifies test names.
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation Bot added size/L PRs between 100-499 LOC and removed size/L PRs between 100-499 LOC labels May 8, 2026
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation Bot added size/L PRs between 100-499 LOC and removed size/L PRs between 100-499 LOC labels May 8, 2026
svozza
svozza previously approved these changes May 11, 2026
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation Bot added size/L PRs between 100-499 LOC and removed size/L PRs between 100-499 LOC labels May 11, 2026
@svozza
Copy link
Copy Markdown
Contributor

svozza commented May 11, 2026

@vishwakt looks like we're getting a CI failure due to a drop in code coverage. My guess is probably because the new guard you added doesn't have a test.

…refactor

Removes unused getDimensionCount method and adds coverage for edge-case boundary checks in setDefaultDimensions
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation Bot added size/L PRs between 100-499 LOC and removed size/L PRs between 100-499 LOC labels May 11, 2026
@sonarqubecloud
Copy link
Copy Markdown

@vishwakt
Copy link
Copy Markdown
Contributor Author

vishwakt commented May 11, 2026

@svozza the drop in coverage was actually a direct result of the recent refactor

the getDimensionCount() method in DimensionsStore became dead code which i've now removed. I've also added another test case for a boundary condition

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/L PRs between 100-499 LOC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: setDefaultDimensions() double-counts overlapping keys, rejecting valid updates near the limit

3 participants