iRacing Telemetry SDK for C# .NET
A modern, async-first .NET SDK for C# developers who want to integrate real-time telemetry data from the iRacing simulator into their applications. Built with compile-time type safety, enum-based variable selection, and a high-performance streaming architecture. Access 200+ racing variables, replay IBT files, control the simulator, and build professional sim racing tools with full IntelliSense support and automatic backpressure handling.
Quick Start
Get started with type-safe, async telemetry streaming:
// Install via NuGet
dotnet add package SVappsLAB.iRacingTelemetrySDK using Microsoft.Extensions.Logging;
using SVappsLAB.iRacingTelemetrySDK;
// 1. Declare the variables you want (validated at compile time)
[RequiredTelemetryVars([TelemetryVar.Speed, TelemetryVar.RPM])]
public class Program
{
public static async Task Main(string[] args)
{
// 2. Create a logger
var logger = LoggerFactory.Create(b => b.AddConsole())
.CreateLogger("TelemetryApp");
// 3. Use an IBT file if given, otherwise connect to live iRacing
var ibt = args.Length == 1 ? new IBTOptions(args[0]) : null;
// 4. Create the client (source generator emits TelemetryData)
await using var client =
TelemetryClient<TelemetryData>.Create(logger, ibt);
// 5. Handle the streams you care about
var handlers = new TelemetryHandlers<TelemetryData>
{
OnTelemetryUpdate = data =>
{
var mph = data.Speed * 2.23694f;
Console.WriteLine($"{mph:F0} mph, {data.RPM:F0} rpm");
return Task.CompletedTask;
}
};
// 6. Monitor until cancelled (or end-of-file, for IBT playback)
using var cts = new CancellationTokenSource();
Console.CancelKeyPress +=
(_, e) => { e.Cancel = true; cts.Cancel(); };
await client.Monitor(handlers, cts.Token);
}
} All telemetry properties are nullable, mirroring iRacing's variable availability model — some variables exist only in certain sessions or contexts.
Controlling the simulator uses the same client:
using SVappsLAB.iRacingTelemetrySDK.SimControl;
var sim = client.SimControl;
sim.Pit.AddFuel(30); // pit service
sim.Pit.ChangeTire(TireLocation.LeftFront);
sim.Replay.Search(ReplaySearchMode.NextIncident); // replay control
sim.Camera.SwitchToCar("001", cameraGroup: 1, camera: 1);Features
Compile-Time Type Safety with IntelliSense Support
Declare telemetry variables using strongly-typed enums (
TelemetryVar.Speed,TelemetryVar.RPM) instead of error-prone strings. A Roslyn source generator creates a customTelemetryDatarecord struct at compile time, giving you IntelliSense support, type safety, and validation before your code even runs.Async-First Architecture with Automatic Backpressure Handling
Modern async/await patterns ensure telemetry collection never blocks your application logic. Dedicated background tasks process data at 60Hz while keeping your code responsive. Each stream is a bounded 60-item channel with a drop-oldest policy, so a slow consumer costs bounded data rather than unbounded memory. Choose the handler-based
MonitorAPI or direct stream access for advanced scenarios.High-Performance Lock-Free Streaming
Lock-free architecture processes over 600,000 telemetry records per second on modern hardware — roughly twice the throughput of the earlier event-based implementation. Telemetry decoding (60Hz, time-critical) and session information (CPU-intensive YAML parsing) run on independent tasks so neither stalls the other.
Live Sessions and IBT File Playback
Access real-time telemetry during active iRacing sessions or replay saved IBT files through the same unified API. Process historical telemetry data for post-race analysis and setup optimization using identical code patterns, at normal speed or as fast as your hardware allows.
Dynamic Variable Lookup
When the variable set isn't known at compile time — a user-configurable dashboard, or a game engine that prefers string-keyed access — look up any telemetry variable by name at runtime with
GetValue(string), alongside or instead of the generated struct.Simulator Control
Send commands to iRacing, not just read from it: pit service (fuel, tires, fast repair), replay search and playback speed, camera switching, chat, and broadcast commands.
Built-in Observability and Performance Monitoring
Integrated
System.Diagnostics.Metricsprovides real-time visibility into SDK performance. Monitor telemetry processing rates, dropped records, and latency histograms using standard tools likedotnet-counters.Documentation Written for AI Coding Agents
The repository ships dedicated agent-facing usage and reference guides, so your AI coding assistant can generate correct SDK code instead of guessing at the API.
Why it's fast
- Source-generated structs eliminate runtime reflection and string lookups from the hot path — only the variables you asked for are ever decoded.
- Lock-free bounded streams keep telemetry current under load instead of queueing unboundedly behind a slow consumer.
- Minimal-allocation reads — each sample is copied once into a reused
buffer (guarding against iRacing overwriting it mid-read), then decoded field-by-field
via
ReadOnlySpan<T>with no further allocations, keeping steady-state GC pressure near zero. - Independent background tasks mean CPU-intensive session-info YAML parsing never stalls the 60Hz telemetry path.
Full details, including the threading model, buffering semantics, memory layout, and built-in metrics, are in the Architecture and Design document.
How It Compares
There are several .NET libraries for reading iRacing telemetry. Most are thin wrappers over the iRacing shared-memory layout: variables are looked up by string name at runtime, and data arrives through events raised on the caller's thread.
This SDK takes a different approach. It treats telemetry as a typed, high-throughput data stream rather than a bag of named values.
| iRacingTelemetrySDK | Typical .NET iRacing libraries | |
|---|---|---|
| Variable access | Compile-time generated TelemetryData struct — only the variables you declare | Runtime lookup by string name or dictionary indexing |
| Type safety | Enum-based selection, validated at build time, full IntelliSense | Strings resolved at runtime; typos surface as runtime errors or nulls |
| API model | Async data streams with async/await, bounded buffering,
and automatic overload handling | Blocking event handlers or manual polling loops |
| Threading | Dedicated background tasks for collection and YAML parsing — your handler never blocks the data source | Callbacks commonly block further frame processing until they return |
| Backpressure | Bounded 60-sample ring buffer with drop-oldest; slow consumers cost bounded data, never memory | Not supported |
| Live + IBT parity | Identical strongly-typed API for both | Frequently separate code paths, or live-only |
| Throughput | 600,000+ records/sec on IBT playback | Unknown |
| Observability | Built-in System.Diagnostics.Metrics counters and histograms | Not supported |
| Simulator control | Pit, replay, camera, chat, and broadcast commands included | Varies |
| AI agent support | Dedicated agent-facing usage and reference docs | Rare |
Use Cases & Applications
- Real-time Racing Dashboards — Build custom HUD overlays with live speed, RPM, and tire data for simrig displays
- Telemetry Analysis Tools — Create data visualization apps for lap time analysis and performance optimization
- Race Engineering Software — Develop professional-grade setup comparison and optimization tools
- Stream Overlays — Add telemetry widgets to racing streams and broadcasts for viewers
- Historical Data Analysis — Process IBT files for post-race performance reviews and driver coaching
- Race Automation — Drive pit service, replay, and camera commands from your own logic or broadcast tooling
Install & Documentation
The package is on NuGet, and the repository has comprehensive documentation, sample projects, and code examples.
Documentation
- Architecture and Design — threading model, data streaming and buffering, iRacing memory layout, performance characteristics, and built-in metrics
- Advanced Usage — direct stream access, multiple consumers, and cancellation behavior
- Migration Guide — upgrading from early pre-1.0 releases
- Sample Projects — ready-to-run examples for telemetry monitoring, IBT analysis, sim control, and data export
- SDK Usage Guide for AI Agents — point your coding assistant here so it writes correct SDK code
How iRacing Telemetry Data Is Laid Out
Live iRacing telemetry comes from the Windows shared-memory map Local\IRSDKMemMapFileName at 60 Hz. Recorded IBT files use the same core iRacing SDK structures,
allowing this SDK to decode live sessions and historical files through one API.
In both formats, irsdk_header is an index of offsets and counts. It points to
session information stored as YAML, an array of irsdk_varHeader metadata, and the
telemetry data. Each variable header describes a field's name, type, byte offset, and element
count.
Live shared-memory layout
The live map reserves fixed-capacity regions. iRacing rotates writes across three telemetry buffers while header offsets remain stable for the session.
IBT file layout
An IBT file adds a 32-byte disk subheader, packs its metadata without alignment padding, and stores a contiguous sequence of telemetry records after the session YAML.
How a telemetry row is read
Each row contains bufLen packed bytes. For every requested variable, its irsdk_varHeader identifies where the value starts and how to decode it.
Character and Boolean values occupy one byte; integers, bit fields, and floats occupy four
bytes; doubles occupy eight bytes. A count greater than one represents an array, including
the per-car CarIdx* variables.
For live data, the SDK selects the newest completed buffer, copies the sample into a reused buffer, and checks iRacing's tick counters for a concurrent write. If a write overlapped the copy, it retries rather than exposing a torn telemetry sample. Source-generated readers then decode only the fields requested by the application.
See the complete iRacing memory map and IBT data-layout reference for structure sizes, offset formulas, buffer fields, and a worked IBT example.
Frequently Asked Questions
How does iRacingTelemetrySDK differ from other .NET iRacing libraries?
Most .NET libraries for iRacing are thin wrappers over the simulator's shared-memory
layout: you look up variables by string name at runtime and receive data through events
raised on the caller's thread. iRacingTelemetrySDK treats telemetry as a typed,
high-throughput data stream instead. A Roslyn source generator emits a TelemetryData struct containing exactly the variables you declared, so variable
names and types are validated when you build rather than when you race. Data reaches your code
through bounded async streams with automatic overload handling, so a slow handler never stalls
the 60Hz data source.
How fast is the iRacing Telemetry SDK?
IBT playback exceeds 600,000 telemetry records per second in the reference benchmark,
roughly twice the throughput of the earlier event-based implementation. Source-generated
structs remove reflection and string lookups from the hot path, each sample is copied once
into a reused buffer and then decoded field-by-field through ReadOnlySpan<T>, so steady-state allocation on the telemetry path is
near zero. Actual throughput depends on the requested variables, the work your consumer
does, storage, and host hardware.
What happens if my code cannot keep up with the telemetry rate?
Each application-facing stream is a bounded channel holding 60 items, which is one second of data at the live 60Hz rate. When a channel is full, the oldest unread sample is discarded rather than blocking the producer. A slow consumer therefore costs you bounded, older data instead of unbounded memory growth or a stalled data source. Consumers that need lossless processing should read promptly and provide their own downstream buffer.
What is iRacing telemetry?
iRacing telemetry is real-time data from the iRacing motorsport simulator including vehicle speed, engine RPM, tire temperatures, fuel levels, and 200+ other racing metrics. This data can be used to build custom dashboards, analyze performance, and create racing tools.
Can the SDK send commands to the simulator?
Yes. In addition to reading telemetry, the SDK can control iRacing: pit service requests, replay search and playback speed, camera switching, chat, and broadcast commands. Commands are fire-and-forget, work independently of monitoring and connection state, and are ignored when iRacing is not running.
Can I choose telemetry variables at runtime instead of compile time?
Yes. When the variable set is not known until runtime — a dashboard whose users pick which
values to display, for example — use the DynamicTelemetryData client type and
read values by name with GetValue(string). Name matching is case-insensitive
and works for any variable reported by GetTelemetryVariables(). Dynamic
lookup requires the client to be created with TelemetryDeliveryMode.Synchronous.
What are IBT files?
IBT files are iRacing Binary Telemetry files that contain recorded telemetry data from a racing session. This SDK can read and replay IBT files using the same strongly-typed API as live data, making it easy to analyze historical race data with the same code.
Does this work with other racing simulators?
This SDK is specifically designed for iRacing and uses the official iRacing SDK (iRSDK) interface. It does not support other racing simulators like Assetto Corsa, rFactor, or F1 games.
Can I use this for commercial applications?
Yes, the SDK is licensed under Apache License 2.0, allowing both personal and commercial use. You can build and sell applications that use this SDK.
What .NET version is required?
The SDK requires .NET 8.0 or higher. It works on Windows for live telemetry, and is cross-platform (Windows, Linux, macOS) for IBT file playback.
Can AI coding assistants use this SDK?
Yes. The repository ships agent-facing documentation — an SDK usage guide and an advanced
reference — written for AI coding agents. Point your agent at those files, or add a line
to your project's AGENTS.md or CLAUDE.md instructing it to read them,
and it can generate correct SDK code without guessing at the API.
Open Source
This project is open source and free to use. Source code, documentation, and sample projects are available on GitHub. Contributions and feedback are welcome!
