> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xpander.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Company Brain on self-hosted installs

> Where Company Brain data stays on a hybrid or air-gapped install, how it works with local models and no internet, the Helm values that turn it on and size it, and the Postgres pgvector image it needs.

The Company Brain runs the same way in xpander cloud, on hybrid installs and on air-gapped installs. On a self-hosted install, everything it stores and caches stays in your cluster.

## Where the data stays

| Data | Where |
| - | - |
| Brains, collections, documents, versions, access lists, learned facts, sources and their scope | Your Postgres |
| Searchable sections and their embeddings | Your Postgres (pgvector) |
| Original files and parsed pages | Your object store |
| Cache | Your Redis, encrypted per organization, every entry with an expiry |
| Access log | Your environment |
| Content of live sources | Nowhere. Read at question time with the person's own account, except folders an admin keeps a copy of |

By default every organization on the install shares the install's Postgres database, and every row carries its organization. To give each organization its own database instead, set `onpremPerOrgDb: true` (see the values below). Decide before you load content: the setting picks one database per organization and never splits one organization's brain across two.

**Hybrid.** xpander cloud never connects to your database, Redis or object store. A brain call that starts in the cloud (Xpander Chat, an MCP client, a Platform page, an upload) is relayed to your install's agent controller, which does the work and returns only the answer. Only usage counts go up. If your install does not answer, the agent is told the company knowledge is offline, and nothing falls back to cloud storage. Live sources are called from your network, so sources that accept only your IP addresses work.

**Air-gapped.** Nothing leaves your environment. Parsing, OCR, embeddings and ranking run on models baked into the images, so nothing is downloaded at run time. Answers are written by the model your install already uses, such as an in-network vLLM, Ollama or NIM endpoint. Usage goes to the local credits ledger when metering is on.

## Turn it on

The Company Brain is off in the charts by default. Turning it on deploys **brain-ingest**, the service that parses, splits and embeds documents, and connects the agent controller to it.

**Hybrid (xpander chart)**

```yaml theme={"dark"}
brain:
  enabled: true
  onpremPerOrgDb: true        # optional: each organization in its own database
  ingest:
    replicas: 1
    objectStore:
      type: local             # or s3
      local:
        persistence:
          size: 20Gi
      s3:
        bucket: ""
        region: ""
        endpointUrl: ""       # for MinIO and other S3-compatible stores
  cacheMaxMemory: 512mb
```

With `type: local`, originals are kept on a volume the chart creates and keeps on uninstall. That volume is `ReadWriteOnce`, so more than one replica needs `accessMode: ReadWriteMany` or `type: s3`; the chart refuses the combination otherwise. S3 credentials come from the pod identity or `envFromSecret`.

**Air-gapped (xpander-airgap chart)**

```yaml theme={"dark"}
brain:
  enabled: true
  cacheMaxMemory: 512mb
global:
  brain:
    enabled: true             # must match brain.enabled; the chart refuses them disagreeing
    onpremPerOrgDb: true      # recommended: each organization in its own database
    ingestReplicas: ""        # keep equal to brain-ingest.replicas (empty means 1)
brain-ingest:
  replicas: 1
```

Originals and parsed pages go to the platform's own object store, in the `kb_files` bucket. The ingest service key is generated and kept across upgrades like every other key. Mirror the `brain-ingest` image with `image_sync.sh` before you install or upgrade.

| Value | Default | What it does |
| - | - | - |
| `brain.enabled` | `false` | Deploys brain-ingest and turns the Company Brain on for the install |
| `onpremPerOrgDb` | `false` | Each organization's brain data in its own database instead of the shared one |
| `cacheMaxMemory` | `512mb` | The most the brain's cache uses in your Redis. Add it to your Redis memory limit |
| `replicas` (ingest) | `1` | Parallel parsing and embedding; each replica takes one document at a time |
| `reranker.backend`, `reranker.url`, `reranker.modelVolume.existingClaim` | `onnx`, empty, empty | Optional ranking model. Without one, search still answers with its combined text and meaning ranking |

### Ranking model

A cross-encoder ranking model (bge-reranker-v2-m3) improves the order of results. It is optional. Pick one `reranker.backend`:

* `ingest`: nothing to stage. The brain-ingest image already includes the model and serves it. Ranking waits at most 5 seconds per question, then answers without it.
* `onnx` (default): stage `model.onnx` and `tokenizer.json` on a volume and name the claim in `reranker.modelVolume.existingClaim`. It is mounted read-only on the agent controller.
* `http`: set `reranker.url` to a ranking endpoint in your network.

On CPU, ranking adds seconds per question; a GPU endpoint keeps it interactive.

## Sizing

Each brain-ingest replica requests 1 vCPU and 4 GiB and may use up to 4 vCPU and 10 GiB. On CPU, one replica with 4 cores embeds about 1.2 sections per second, so a 300-page document takes around 15 minutes. That suits a steady trickle of uploads. For bulk loads, such as moving existing knowledge bases, add replicas or point embedding at a GPU server in your cluster that serves bge-m3.

The brain-ingest image is about 5.2 GB and amd64 only. Budget registry space and the first pull on each node.

## Postgres with pgvector

The brain needs the pgvector extension, version 0.8 or newer. The charts' bundled Postgres runs the pgvector build of the official image on the same major version as before (`pgvector/pgvector:0.8.7-pg15-trixie` on hybrid, `0.8.7-pg16-bookworm` on air-gapped), so an upgrade swaps the image on the same volume and the Postgres pod restarts once.

* **Before you upgrade**, mirror the new image and take a restore point: a snapshot of the Postgres volume, or set `postgres.upgradeGuard.backup.pvcName` to an existing claim and the upgrade writes a full dump there first.
* **During the upgrade**, a guard on the new image refuses to continue if the running server's major version differs from the image's.
* **After every install and upgrade**, a job creates the `vector` extension in every database and the installer prints one status line, for example `pgvector: ok vector=0.8.7 ok=3 failed=none`. A `degraded` or `failed` line names the databases to look at.

**External Postgres** (such as Amazon RDS): install pgvector 0.8 on the server, and run `CREATE EXTENSION vector` once per database where your user cannot create extensions. Without pgvector, the Company Brain is unavailable and everything else keeps working.

## Network

Live sources are reached from your install with each person's own sign-in: Google APIs for Google Drive, Microsoft Graph for SharePoint and OneDrive, and Atlassian's API for Confluence and Jira. On a hybrid install, allow those hosts in your egress policy to use them.

**Air-gapped installs** cannot use live sources yet: they have no OAuth sign-in to Google, Microsoft or Atlassian, so **Add source** says so instead of offering a sign-in. Collections work fully, and with `global.network.internetEgress: false` importing a document from a URL is off as well.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.