diff --git a/CHANGELOG.md b/CHANGELOG.md
index 872b948528..9775ad5cc9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
### Features
+- Reduced the memory footprint of `SpanTracer` by initializing the tags lazily ([2636](https://github.com/getsentry/sentry-dotnet/pull/2636))
- Added distributed tracing without performance for Azure Function Workers ([#2630](https://github.com/getsentry/sentry-dotnet/pull/2630))
- The SDK now provides and overload of `ContinueTrace` that accepts headers as `string` ([#2601](https://github.com/getsentry/sentry-dotnet/pull/2601))
- Sentry tracing middleware now gets configured automatically ([#2602](https://github.com/getsentry/sentry-dotnet/pull/2602))
diff --git a/benchmarks/Sentry.Benchmarks/TransactionBenchmarks.cs b/benchmarks/Sentry.Benchmarks/TransactionBenchmarks.cs
new file mode 100644
index 0000000000..f2abfa0188
--- /dev/null
+++ b/benchmarks/Sentry.Benchmarks/TransactionBenchmarks.cs
@@ -0,0 +1,34 @@
+using BenchmarkDotNet.Attributes;
+
+namespace Sentry.Benchmarks;
+
+public class TransactionBenchmarks
+{
+ private const string Operation = "Operation";
+ private const string Name = "Name";
+
+ [Params(1, 10, 100, 1000)]
+ public int SpanCount;
+
+ private IDisposable _sdk;
+
+ [GlobalSetup(Target = nameof(CreateTransaction))]
+ public void EnabledSdk() => _sdk = SentrySdk.Init(Constants.ValidDsn);
+
+ [GlobalCleanup(Target = nameof(CreateTransaction))]
+ public void DisableDsk() => _sdk.Dispose();
+
+ [Benchmark(Description = "Creates a Transaction")]
+ public void CreateTransaction()
+ {
+ var transaction = SentrySdk.StartTransaction(Name, Operation);
+
+ for (var i = 0; i < SpanCount; i++)
+ {
+ var span = transaction.StartChild(Operation);
+ span.Finish();
+ }
+
+ transaction.Finish();
+ }
+}
diff --git a/src/Sentry/Span.cs b/src/Sentry/Span.cs
index 9673bde909..0c6f16ff8f 100644
--- a/src/Sentry/Span.cs
+++ b/src/Sentry/Span.cs
@@ -88,7 +88,7 @@ public Span(ISpan tracer)
Status = tracer.Status;
IsSampled = tracer.IsSampled;
_extra = tracer.Extra.ToDictionary();
- _tags = tracer.Tags.ToDictionary();
+ _tags = tracer is SpanTracer s ? s.InternalTags?.ToDictionary() : tracer.Tags.ToDictionary();
}
///
diff --git a/src/Sentry/SpanTracer.cs b/src/Sentry/SpanTracer.cs
index 1b560ae802..63f84024a1 100644
--- a/src/Sentry/SpanTracer.cs
+++ b/src/Sentry/SpanTracer.cs
@@ -52,6 +52,8 @@ public class SpanTracer : ISpan
private ConcurrentDictionary? _tags;
+ internal ConcurrentDictionary? InternalTags => _tags;
+
///
public IReadOnlyDictionary Tags => _tags ??= new ConcurrentDictionary();