# Resident Workers vs Client-Owned Workers in the Prime Agent Daemon: Key Differences Explained

> Understand the crucial differences between resident workers and client-owned workers in Prime Agent daemon. Learn how each impacts agent persistence and lifecycle management.

- Repository: [Prime Intellect/prime-agent](https://github.com/PrimeIntellect-ai/prime-agent)
- Tags: deep-dive
- Published: 2026-08-18

---

**Resident workers are long-lived daemon processes that persist across client disconnections, while client-owned workers are ephemeral processes bound to the lifecycle of the creating client and automatically terminate when that client disconnects.**

The Prime Agent daemon from [PrimeIntellect-ai/prime-agent](https://github.com/PrimeIntellect-ai/prime-agent) supports two distinct worker lifecycle models that determine process ownership, persistence, and shutdown behavior. Understanding the difference between resident and client-owned workers is essential for building reliable agent architectures that match your operational requirements.

## Lifecycle Semantics and Ownership Model

The daemon distinguishes workers through the `DaemonSessionLifecycle` union type defined in [`packages/coding-agent/src/modes/daemon/daemon-protocol.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/daemon/daemon-protocol.ts). This type accepts two string literals: `"resident"` and `"client_owned"`.

### Resident Workers (Default)

Resident workers operate as daemon-global resources. When you create a session without explicitly requesting client ownership, the daemon constructs a descriptor with `lifecycle: "resident"` and leaves the `ownerClientId` field undefined. These workers survive individual client disconnections and continue running until the daemon itself shuts down or receives an explicit stop command.

### Client-Owned Workers

Client-owned workers are strictly tied to the client connection that created them. When a session is created with `lifecycle: "client_owned"`, the daemon captures the originating client’s identifier and stores it as `ownerClientId` in the worker descriptor. This binding ensures that when the owning client disconnects, the daemon automatically terminates the associated worker process.

## How the Daemon Creates Each Worker Type

The entry point in [`packages/coding-agent/src/main.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/main.ts) handles the branching logic around line 991. The `createSessionDescriptor` function checks the `options.clientOwned` boolean to determine which lifecycle to assign.

**Resident worker creation (default):**

```typescript
// Resident workers are created when clientOwned is false or undefined
const sessionDescriptor = await createSessionDescriptor({
  name: "background-agent",
  // clientOwned defaults to false
});
// Results in: { lifecycle: "resident", ownerClientId: undefined }

```

**Client-owned worker creation:**

```typescript
// Client-owned workers require explicit opt-in
const sessionDescriptor = await createSessionDescriptor({
  name: "interactive-session",
  clientOwned: true,  // Explicitly request client ownership
});
// Results in: { lifecycle: "client_owned", ownerClientId: "<client-id>" }

```

Before accepting a client-owned request, the daemon validates that it advertises the `client_owned_sessions` capability. If a client attempts to create a client-owned session against a daemon that does not support this feature, the call raises a `DaemonCapabilityUnavailableError`.

## Internal Implementation Details

The distinction between these worker types is enforced in [`packages/coding-agent/src/modes/daemon/daemon-supervisor.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/daemon/daemon-supervisor.ts) around line 2030. When processing a `CreateSession` command, the supervisor executes conditional ownership assignment:

```typescript
// From daemon-supervisor.ts (~line 2030)
const ownerClientId = command.lifecycle === "client_owned" 
  ? clientId 
  : undefined;

```

This single line determines the ownership model. For resident workers, the `ownerClientId` remains `undefined`, signaling to the daemon’s garbage collection and lifecycle management systems that the process should persist independently of any specific client connection.

The `DaemonSessionLifecycle` type definition in [`daemon-protocol.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/daemon-protocol.ts) (around line 175) formalizes these values:

```typescript
export type DaemonSessionLifecycle = "resident" | "client_owned";

```

Additionally, the supervisor retrieves resident worker collections for daemon-wide operations (such as update-restart checks) by iterating over `workers.values()` around line 4485 in the same file, filtering for processes that lack an `ownerClientId` or simply processing all resident entries.

## Operational Behavior and Shutdown

The practical difference between these models emerges during connection failures and daemon maintenance events.

**Resident worker characteristics:**
- Survive client disconnections and network interruptions
- Ideal for background tasks, persistent LLM assistants, or long-running automation agents
- Require explicit shutdown via API call or daemon termination
- Listed in daemon-wide worker inventories for maintenance operations

**Client-owned worker characteristics:**
- Automatically terminate when the owning client disconnects (gracefully or otherwise)
- Suitable for interactive REPL sessions, temporary sub-agents, or ad-hoc tasks
- Cannot outlive the client session that spawned them
- Cleaned up immediately upon client socket closure to prevent resource leaks

## Summary

- **Resident workers** use `lifecycle: "resident"` with no `ownerClientId`, persist beyond client disconnections, and serve as daemon-wide background processes.
- **Client-owned workers** use `lifecycle: "client_owned"`, bind to a specific `ownerClientId`, and automatically terminate when that client disconnects.
- The daemon validates the `client_owned_sessions` capability before permitting client-owned creation.
- Implementation logic resides primarily in [`daemon-supervisor.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/daemon-supervisor.ts) (ownership assignment) and [`main.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/main.ts) (session descriptor construction).
- Choose resident workers for long-running agents and client-owned workers for ephemeral, interactive tasks.

## Frequently Asked Questions

### What happens to client-owned workers if the network connection drops unexpectedly?

The daemon detects the client disconnection and immediately terminates any workers associated with that client’s `ownerClientId`. This prevents orphaned processes and ensures resource cleanup even during ungraceful disconnections.

### Can I convert a resident worker to a client-owned worker after creation?

No, the lifecycle is immutable once the session descriptor is created. You must stop the existing resident worker and create a new session with the desired `client_owned` lifecycle to change ownership models.

### Does using resident workers require special daemon configuration?

Resident workers are supported by default and require no capability flags. However, client-owned workers require the daemon to advertise the `client_owned_sessions` capability; attempting to create them against unsupported daemons results in a `DaemonCapabilityUnavailableError`.

### Where is the worker ownership logic implemented in the source code?

The ownership assignment occurs in [`packages/coding-agent/src/modes/daemon/daemon-supervisor.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/daemon/daemon-supervisor.ts) around line 2030, where the code conditionally sets `ownerClientId` based on the `command.lifecycle` value.