# How Profiles Ensure Data Isolation in the Hindsight Embedded Client

> Learn how Hindsight profiles ensure data isolation with independent daemons, separate database instances, and isolated configuration files for enhanced security.

- Repository: [vectorize-io/hindsight](https://github.com/vectorize-io/hindsight)
- Tags: how-to-guide
- Published: 2026-03-13

---

**The Hindsight embedded client isolates data per profile by running independent daemon processes on unique TCP ports, maintaining separate pg0 database instances, and storing profile-specific configuration files in isolated directories.**

The vectorize-io/hindsight repository provides an embedded client that enables local memory management for AI applications. Understanding how profiles ensure data isolation in the Hindsight embedded client is critical for running multi-tenant applications or separating test and production environments on the same machine.

## The Three Pillars of Profile Isolation

### Isolated Daemon Processes

Each profile operates its own daemon process bound to a unique TCP port. According to the source code in [`hindsight-embed/hindsight_embed/daemon_embed_manager.py`](https://github.com/vectorize-io/hindsight/blob/main/hindsight-embed/hindsight_embed/daemon_embed_manager.py), the `DaemonEmbedManager.get_url()` method constructs the daemon URL by retrieving the port from profile metadata via `ProfileManager.resolve_profile_paths`, resulting in endpoints like `http://127.0.0.1:{port}`. This ensures that memory operations for one profile never intersect with another profile's daemon.

### Dedicated Database Instances

Data persistence is isolated through separate pg0 instances created per profile. The `DaemonEmbedManager.get_database_url()` method, implemented at lines 60-64 in [`hindsight-embed/hindsight_embed/daemon_embed_manager.py`](https://github.com/vectorize-io/hindsight/blob/main/hindsight-embed/hindsight_embed/daemon_embed_manager.py), generates a distinct database URL following the pattern `pg0://hindsight-embed-{safe_profile}`. This guarantees that banks, memories, and mental models remain segregated at the storage layer, with physical storage located at `~/.pg0/instances/hindsight-embed-{profile}/` as documented in the `HindsightEmbedded` class.

### Profile-Specific Configuration

Configuration and metadata isolation is maintained through the `ProfileManager` class in [`hindsight-embed/hindsight_embed/profile_manager.py`](https://github.com/vectorize-io/hindsight/blob/main/hindsight-embed/hindsight_embed/profile_manager.py). This component stores individual `.env` files, lock files, and log files under `~/.hindsight/profiles/`. When the daemon starts, it loads the profile-specific environment variables, including the unique database URL, ensuring complete operational separation between profiles.

## Implementation Flow

When instantiating `HindsightEmbedded(profile="myapp")`, the client executes a three-step isolation protocol:

1. **Configuration Assembly**: The client builds a configuration dictionary containing LLM provider settings, API keys, and the profile identifier.
2. **Daemon Initialization**: The `self._manager.ensure_running(self.config, self.profile)` method checks if a daemon exists for the specified profile on its allocated port; if absent, it invokes `_start_daemon` to create one.
3. **Environment Binding**: The daemon reads the profile's `.env` file, sets `HINDSIGHT_API_DATABASE_URL` to the per-profile pg0 URL, and binds exclusively to the profile-specific port.

Because each profile gets an independent daemon, independent database URL, and independent config files, no data from one profile can be seen or overwritten by another profile. The isolation works even when multiple clients run concurrently on the same machine.

## Practical Examples

The following example demonstrates complete data isolation between two profiles:

```python
from hindsight import HindsightEmbedded

# Profile "alice" stores data in its own pg0 instance

alice = HindsightEmbedded(profile="alice", llm_provider="groq", llm_api_key="...")
alice.retain(bank_id="alice", content="Alice likes cats")
alice.close()      # daemon stays alive until idle timeout

# Profile "bob" cannot see Alice's data

bob = HindsightEmbedded(profile="bob", llm_provider="groq", llm_api_key="...")
print(bob.recall(bank_id="alice", query="What does Alice like?"))

# → []   (empty because Bob's database is separate)

bob.close()

```

To verify the underlying isolation mechanisms, inspect the daemon and database URLs:

```python
from hindsight import HindsightEmbedded

client = HindsightEmbedded(profile="team-prod")
print("Daemon URL:", client.url)          # e.g. http://127.0.0.1:8890

print("Database URL:", client._manager.get_database_url("team-prod"))

# → pg0://hindsight-embed-team-prod

client.close()

```

## Summary

- **Process Isolation**: Each profile runs on a unique TCP port via `DaemonEmbedManager.get_url()`, preventing cross-profile daemon communication.
- **Database Isolation**: `DaemonEmbedManager.get_database_url()` creates distinct `pg0://hindsight-embed-{profile}` instances for storage separation.
- **Configuration Isolation**: `ProfileManager.resolve_profile_paths()` maintains separate `.env`, lock, and log files under `~/.hindsight/profiles/`.
- **Concurrent Safety**: Multiple profiles can run simultaneously on the same machine without data leakage or resource conflicts.

## Frequently Asked Questions

### Can multiple profiles run simultaneously on the same machine?

Yes. Because each profile operates on a unique TCP port returned by `ProfileManager.resolve_profile_paths()` and maintains its own daemon process, you can run multiple `HindsightEmbedded` instances with different profile names concurrently. Each daemon binds only to its assigned port, ensuring network-level isolation between profiles.

### Where is profile data physically stored?

Profile data lives in two primary locations. Configuration files, environment variables, and logs reside under `~/.hindsight/profiles/`, while the actual database files are stored at `~/.pg0/instances/hindsight-embed-{profile}/`. This separation allows you to back up or reset individual profiles without affecting others.

### What happens if I don't specify a profile when instantiating the client?

If no profile is specified, the client uses the **default** profile. The `ProfileManager` distinguishes between default and named profiles in `resolve_profile_paths()`, but both follow the same isolation rules. The default profile simply uses the name "default" for its database URL (`pg0://hindsight-embed-default`) and port allocation.

### Is there a performance penalty for using multiple profiles?

There is minimal overhead. While each profile runs its own daemon process, the `ensure_running()` method in `DaemonEmbedManager` only starts a daemon if one is not already listening on the allocated port. Daemons remain idle with timeout-based shutdown, so inactive profiles consume no CPU resources, only disk space for their separate pg0 instances.