# How the Roo Code Telemetry System Tracks Task Lifecycle Events

> Discover how Roo Code's telemetry system tracks task lifecycle events. Learn about its three-layer architecture, event dispatching, and data transmission to external analytics.

- Repository: [Roo Code/Roo-Code](https://github.com/RooCodeInc/Roo-Code)
- Tags: internals
- Published: 2026-04-26

---

**Roo Code tracks task lifecycle events through a three-layer architecture where the Task model emits creation and status changes, TelemetryService dispatches them to registered clients, and PostHogTelemetryClient transmits the data to external analytics.**

The Roo Code extension implements a comprehensive telemetry pipeline to monitor task execution from initialization through completion. By instrumenting critical points in the task lifecycle, this system captures creation, restart, start, completion, and abort events while respecting user privacy preferences. The architecture decouples event emission from transmission, allowing the VS Code extension to collect usage metrics without impacting performance.

## Task Lifecycle Capture Points

### Creation and Restart Events

When a `Task` object is instantiated in [`src/core/task/Task.ts`](https://github.com/RooCodeInc/Roo-Code/blob/main/src/core/task/Task.ts), the constructor determines whether this represents a new task or a history item retry. For new tasks, the constructor calls `TelemetryService.instance.captureTaskCreated(this.taskId)` at lines 516-517. For retries, it invokes `captureTaskRestarted(this.taskId)` at lines 509-511.

These fire-and-forget calls delegate immediately to the telemetry dispatcher without blocking task initialization.

### Runtime Status Changes

As tasks execute, the `Task` class emits `RooCodeEventName` events via `this.emit()`. The class triggers `TaskStarted` once the underlying Roo Code process is ready (see [`Task.ts`](https://github.com/RooCodeInc/Roo-Code/blob/main/Task.ts) line 2479).

Higher-level components listen for these emissions. The CLI runner in [`packages/evals/src/cli/runTaskInCli.ts`](https://github.com/RooCodeInc/Roo-Code/blob/main/packages/evals/src/cli/runTaskInCli.ts) registers IPC listeners that react to `TaskStarted`, `TaskCompleted`, `TaskAborted`, and `TaskTokenUsageUpdated`. When a task completes, the system calls `TelemetryService.instance.captureTaskCompleted(taskId)` from [`src/core/tools/AttemptCompletionTool.ts`](https://github.com/RooCodeInc/Roo-Code/blob/main/src/core/tools/AttemptCompletionTool.ts) at line 204.

The CLI runner also extracts the optional `rooTaskId` from the `TaskStarted` payload (lines 199-202) to enable correlation with backend systems.

## The Three-Layer Telemetry Architecture

### Layer 1: Task Model Event Emission

The Task model in [`src/core/task/Task.ts`](https://github.com/RooCodeInc/Roo-Code/blob/main/src/core/task/Task.ts) serves as the event origin. It defines lifecycle transitions and triggers the initial telemetry capture calls directly from its constructor and event emission points.

### Layer 2: TelemetryService Dispatcher

Located at [`packages/telemetry/src/TelemetryService.ts`](https://github.com/RooCodeInc/Roo-Code/blob/main/packages/telemetry/src/TelemetryService.ts), this singleton holds registered `TelemetryClient` instances and provides typed convenience methods including `captureTaskCreated` (lines 81-84), `captureTaskCompleted` (lines 89-92), and `captureTaskRestarted`. Each method validates `isReady` (lines 38-40) before delegating to clients:

```typescript
public captureTaskCreated(taskId: string): void {
  this.captureEvent(TelemetryEventName.TASK_CREATED, { taskId });
}

```

The service initializes once in the VS Code extension entry point ([`src/extension.ts`](https://github.com/RooCodeInc/Roo-Code/blob/main/src/extension.ts) lines 141-143), where it registers the PostHog client:

```typescript
const telemetryService = TelemetryService.createInstance();
telemetryService.register(new PostHogTelemetryClient());

```

### Layer 3: PostHog Telemetry Client

The concrete implementation in [`packages/telemetry/src/PostHogTelemetryClient.ts`](https://github.com/RooCodeInc/Roo-Code/blob/main/packages/telemetry/src/PostHogTelemetryClient.ts) handles network transmission. The `capture` method (lines 58-66) formats events and forwards them to the PostHog SDK, respecting runtime enablement flags to ensure privacy compliance.

## Configuration and Privacy Controls

### Enabling and Disabling Telemetry

Users can toggle telemetry collection at runtime without restarting the extension. The `TelemetryClient.updateTelemetryState(isOptedIn)` method sets a static `telemetryEnabled` flag, while `TelemetryService.updateTelemetryState` propagates this change to all registered clients. This ensures immediate compliance with user preferences across the entire telemetry stack.

## Summary

- Roo Code tracks task lifecycles through a centralized `TelemetryService` that acts as an event dispatcher between the Task model and analytics backends.
- The `Task` class in [`src/core/task/Task.ts`](https://github.com/RooCodeInc/Roo-Code/blob/main/src/core/task/Task.ts) triggers `captureTaskCreated` (lines 516-517) and `captureTaskRestarted` (lines 509-511) during initialization.
- Runtime events like `TaskCompleted` are captured via `TelemetryService.instance.captureTaskCompleted()`, called from tools such as [`AttemptCompletionTool.ts`](https://github.com/RooCodeInc/Roo-Code/blob/main/AttemptCompletionTool.ts) (line 204).
- The `PostHogTelemetryClient` in [`packages/telemetry/src/PostHogTelemetryClient.ts`](https://github.com/RooCodeInc/Roo-Code/blob/main/packages/telemetry/src/PostHogTelemetryClient.ts) transmits events to external analytics when enabled.
- Telemetry can be disabled at runtime through `updateTelemetryState`, which propagates to all registered clients via the static `telemetryEnabled` flag.

## Frequently Asked Questions

### How does Roo Code distinguish between new tasks and restarted tasks for telemetry?

Roo Code distinguishes these in the [`Task.ts`](https://github.com/RooCodeInc/Roo-Code/blob/main/Task.ts) constructor. When instantiating a fresh task, it calls `captureTaskCreated` (lines 516-517). When loading a history item as a retry, it calls `captureTaskRestarted` (lines 509-511) instead, allowing analytics to differentiate between new work and continued sessions.

### Can I disable telemetry in Roo Code without restarting the extension?

Yes. The telemetry system supports runtime toggling through `TelemetryService.updateTelemetryState(isOptedIn)`, which immediately propagates to all registered clients via the `TelemetryClient.updateTelemetryState` method. This updates the static `telemetryEnabled` flag without requiring a restart.

### What happens if telemetry is not initialized when a task event occurs?

The `TelemetryService` checks `isReady` (lines 38-40) before delegating to clients. If no clients are registered or telemetry is disabled, the capture methods return early without error, ensuring task execution continues uninterrupted regardless of telemetry state.

### Where is the telemetry client initialized in the Roo Code codebase?

The client initializes in the VS Code extension entry point at [`src/extension.ts`](https://github.com/RooCodeInc/Roo-Code/blob/main/src/extension.ts) (lines 141-143). The code creates a singleton instance via `TelemetryService.createInstance()` and registers the `PostHogTelemetryClient` before other extension services begin emitting task events.