diff --git a/Directory.Packages.props b/Directory.Packages.props
index 8d52d3668a..96a7326009 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -64,6 +64,7 @@
+
diff --git a/examples/actor.open-telemetry/ActorOpenTelemetry.csproj b/examples/actor.open-telemetry/ActorOpenTelemetry.csproj
new file mode 100644
index 0000000000..e9896ca5aa
--- /dev/null
+++ b/examples/actor.open-telemetry/ActorOpenTelemetry.csproj
@@ -0,0 +1,16 @@
+
+
+ Exe
+ net8.0
+ 10
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/actor.open-telemetry/Program.cs b/examples/actor.open-telemetry/Program.cs
new file mode 100644
index 0000000000..a5813bed26
--- /dev/null
+++ b/examples/actor.open-telemetry/Program.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Diagnostics;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using OpenTelemetry;
+using OpenTelemetry.Metrics;
+using OpenTelemetry.Resources;
+using OpenTelemetry.Trace;
+using Proto;
+using Proto.OpenTelemetry;
+
+// Configure logging so Proto.Actor writes to the console
+var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
+Log.SetLoggerFactory(loggerFactory);
+
+// Export spans and metrics to the console and an OTLP collector (e.g., TraceLens)
+using var tracerProvider = Sdk.CreateTracerProviderBuilder()
+ .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("ActorOpenTelemetrySample"))
+ .AddProtoActorInstrumentation()
+ .AddConsoleExporter()
+ .AddOtlpExporter()
+ .Build();
+
+using var meterProvider = Sdk.CreateMeterProviderBuilder()
+ .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("ActorOpenTelemetrySample"))
+ .AddProtoActorInstrumentation()
+ .AddConsoleExporter()
+ .AddOtlpExporter()
+ .Build();
+
+var system = new ActorSystem(ActorSystemConfig.Setup().WithMetrics());
+
+// Simple actor that prints its trace id
+var props = Props.FromFunc(ctx =>
+{
+ if (ctx.Message is string msg)
+ {
+ Console.WriteLine($"[actor] received '{msg}' traceId={Activity.Current?.TraceId}");
+ }
+
+ return Task.CompletedTask;
+}).WithTracing();
+
+var pid = system.Root.Spawn(props);
+var tracedRoot = system.Root.WithTracing();
+
+using var rootActivity = new ActivitySource(Proto.ProtoTags.ActivitySourceName).StartActivity("root");
+tracedRoot.Send(pid, "hello");
+
+// Flush telemetry before exiting
+tracerProvider.ForceFlush();
+meterProvider.ForceFlush();
+
+Console.WriteLine("Press enter to exit");
+Console.ReadLine();
diff --git a/examples/actor.open-telemetry/README.md b/examples/actor.open-telemetry/README.md
new file mode 100644
index 0000000000..2c24b23b58
--- /dev/null
+++ b/examples/actor.open-telemetry/README.md
@@ -0,0 +1,22 @@
+# Actor OpenTelemetry
+
+Demonstrates Proto.Actor tracing and metrics using OpenTelemetry with console exporters. The sample runs a single actor system and prints spans and counters directly to the console, so no external collector is required. It also sends telemetry to an OTLP collector on `localhost:4317`, which can be visualized with [TraceLens](https://tracelens.io).
+
+## Run
+
+```bash
+DOTNET_ReadyToRun=0 dotnet run --project examples/actor.open-telemetry
+```
+
+The program sends a message to an instrumented actor. The console output shows the trace identifier for the message and periodic dumps of Proto.Actor metrics.
+
+## Visualize with TraceLens
+
+Start TraceLens via Docker Compose to explore the emitted spans and counters:
+
+```bash
+curl -L https://raw.githubusercontent.com/asynkron/TraceLens/main/docker-compose.yml -o docker-compose.yml
+docker compose up
+```
+
+With TraceLens running, execute the example again. Open http://localhost:5001 to inspect traces and metrics.