Skip to content

[SignalR] Reduce hub invocation activity overhead - #69557

Open
martincostello wants to merge 8 commits into
dotnet:mainfrom
martincostello:signalr-reducea-activity-overhead
Open

martincostello wants to merge 8 commits into
dotnet:mainfrom
martincostello:signalr-reducea-activity-overhead

Conversation

@martincostello

Copy link
Copy Markdown
Member

Reduce hub invocation activity overhead

Reduce the overhead of activity for SignalR hub invocations.

Description

  • Pass hub activity tags to ActivitySource in a reusable thread-static list to avoid boxing.
  • Cache the activity display name per hub method.
  • Cache the link to the connection's original activity per connection.
  • Avoid performance regression when using TagList.

Benchmarks

DefaultHubDispatcherTelemetryBenchmark.Invocation

Scenario Baseline time Candidate time Time Baseline allocated Candidate allocated Allocated
No telemetry 172.0 ns 165.9 ns −3.5% 552 B 552 B 0%
Traces 751.7 ns 502.8 ns −33.1% 2,064 B 1,488 B −27.9%

Traced invocations on main also pay a JIT AVX to SSE transition penalty that the branch avoids (dotnet/runtime#133784). With DOTNET_EnableAVX=0, a traced invocation takes 539.9 ns on main and 492.2 ns on the branch.

Detailed results

main

BenchmarkDotNet=v0.13.0, OS=Windows 10.0.26200
Unknown processor
.NET SDK=11.0.100-rc.1.26420.103
  [Host] : .NET 11.0.0 (11.0.26.45408), X64 RyuJIT

Affinity=00000000111111111111  Toolchain=InProcessEmitToolchain  RunStrategy=Throughput
Method Tracing Mean Error StdDev Op/s Gen 0 Gen 1 Gen 2 Allocated
Invocation False 172.0 ns 2.61 ns 2.31 ns 5,814,777.3 0.0439 - - 552 B
Invocation True 764.6 ns 13.49 ns 12.62 ns 1,307,925.8 0.1640 - - 2,064 B

PR

BenchmarkDotNet=v0.13.0, OS=Windows 10.0.26200
Unknown processor
.NET SDK=11.0.100-rc.1.26420.103
  [Host] : .NET 11.0.0 (11.0.26.45408), X64 RyuJIT

Affinity=00000000111111111111  Toolchain=InProcessEmitToolchain  RunStrategy=Throughput
Method Tracing Mean Error StdDev Median Op/s Gen 0 Gen 1 Gen 2 Allocated
Invocation False 169.1 ns 2.94 ns 4.03 ns 169.3 ns 5,912,187.4 0.0439 - - 552 B
Invocation True 507.3 ns 9.74 ns 27.14 ns 493.9 ns 1,971,107.7 0.1183 - - 1,488 B

- Pass hub activity tags to `ActivitySource` in a reusable thread-static list to avoid boxing.
- Cache the activity display name per hub method.
- Cache the link to the connection's original activity per connection.
- Avoid performance regression when using `TagList`.
@github-actions github-actions Bot added the area-signalr Includes: SignalR clients and servers label Sep 27, 2026
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Sep 27, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Thanks for your PR, @martincostello. Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Low-level thread-static reuse and concurrent telemetry caching warrant final human review.

Review effort: Balanced
Findings: None

What changed in this PR

Optimizes SignalR hub invocation telemetry to reduce traced-request allocations and execution time.

Changes:

  • Reuses tag collections and cached activity links/display names.
  • Generalizes endpoint tagging for TagList and list-backed collections.
  • Adds activity behavior tests and a telemetry benchmark.
File Description
HubConnectionHandlerTests.Activity.cs Tests resolved activity method names.
HubMethodDescriptor.cs Caches activity display names.
DefaultHubDispatcher.cs Reuses tags and cached telemetry metadata.
HubConnectionContext.cs Caches the original activity link.
DefaultHubDispatcherTelemetryBenchmark.cs Benchmarks invocation telemetry overhead.
ConnectionEndpointTags.cs Supports generic tag collections without boxing.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Looks like this PR hasn't been active for some time and the codebase could have been changed in the meantime.
To make sure no conflicting changes have occurred, please rerun validation before merging. You can do this by leaving an /azp run comment here (requires commit rights), or by simply closing and reopening.

@dotnet-policy-service dotnet-policy-service Bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Oct 6, 2026
@martincostello martincostello removed the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Oct 6, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Looks like this PR hasn't been active for some time and the codebase could have been changed in the meantime.
To make sure no conflicting changes have occurred, please rerun validation before merging. You can do this by leaving an /azp run comment here (requires commit rights), or by simply closing and reopening.

@dotnet-policy-service dotnet-policy-service Bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Oct 15, 2026
@martincostello martincostello removed the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Oct 15, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Looks like this PR hasn't been active for some time and the codebase could have been changed in the meantime.
To make sure no conflicting changes have occurred, please rerun validation before merging. You can do this by leaving an /azp run comment here (requires commit rights), or by simply closing and reopening.

@dotnet-policy-service dotnet-policy-service Bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Oct 23, 2026
@martincostello martincostello removed the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Oct 23, 2026

This branch was previously deployed

1 inactive (outdated) deployment
copilot-pat-pool — 6ebfa783 Deployed Sep 27, 2026 by dotnet-policy-service[bot] via pat_pool #1638
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-signalr Includes: SignalR clients and servers community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants