# Server Telemetry

URL: https://docs.testvibe.com/load-testing/server-telemetry

Client-side numbers tell you what users experience under load; server telemetry tells you *why* . Install the TestVibe agent in the application you are testing and your results gain live server-side **CPU** , **memory** , **session** , and **custom** metrics — rendered next to the client-side charts.

The metrics appear in two places:

- **Load test results** — server vitals next to the client-side charts.
- **Dashboard → Live Servers** — the same vitals streaming in real time while you watch.
The agent only sends data while one of your load runs is active or someone is watching the Dashboard — there is **no idle traffic** , and it is always best-effort so it can never disturb your application.

## What you'll need

1. A **TestVibe API key** ( `tvb_…` , workspace-scoped) — TestVibe → **Settings → CLI & API keys** . See [API keys](/account-settings/api-keys) . The agent discovers your projects from the key.
2. The agent for your stack (below). The .NET agent is the [`TestVibe.Telemetry`](https://www.nuget.org/packages/TestVibe.Telemetry) NuGet package; it discovers your projects from the API key, so you don't even need a project id.

## .NET

Install the package:

```sh
dotnet add package TestVibe.Telemetry
```

It targets `netstandard2.0` , so it runs on .NET Framework 4.6.1+, .NET Core 2.0+, and .NET 5–10+. Register it once at startup. The optional `SessionCount` callback unlocks **Sessions** and **Memory / session** ; wire it to whatever represents an active session in your app.

- ASP.NET Core - Worker / Generic Host - Console / daemon - WinForms / WPF - Wisej.NET

```csharp
// Program.cs
using TestVibe;

var builder = WebApplication.CreateBuilder(args);
// ... services ...
var app = builder.Build();

Telemetry.Register(
    builder.Configuration["TestVibe:Server"] ?? "https://app.testvibe.com",
    builder.Configuration["TestVibe:ApiKey"], // tvb_… from Settings → CLI & API keys
    new TelemetryOptions
    {
        // Optional: report a live count (e.g. active SignalR connections or signed-in users).
        SessionCount = () => MyConnectionCounter.Current,
    });

app.Run();
```

```csharp
// Program.cs (Worker Service, or any Generic Host)
using TestVibe;

var host = Host.CreateApplicationBuilder(args).Build();

Telemetry.Register("https://app.testvibe.com", Environment.GetEnvironmentVariable("TESTVIBE_API_KEY"));

host.Run();
```

```csharp
using TestVibe;

class Program
{
    static async Task Main()
    {
        TestVibe.Telemetry.Register("https://app.testvibe.com", "tvb_…");
        await RunForeverAsync();
    }
}
```

```csharp
// Program.cs / App startup
using TestVibe;

[STAThread]
static void Main()
{
    TestVibe.Telemetry.Register("https://app.testvibe.com", "tvb_…");
    Application.Run(new MainForm());
}
```

```csharp
// Program.cs — register once in the static constructor
using TestVibe;

static Program()
{
    Telemetry.Register("https://app.testvibe.com", "tvb_…", new TelemetryOptions
    {
        // Wisej tracks live sessions for you — report the built-in count.
        SessionCount = () => Wisej.Web.Application.SessionCount,
    });
}
```

### Custom metrics, info & errors

Anywhere in your app:

```csharp
// Gauges — chart alongside CPU/memory (latest value wins, up to 20 metrics).
TestVibe.Telemetry.ReportMetric("Orders/min", ordersPerMinute);

// Static facts shown in the server card header.
TestVibe.Telemetry.ReportInfo("Region", "westeurope");

// Errors — grouped + persisted under Dashboard → Telemetry → Errors & exceptions.
// Unhandled exceptions are captured automatically; report handled ones too:
try { DoWork(); }
catch (Exception ex) { TestVibe.Telemetry.ReportError(ex); throw; }
```

## Node.js

Node services use the [`testvibe-telemetry`](https://www.npmjs.com/package/testvibe-telemetry) npm package (Node 18+, zero dependencies):

```sh
npm install testvibe-telemetry
```

Start it once at boot:

```javascript
const { startTestVibeLoadAgent } = require('testvibe-telemetry');

const telemetry = startTestVibeLoadAgent({
  server: 'https://app.testvibe.com',
  apiKey: 'tvb_…',               // Settings → CLI & API keys
  project: '<your-project-id>',  // Settings → Telemetry
  sessions: () => myActiveSessions, // optional
});
```

Uncaught exceptions are captured automatically; report handled errors with `telemetry.reportError(err)` .

No npm? Copy the single-file agent shown in **Settings → Telemetry** ( `testvibe-load-agent.js` — the same file the package installs) into your app and require `'./testvibe-load-agent'` instead.

## Reading server metrics

- **CPU** climbing toward saturation while latency p95 rises is the classic capacity ceiling — scale up or optimize before raising thresholds.
- **Memory** growing run-over-run without recovering suggests a leak the load test is exposing; **Memory / session** isolates whether it's per-session.
- **Sessions** confirms the load actually produced the concurrency you configured.

## Related help

- [Run a load test and read results](/load-testing/run-a-load-test-and-read-results)
- [API keys](/account-settings/api-keys)
