Rekalldocs
Guides

Self-hosting (Enterprise)

Run the SKIM engine inside your own network — a licensed single binary plus a versioned model artifact. Cloud Run, Kubernetes, or VMs. The exact same API as the managed cloud.

Self-hosting is an enterprise offering. Licensed customers run the SKIM engine themselves — the same single binary the managed cloud runs, paired with a licensed model artifact you point the binary at. rekall serve exposes the identical REST API as the managed cloud; the only thing that changes for your clients is the base URL.

The same-API promise holds

Cloud is https://api.rekall.sh/v1; your deployment is whatever host you serve on. Point any SDK or the CLI client at it by setting REKALL_BASE_URL — nothing else changes. Develop against the cloud, deploy on-prem, by changing a URL. There is no GPU anywhere in the serving path.

Getting the license & model artifact

The binary and the versioned model artifact are provided under an enterprise license. Talk to us to get access, your model bucket, and keys.

Configuration

The server is configured entirely through environment variables. The model artifact and the knowledge directory are the two things you must point it at.

VariablePurposeExample
REKALL_MODEL_URILocation of the versioned model folder. A local path, or an s3:// / gs:// bucket folder holding the model version.gs://customer-bucket/rekall/models/v0.1 · s3://acme-rekall/models/v0.1 · /opt/rekall/models/v0.1
REKALL_MODEL_CACHELocal directory where a remote model is downloaded and cached, so restarts don't re-fetch it./var/cache/rekall/model
REKALL_DATA_DIRKnowledge storage root. Stores live in per-project subfolders (<data-dir>/<project>/…)./var/lib/rekall
REKALL_PROJECTDefault project name for stores when a request doesn't specify one.acme
REKALL_ENRICH_URLOptional: OpenAI-compatible endpoint for LLM answers and image / scanned-PDF ingestion (default: OpenRouter).http://vlm:8000/v1
REKALL_ENRICH_MODELAnswer model. Setting it routes answer=true through this LLM instead of the native decoder.deepseek/deepseek-v4-flash
REKALL_VISION_MODELVision model for image ingestion; falls back to REKALL_ENRICH_MODEL when unset.qwen/qwen3.5-flash-02-23
REKALL_ENRICH_API_KEYBearer token for the enrichment endpoint, if required.
REKALL_API_KEYPresent on clients; the server issues and validates keys via rekall keys.rk_live_…

Model URIs are versioned folders — pin a version (…/models/v0.1) so a deployment serves a known checkpoint, and roll forward deliberately by pointing at a new folder.

export REKALL_MODEL_URI="gs://customer-bucket/rekall/models/v0.1"
export REKALL_MODEL_CACHE="/var/cache/rekall/model"
export REKALL_DATA_DIR="/var/lib/rekall"
export REKALL_PROJECT="acme"

rekall serve --port 9009
Output
rekall 0.2.0 · engine skim-v1 (CPU)
  model    gs://customer-bucket/rekall/models/v0.1  → cached /var/cache/rekall/model
  data-dir /var/lib/rekall   project acme
  auth     enabled (2 keys)
  listening on http://0.0.0.0:8080  →  API at /v1

The model loads on startup — a few seconds when pulling from a bucket into REKALL_MODEL_CACHE, near-instant from a warm cache or a local path.

Point clients at it

Everything speaks the same API — just set the base URL.

export REKALL_BASE_URL=https://rekall.internal.acme.com/v1
export REKALL_API_KEY=ck_live_…

rekall ingest ./docs --store demo
rekall search "which supplier contract conflicts with the 2026 policy?" --store demo
import { Rekall } from "rekall-search";

const rekall = new Rekall({
  baseUrl: "https://rekall.internal.acme.com/v1",
  apiKey: process.env.REKALL_API_KEY,
});
from rekall import Rekall

rekall = Rekall(
    base_url="https://rekall.internal.acme.com/v1",
    api_key=os.environ.get("REKALL_API_KEY"),
)
curl https://rekall.internal.acme.com/v1/health
# { "status": "ok", "version": "1.0.0", "engine": "skim-v1" }

Authentication

The server requires a per-project API key (Authorization: Bearer <key>). Issue and manage them with the CLI on the server host:

rekall keys create            # prints a new rk_… key once — store it
rekall keys list
rekall keys revoke ck_live_…

--no-auth is for local dev only

rekall serve --no-auth disables key checks for a throwaway local-development server on your own machine. Anyone who can reach the port can then read and write every store — never run a real deployment with --no-auth.

Knowledge storage

REKALL_DATA_DIR holds everything the server persists — the learned document encodings and the original document text — organized into per-project subfolders (<data-dir>/<project>/<store>/…). It's a plain directory: back it up, snapshot it, or move it between hosts. Because ingestion is incremental and there's no reindex, there is no rebuild step after a restore. On managed platforms, mount durable storage here (see the Cloud Run recipe below).

Deploy on Cloud Run

Rekall is a single CPU-only binary, so it drops straight onto Cloud Run.

Dockerfile
FROM gcr.io/distroless/base-debian12
COPY rekall /usr/local/bin/rekall
# Model is pulled from REKALL_MODEL_URI at startup into REKALL_MODEL_CACHE.
ENTRYPOINT ["rekall", "serve"]

Cloud Run injects $PORT; have the binary bind it:

gcloud run deploy rekall \
  --image=REGION-docker.pkg.dev/PROJECT/rekall/rekall:0.2.0 \
  --cpu=4 --memory=4Gi --no-cpu-throttling \
  --min-instances=1 \
  --set-env-vars=REKALL_MODEL_URI=gs://customer-bucket/rekall/models/v0.1 \
  --set-env-vars=REKALL_MODEL_CACHE=/tmp/rekall-model \
  --set-env-vars=REKALL_DATA_DIR=/data,REKALL_PROJECT=acme \
  --add-volume=name=knowledge,type=cloud-storage,bucket=acme-rekall-data \
  --add-volume-mount=volume=knowledge,mount-path=/data \
  --args=serve,--port,$PORT

Two things matter here:

  • Persist knowledge with a GCS volume mount. Cloud Run instances are ephemeral — mount a Cloud Storage bucket at REKALL_DATA_DIR (/data) so stores survive restarts and scale-out. The model can live in a separate GCS folder (REKALL_MODEL_URI), cached to the instance's local /tmp.
  • Keep --min-instances ≥ 1. The model load takes a few seconds on cold start; a warm minimum instance keeps first-query latency flat.

The same image runs on Kubernetes (mount a PVC at REKALL_DATA_DIR, a readiness probe on /v1/health) or any VM.

Run it as a service (systemd) on a VM

/etc/systemd/system/rekall.service
[Unit]
Description=Rekall Neural Search server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=rekall
Group=rekall
Environment=REKALL_MODEL_URI=gs://customer-bucket/rekall/models/v0.1
Environment=REKALL_MODEL_CACHE=/var/cache/rekall/model
Environment=REKALL_DATA_DIR=/var/lib/rekall
Environment=REKALL_PROJECT=acme
Environment=REKALL_LOG=info
ExecStart=/usr/local/bin/rekall serve --port 9009
Restart=on-failure
RestartSec=2

# Hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/rekall /var/cache/rekall
PrivateTmp=true

[Install]
WantedBy=multi-user.target
sudo useradd --system --home /var/lib/rekall --shell /usr/sbin/nologin rekall
sudo install -d -o rekall -g rekall /var/lib/rekall /var/cache/rekall
sudo systemctl daemon-reload
sudo systemctl enable --now rekall
sudo systemctl status rekall

Health checks

Point your load balancer, Cloud Run readiness probe, or uptime monitor at the unauthenticated health endpoint:

curl https://rekall.internal.acme.com/v1/health
# { "status": "ok", "version": "1.0.0", "engine": "skim-v1" }

See the Health endpoint for the response shape.

Where it runs

CPU-only means Rekall runs wherever you have commodity compute:

On-prem / VPC

A single binary inside your network — no GPU procurement, no data leaving your walls.

Cloud Run / K8s

One CPU container, autoscaled; knowledge on a mounted GCS volume or PVC.

Air-gapped

Point REKALL_MODEL_URI at a local path; no outbound calls in the serving path.

Next steps

On this page