Purple8 Hyper Graph — Hardware Sizing Guide
Release: v0.72.0 (pip install purple8-hyper-graph) · Last Updated: 2026-10-26
Applies to: Self-hosted deployments (Developer Free up to 50K nodes / 1 MCP agent, and Enterprise / Custom across Docker, Red Hat OpenShift UBI9, Kubernetes, bare metal, and VM)
Overview
Purple8 Hyper Graph runs entirely on your infrastructure — no mandatory cloud services, no egress fees, no telemetry unless you opt in.
This document covers three deployment configurations:
| Configuration | Description |
|---|---|
| [A] Hyper Only | Graph + vector engine (BrickCoreStorage + BrickWAL + CortexAutoConfig), no document intelligence, no LLM |
| [B] DocIntel + Hyper + BYOK LLM | Full RAG pipeline with a cloud LLM (OpenAI, Anthropic, Google, Bedrock, Azure) |
| [C] DocIntel + Hyper + Local LLM | Full RAG pipeline with a locally hosted LLM (Ollama, vLLM, TGI) |
The one thing that makes Purple8 different from every other database
RAM does not scale with corpus size.
Traditional graph and vector databases have a RAM requirement that grows linearly with data volume (N). Never project Purple8 memory usage by multiplying per-node size by N.
Purple8 Hyper Graph is powered by BrickCoreStorage (Purple8 Cortex) with BrickWAL (fdatasync before mutation) and CortexAutoConfig (auto_config=True). Using the brick seal-and-evict cycle, BrickCoreStorage fills the lock-free Rust DashMap write buffer for one batch, seals the batch to BrickWAL with a single os.write() + fdatasync(), and immediately evicts completed buffer entries back to the OS. CortexAutoConfig probes your available RAM at startup and derives (M, ef_construction, segment_size, batch_size) so that peak process RSS is bounded by alpha * available_ram (default 0.75). On a constrained machine it uses a smaller working batch — ingest takes longer, but it always completes correctly.
The result: the same software runs on a 4 GB edge device and a 256 GB server. You do not need to resize your fleet's RAM when your corpus grows — you add storage, not RAM.
What drives RAM in Purple8:
- Your embedding dimension (the dominant factor for batch buffer sizing)
- Your LLM model size (Config C only — the local LLM weights, not Purple8 itself)
- A small search index metadata footprint that grows slowly (~64 MB at 1M nodes, ~3.2 GB at 50M nodes)
What does NOT drive RAM in Purple8:
- Total corpus size (number of nodes or documents
N)
See the Memory Model section for validated numbers.
Hardware & Accelerator Auto-Discovery (CortexAutoConfig & worker_solver.py)
At startup, CortexAutoConfig and worker_solver.py automatically discover the host's compute and accelerator topology:
- Multi-socket CPU & NUMA topology: Detects
cpu_socketsandnuma_nodes, automatically derivingrecommended_shards = max(cpu_sockets, numa_nodes)so shard instances align with physical NUMA domains. - Intel AMX & Intel XPU: Automatically detects Intel AMX tile instructions (
amx_tile,amx_int8,amx_bf16) on Intel Xeon Scalable processors and Intel XPU (torch.xpuintegrated and discrete Intel Arc / Data Center GPU Max accelerators). - NVIDIA Tensor Core GPUs: Automatically detects NVIDIA Hopper (
H100/H200,sm_90) and NVIDIA Blackwell Ultra B300 / GB300 (288 GB HBM3e, compute capabilitysm_103, 5th-gen FP4 Tensor Cores). - Apple Silicon Metal / Unified Memory: Detects Apple M-series unified memory (
mps), allowingBrickCoreStorageand local LLMs to share physical RAM without PCIe transfer overhead.
Configuration A — Hyper Only
Pure graph + vector engine. No document parsing, no LLM generation.
What sets your RAM requirement: embedding dimension × batch size only. The table below is the same regardless of whether you have 100K or 50M nodes.
| Embedding Model | Dim | Peak RSS (ingest) | RSS (query, steady-state) |
|---|---|---|---|
all-MiniLM-L6-v2, all-minilm (Ollama) | 384 | ~9 GB | ~5.4 GB |
nomic-embed-text | 768 | ~12 GB (est.) | ~7 GB (est.) |
text-embedding-3-small, Titan v2 | 1536 | ~16 GB (est.) | ~10 GB (est.) |
text-embedding-3-large, gemini-embedding-2 | 3072 | ~24 GB (est.) | ~16 GB (est.) |
384-dim figures are validated at 8,841,823 nodes (full MS MARCO corpus, Apple M-series, 24 GB, May 7, 2026). Higher-dim rows are estimates scaled by embedding dimension — run your own ingest benchmark to confirm.
Hardware (Config A)
| Component | Minimum | Ideal |
|---|---|---|
| CPU | 4 cores (x86-64 or ARM64) | 8–16 cores, AVX2 |
| RAM | 16 GB (384-dim) · 32 GB (3072-dim) | Same — RAM scales with dim during ingest, drops at query time |
| Storage | See storage table below | NVMe ≥ 3 GB/s for large corpora |
| OS | Linux (Ubuntu 22.04+) or macOS 13+ | Linux Ubuntu 22.04 LTS |
| Python | 3.11 or 3.12 | 3.12 |
| Network | None required — fully offline | — |
There is no "enterprise RAM tier" for Config A. If you're at 50M nodes with 384-dim embeddings, you still need ~6 GB of RAM for Purple8. You need more storage and more CPU for graph traversal at scale — not more RAM.
Storage Sizing — Configuration A
Storage is the axis that scales with corpus size. Plan your disk here.
| Corpus Size | 384-dim (MiniLM) | 768-dim (nomic) | 1536-dim (OpenAI small) | 3072-dim (OpenAI large) |
|---|---|---|---|---|
| 500K nodes | ~4 GB | ~6 GB | ~10 GB | ~18 GB |
| 1M nodes | ~7 GB | ~11 GB | ~20 GB | ~36 GB |
| 5M nodes | ~32 GB | ~50 GB | ~95 GB | ~180 GB |
| 10M nodes | ~62 GB | ~98 GB | ~185 GB | ~355 GB |
| 50M nodes | ~305 GB | ~480 GB | ~920 GB | ~1.75 TB |
Includes graph storage, WAL, and HNSW index. Add 20% headroom for edge-heavy graphs and WAL retention. Use NVMe for corpora above 10M nodes.
Configuration B — DocIntel + Hyper + BYOK LLM
Full RAG pipeline. Embeddings and LLM generation go to a cloud provider (your API key — their compute). Supported: OpenAI, Anthropic, Google, Azure OpenAI, AWS Bedrock, Mistral, Cohere.
What sets your RAM requirement: same as Config A — embedding dim × batch size. The cloud provider handles all LLM inference. Purple8 itself does not hold model weights in memory.
Additional requirements over Config A:
- Internet access (HTTPS outbound to your LLM provider)
- API key for your chosen provider
- +1–2 GB RAM for the document processing and chunking pipeline
Hardware (Config B)
| Component | Minimum | Ideal |
|---|---|---|
| CPU | 4 cores | 8–16 cores |
| RAM | 10 GB (384-dim) · 18 GB (3072-dim) | Same — RAM driven by embedding dim, not corpus |
| Storage | See Config A storage table | NVMe for large corpora |
| Network | Stable broadband, HTTPS to LLM provider | < 50 ms to provider endpoint for low-latency RAG queries |
| API key | Required | — |
Default Models (BYOK)
| Provider | Default LLM | Default Embedding | Embedding Dim |
|---|---|---|---|
| OpenAI | gpt-5.4-mini | text-embedding-3-large | 3072 |
| Anthropic | claude-haiku-4-5-20251001 | text-embedding-3-large (OpenAI) | 3072 |
gemini-2.5-flash | gemini-embedding-2 | 3072 | |
| Azure OpenAI | gpt-5.4-mini | text-embedding-3-large | 3072 |
| AWS Bedrock | claude-haiku-4-5-20251001-v1:0 | amazon.titan-embed-text-v2:0 | 1536 |
| Mistral | mistral-large-latest | — | — |
| Cohere | command-r-plus-08-2024 | — | — |
Most cloud providers default to 3072-dim embeddings. If your workload is cost-sensitive and retrieval quality at 1536-dim is acceptable, switching to Bedrock Titan or OpenAI
text-embedding-3-smallhalves your storage footprint with no change to your RAM requirement.
Airgapped or network-restricted deployments cannot use BYOK. Use Config C.
Configuration C — DocIntel + Hyper + Local LLM
Full RAG pipeline with a locally hosted LLM. No API keys, no internet after initial model download. All inference runs on your hardware.
What sets your RAM requirement: Purple8's share is the same small envelope as Configs A/B. The dominant RAM consumer is the LLM model weights. Size your machine for the LLM you want to run — Purple8 fits in whatever headroom remains.
Total RAM needed = Purple8 share (6–14 GB, set by embedding dim)
+ LLM model RAM (set by model size and quantisation)
+ OS overhead (~2 GB)LLM RAM Footprint by Model Size
| Model | Quantisation | VRAM / Unified RAM needed | Generation speed (CPU) | Generation speed (GPU) |
|---|---|---|---|---|
| 3B (llama3.2:3b, phi3) | Q4 | ~3 GB | 15–30 tok/s | 60–100 tok/s |
| 7B (llama3, mistral:7b) | Q4 | ~5 GB | 8–15 tok/s | 40–80 tok/s |
| 7B | Q8 | ~8 GB | 5–10 tok/s | 35–70 tok/s |
| 13B (llama2:13b) | Q4 | ~8 GB | 4–8 tok/s | 25–50 tok/s |
| 34B (codellama:34b) | Q4 | ~20 GB | 1–3 tok/s | 10–25 tok/s |
| 70B (llama3.3:70b) | Q4 | ~40 GB | 0.5–1 tok/s | 8–15 tok/s |
Worked Examples — Total RAM for Config C
| Embedding | LLM | Total RAM — ingest peak | Total RAM — query steady-state | Suitable machine |
|---|---|---|---|---|
| 384-dim + llama3.2:3b | ~9 + 3 + 2 = ~14 GB | ~5.4 + 3 + 2 = ~10 GB | M5 base 16 GB, RTX 4060 8 GB | |
| 384-dim + llama3:7b Q4 | ~9 + 5 + 2 = ~16 GB | ~5.4 + 5 + 2 = ~12 GB | M5 Pro 24 GB, RTX 4070 | |
| 3072-dim + llama3:7b Q4 | ~24 + 5 + 2 = ~31 GB | ~16 + 5 + 2 = ~23 GB | M5 Pro 48 GB, RTX 3090 | |
| 3072-dim + llama3.3:70b Q4 | ~24 + 40 + 2 = ~66 GB | ~16 + 40 + 2 = ~58 GB | M5 Max 64 GB (query only), M5 Ultra, A100 |
"Ingest peak" is the worst-case machine requirement. "Query steady-state" is the footprint once ingest is done — the engine returns ~3.6 GB to the OS at 384-dim.
Apple Silicon (M-series) — Unified Memory
Unified memory (CPU + GPU share physical RAM) makes Apple Silicon particularly well-suited for Config C. Purple8 and the LLM share the same memory pool with no PCIe transfer overhead.
| Chip | Unified Memory Options | What fits comfortably |
|---|---|---|
| M2 / M3 (base) | 8 GB, 16 GB, 24 GB | Purple8 + 3B–7B Q4 on 16 GB |
| M2 Pro / M3 Pro | 18 GB, 36 GB | Purple8 + 7B–13B Q4 |
| M2 Max / M3 Max | 32 GB, 64 GB, 96 GB | Purple8 + 34B Q4 |
| M4 (base) | 16 GB, 24 GB, 32 GB | Purple8 + 7B Q4 on 16 GB |
| M4 Pro | 24 GB, 48 GB | Purple8 + 13B–34B Q4 |
| M4 Max | 36 GB, 64 GB, 128 GB | Purple8 + 70B Q4 on 128 GB |
| M5 (base) | 16 GB, 24 GB, 32 GB | Purple8 + 7B Q4 on 16 GB |
| M5 Pro | 24 GB, 48 GB, 64 GB | Purple8 + 13B–34B Q4 |
| M5 Max | 64 GB, 128 GB | Purple8 + 70B Q4 |
| M5 Ultra | 128 GB, 256 GB, 512 GB | Entire enterprise stack — Purple8 + 405B |
Purple8 validated benchmark (8.84M nodes, 384-dim, Apple M-series, 24 GB, May 7, 2026): Purple8 peak RSS during ingest = ~9 GB; drops to ~5.4 GB at query time (−3,626 MB returned to OS after ingest completes). On a 16 GB M-series host, this leaves ~6–10 GB free for a 7B Q4 LLM depending on ingest vs query phase.
GPU / XPU VRAM vs Model Size Reference
| Accelerator Memory | Max model (Q4_K_M / FP4) | Example Accelerators |
|---|---|---|
| 6–8 GB | 7B Q4 (4.1 GB) | RTX 3060, RTX 4060, Intel Arc A750 |
| 12–16 GB | 13B Q8 / 14B Q4 | RTX 4070, RTX 4080, A4000, Intel Arc A770 (torch.xpu) |
| 24 GB | 34B Q4 (20 GB) | RTX 3090, RTX 4090, NVIDIA A10G, NVIDIA L4 |
| 40–80 GB | 70B Q4 / 70B Q8 | NVIDIA A100 (40/80 GB), NVIDIA H100 (80 GB, sm_90) |
| 128–141 GB | 110B Q8 / 405B FP4 | Intel Data Center GPU Max (torch.xpu), NVIDIA H200 (141 GB HBM3e) |
| 192 GB | 405B Q4 / FP8 | NVIDIA Blackwell B200 (sm_100) |
| 288 GB HBM3e | 405B+ FP8 / Multi-70B FP4 | NVIDIA Blackwell Ultra B300 / GB300 (sm_103, FP4 Tensor Cores) |
Recommended Local LLM Stack
| Stack | Best for | Notes |
|---|---|---|
| Ollama | Development, single-machine | Easiest setup, auto-manages models |
| vLLM | Production, high throughput, multi-GPU | PagedAttention, continuous batching |
| HuggingFace TGI | Custom models, fine-tunes | Full HF Hub compatibility |
| llama.cpp server | CPU-only, edge deployments | Best Q4/Q8 CPU performance |
Default Models (Local / Ollama)
| Role | Default Model | Disk | RAM |
|---|---|---|---|
| Generation | llama3.2:3b | ~2 GB | ~3 GB |
| Embedding | nomic-embed-text:latest | ~300 MB | ~500 MB |
| Embedding (fast/light) | all-minilm:latest | ~45 MB | ~100 MB — 384-dim |
| Generation (balanced) | mistral-nemo:12b | ~7 GB | ~10 GB |
| Generation (capable) | llama3.3:70b | ~40 GB | 40 GB VRAM or ~80 GB RAM |
Memory Model
Purple8 sizes itself to your hardware automatically
When Purple8 starts, it detects how much RAM is available on your machine and automatically configures its processing batch size to stay within that envelope. You don't set memory limits or tune parameters — it figures out what fits and adjusts accordingly.
The trade-off is time, not correctness:
- More RAM available → larger batch → faster ingest
- Less RAM available → smaller batch → ingest takes longer, but completes correctly
- The same corpus runs on a 4 GB machine or a 128 GB machine — just faster on the bigger one
This means you never hit an out-of-memory error during ingest, regardless of corpus size. Purple8 will always find a batch geometry that fits.
RAM does not scale with corpus size
However you configure it, Purple8's peak RAM is determined by your embedding dimension — not by how many documents you have stored. A machine that handles a 1M node corpus handles a 50M node corpus with identical peak memory. When your corpus grows, you add storage, not RAM.
Validated numbers (May 7, 2026)
Full MS MARCO passage corpus — 8,841,823 passages · 384-dim embeddings · Apple M-series, 24 GB
| Phase | RAM |
|---|---|
| During ingest | ~9 GB peak — stable from node 1 to node 8.84M |
| After ingest, at query time | ~5.4 GB — engine releases ~3.6 GB back to OS |
No swap was required. The peak held at the same level from the very first batch to the last. The same 16 GB machine handles this corpus and any larger one.
Index RAM (the one thing that does grow — slowly)
Purple8 keeps a small in-memory index to accelerate search. This grows with corpus size but very gradually:
| Corpus size | Index RAM |
|---|---|
| 1M nodes | ~64 MB |
| 5M nodes | ~320 MB |
| 10M nodes | ~640 MB |
| 50M nodes | ~3.2 GB |
At 50M nodes this adds ~3.2 GB — a predictable, plannable cost.
The bottom line
On a 16 GB machine with 384-dim embeddings:
- Purple8 peak during ingest: ~9 GB (validated at 8.84M nodes)
- Purple8 at query time: ~5.4 GB
- Index overhead at 10M nodes: ~640 MB
- Remaining headroom at query time: ~9 GB — enough for a 7B LLM (Config C)
You do not need to upgrade RAM as your corpus grows. You upgrade storage.
Quick Comparison
| Config A — Hyper Only | Config B — BYOK LLM | Config C — Local LLM | |
|---|---|---|---|
| RAM driver | Embedding dim | Embedding dim | Embedding dim + LLM model size |
| RAM scales with corpus? | No | No | No |
| Typical min RAM | 8–16 GB (by dim) | 10–18 GB (by dim) | 16–64 GB (by LLM size) |
| Storage scales with corpus? | Yes | Yes | Yes |
| Internet required | No | Yes | No (after download) |
| API key required | No | Yes | No |
| GPU required | No | No | Recommended |
| Latency (RAG query) | N/A (no LLM) | 1–5 s (API) | 0.5–3 s (GPU) / 5–30 s (CPU) |
| Cost model | Hardware only | Hardware + API fees | Hardware only |
| Air-gap compatible | ✅ | ❌ | ✅ |
| Data leaves premises | No | Yes (to LLM provider) | No |
Software Requirements (All Configurations)
| Requirement | Version |
|---|---|
| Python | 3.11 or 3.12 (3.12 recommended) |
| Docker | 24.0+ (if using container deployment) |
| Docker Compose | 2.20+ |
| OS — Linux | Ubuntu 22.04 LTS, Debian 12, RHEL 9 / Red Hat UBI9 (ubi9/python-312:9.5), or equivalent |
| OS — macOS | 13.0+ (Ventura) |
| OS — Windows | Windows 11 + WSL2 (Ubuntu 22.04) |
| glibc | 2.34+ (RHEL 9 / UBI9 via Dockerfile.rhel) or 2.35+ (Ubuntu 22.04+) |
| CUDA | 12.1+ (12.8+ for NVIDIA Blackwell / Blackwell Ultra B300 sm_103) |
| Ollama | 0.3.0+ (Config C only) |
Python Packages (auto-installed via pip)
Core: hnswlib, numpy, fastapi, uvicorn, pydantic>=2.0, structlog, orjson, PyJWT[cryptography], lark
Optional (auto-detected): scipy (AEC spectral), ifcopenshell (BIM/IFC), openai, anthropic, google-generativeai, boto3, transformers
Ports and Networking
| Port | Protocol | Purpose | Configurable |
|---|---|---|---|
8000 | TCP/HTTP | Purple8 REST API | P8G_PORT |
8001 | TCP/HTTP | MCP Server | P8G_MCP_PORT |
9090 | TCP/HTTP | Prometheus metrics (/metrics) | P8G_METRICS_PORT |
11434 | TCP/HTTP | Ollama (Config C, local only) | OLLAMA_BASE_URL |
All ports are configurable. No inbound ports are required unless exposing the API externally. For K8s deployments, all communication is cluster-internal by default.
Kubernetes Resource Requests
Recommended resources block for the Purple8 pod.
Key principle: Purple8's memory limit does NOT increase with corpus size. Set the limit based on your embedding dimension (see Memory Model section). Adding more nodes → more storage PVC, NOT more memory.
Config A / B — 384-dim embeddings (e.g. MiniLM, nomic)
resources:
requests:
memory: "6Gi" # Query-time steady-state (validated: ~5.4 GB at 8.84M nodes)
cpu: "2"
limits:
memory: "12Gi" # Ingest peak ~9 GB + headroom; same at any corpus size
cpu: "8"Config A / B — 1536-dim or 3072-dim embeddings (e.g. OpenAI, Gemini)
resources:
requests:
memory: "12Gi"
cpu: "2"
limits:
memory: "28Gi" # Estimated ingest peak for 3072-dim; validated data pending
cpu: "8"Config C (Purple8 container + Ollama sidecar, 7B Q4 model)
# Purple8 container
resources:
requests:
memory: "6Gi" # Query-time steady-state
cpu: "2"
limits:
memory: "12Gi" # Ingest peak; corpus-size independent
cpu: "8"
# Ollama sidecar — sized for the LLM model, not the corpus
resources:
requests:
memory: "5Gi" # 7B Q4 working set
cpu: "4"
limits:
memory: "8Gi"
cpu: "16"
nvidia.com/gpu: "1" # if using GPU node poolScaling advice: When your corpus grows from 1M to 50M nodes, increase your storage PVC size — not your memory limits. Memory limits are stable once set for your embedding dimension.
Notes for Specific Environments
Docker Desktop (macOS / Windows)
- Set Docker Desktop memory to at least 14 GB (Config A/B, 384-dim — covers ~9 GB ingest peak + OS overhead). At query time only ~7–8 GB is needed. For 3072-dim ingest peak, allocate at least 28 GB.
- For Config C with a 7B Q4 model, allocate 18 GB (Purple8 ingest ~9 GB + Ollama ~8 GB + OS). Once ingest is done, ~14 GB suffices.
- Enable VirtioFS file sharing for NVMe-comparable I/O on the data volume.
- CPU-only Ollama inference works well on Apple Silicon via Docker Desktop with hardware acceleration (Docker Desktop 4.30+).
AWS EC2
| Config | Recommended instance | Notes |
|---|---|---|
| A/B · 384-dim | m7g.xlarge (4 vCPU, 16 GB, ARM64) | Purple8 needs ~10 GB peak — 16 GB is the right size at any corpus |
| A/B · 3072-dim | m7g.2xlarge (8 vCPU, 32 GB, ARM64) | 32 GB comfortable for 3072-dim at any corpus; scale CPU for throughput |
| C (7B Q4, GPU) | g5.xlarge (4 vCPU, 16 GB, 24 GB VRAM) | A10G — Purple8 + Ollama 7B fits in 16 GB system + GPU memory |
| C (34B Q4, GPU) | g5.12xlarge (48 vCPU, 192 GB, 4× 24 GB VRAM) | Multi-GPU Ollama |
| C (70B Q4, GPU) | p4d.xlarge or g5.48xlarge | 70B Q4 needs ~40 GB VRAM; A100 40GB ideal |
GCP
| Config | Recommended machine | Notes |
|---|---|---|
| A/B · 384-dim | n2-standard-4 (4 vCPU, 16 GB) | Purple8 needs ~10 GB — no need for highmem tiers |
| A/B · 3072-dim | n2-standard-8 (8 vCPU, 32 GB) | Scale CPU for throughput; RAM is still embedding-dim-driven |
| C (GPU) | a2-highgpu-1g (12 vCPU, 85 GB, A100 40 GB) | Best for 70B Q4 models |
Azure
| Config | Recommended VM | Notes |
|---|---|---|
| A/B · 384-dim | Standard_D4s_v5 (4 vCPU, 16 GB) | Purple8 peak ~10 GB — 16 GB is the right size at any corpus |
| A/B · 3072-dim | Standard_D8s_v5 (8 vCPU, 32 GB) | RAM driven by dim, not corpus; scale VM SKU for throughput |
| C (GPU) | Standard_NC24ads_A100_v4 (24 vCPU, 220 GB, A100 80 GB) | Best for large models |