brainy/docs/SCALING.md
David Snelling 35b9d7ef43 refactor(8.0)!: remove orphaned zero-config subsystem + dead cloud/progressive-init storage vestige
The old config-generation subsystem (src/config/ + autoConfiguration.ts) was
superseded during the 8.0 rework and never wired into init(): it emitted settings
for a partitioning subsystem that no longer exists and probed deleted cloud env
vars. The live zero-config path is inline — recall preset → HNSW knobs, storage
auto-detect, auto persistMode, container-memory-aware cache sizing.

The storage progressive-init / cloud-detection cluster was equally dead after the
cloud adapters were dropped: isCloudStorage() is permanently false (no overriders),
scheduleBackgroundInit/runBackgroundInit were never called (the latter an empty
body), initMode was never assigned, and Brainy.isFullyInitialized()/
awaitBackgroundInit() were always-trivial with zero callers. scheduleCountPersist()
collapses to its only-ever-taken immediate write-through path.

Removed:
- src/config/{index,zeroConfig,storageAutoConfig,modelAutoConfig,sharedConfigManager}.ts
- src/utils/autoConfiguration.ts + the inert BrainyZeroConfig export
- Brainy.isFullyInitialized()/awaitBackgroundInit() (+ BrainyInterface decls)
- InitMode type, isCloudStorage/detectCloudEnvironment/resolveInitMode,
  scheduleBackgroundInit/runBackgroundInit/ensureValidatedForWrite and their state
- Dead cloud env-var probes (K_SERVICE/K_REVISION/AWS_LAMBDA_FUNCTION_NAME/
  FUNCTIONS_TARGET/AZURE_FUNCTIONS_ENVIRONMENT)

Kept (verified live): production-detection logging (environment.ts), container-
memory cache sizing (memoryDetection/paramValidation), on-disk hash bucketing
(sharding.ts).

Docs: scrubbed deleted-subsystem references (JS quantization knobs, cloud/OPFS
adapters, partitioning, old zero-config API) across 14 files; deleted two wholly-
obsolete feature docs (complete-feature-list, v3-features); rewrote
architecture/zero-config for 8.0.

~3,700 LOC removed. Build clean; 1392 unit + 24 db-mvcc green.
2026-06-15 11:11:21 -07:00

5.9 KiB

Brainy Scaling Guide

One Line Summary: Single-node by design — Brainy scales by getting the most out of one machine plus operator-layer backup.

Table of Contents

Quick Start

In-Memory

import Brainy from '@soulcraft/brainy'
const brain = new Brainy({ storage: { type: 'memory' } })

On-Disk (Default for Node)

const brain = new Brainy({
  storage: { type: 'filesystem', rootDirectory: './brainy-data' }
})

How Brainy Scales

Brainy 8.0 is a single-node library. There is no cluster, no peer discovery, no S3 coordination. Scaling means:

  • Up: give the process more RAM, CPU, and IOPS
  • Out: stand up multiple independent Brainy instances behind your own service layer
  • Cold storage: snapshot the on-disk artifact off-site so you can rehydrate elsewhere

The three knobs that matter most:

  1. config.vector.recall'fast', 'balanced', or 'accurate' (default 'balanced')
  2. config.vector.persistMode'immediate' for durability, 'deferred' for throughput

The native vector provider (via the optional @soulcraft/cortex package) extends this with a higher-performing index — and its own at-scale acceleration such as on-disk compressed indexing — when installed.

Storage Configurations

const brain = new Brainy({
  storage: {
    type: 'filesystem',
    rootDirectory: '/var/lib/brainy'
  }
})
  • Stores everything in a sharded JSON tree under rootDirectory
  • Atomic writes via rename
  • Survives process restarts
  • Snapshot it off-site with gsutil rsync, aws s3 sync, rclone, or tar from your scheduler

Memory

const brain = new Brainy({ storage: { type: 'memory' } })
  • Zero I/O, fastest possible
  • No persistence — process exit discards everything
  • Use for tests and ephemeral caches

Auto

const brain = new Brainy({
  storage: { type: 'auto', rootDirectory: './data' }
})
  • Picks filesystem when running on Node with a writable rootDirectory
  • Falls back to memory otherwise

Scaling Patterns

Stage 1: Prototype (Memory)

const brain = new Brainy({ storage: { type: 'memory' } })
// Development, tests, <100K items

Stage 2: Production (Filesystem)

const brain = new Brainy({
  storage: { type: 'filesystem', rootDirectory: '/var/lib/brainy' }
})
// Most production workloads up to ~10M entities on a single host

Stage 3: Higher Throughput (Tune the Vector Index)

const brain = new Brainy({
  storage: { type: 'filesystem', rootDirectory: '/var/lib/brainy' },
  vector: {
    recall: 'fast',                // Trade recall for latency
    persistMode: 'deferred'        // Batch persistence
  }
})

Stage 4: Multi-Instance (Operator-Layer)

Run multiple Brainy processes behind your own routing/service layer. Each process owns its own rootDirectory. Sync each artifact off-site independently. Brainy itself does not coordinate between processes.

Real World Examples

Example 1: Single-Node App With Backup

const brain = new Brainy({
  storage: { type: 'filesystem', rootDirectory: '/var/lib/brainy' }
})

Schedule (cron / systemd timer):

*/15 * * * *  rclone sync /var/lib/brainy remote:brainy-backup

Example 2: Tests

const brain = new Brainy({ storage: { type: 'memory' } })
// Fast, no cleanup needed between runs

Example 3: Multi-Tenant Service

Spin up one Brainy instance per tenant, each in its own directory:

function brainForTenant(tenantId: string) {
  return new Brainy({
    storage: {
      type: 'filesystem',
      rootDirectory: `/var/lib/brainy/${tenantId}`
    }
  })
}

Your service layer handles routing and isolation; Brainy stays simple.

Example 4: Higher Recall at Scale

const brain = new Brainy({
  storage: { type: 'filesystem', rootDirectory: '/var/lib/brainy' },
  vector: {
    recall: 'accurate'
  }
})

Tuning Knobs Summary

Setting Values When to change
vector.recall 'fast' / 'balanced' / 'accurate' Trade recall for latency
vector.persistMode 'immediate' / 'deferred' Throughput vs. durability
storage.cache.maxSize integer Hot-path read cache size
storage.cache.ttl ms Cache freshness

Monitoring & Observability

const stats = await brain.stats()
// {
//   nounCount: 50000,
//   verbCount: 80000,
//   vectorIndex: { ... },
//   storage: { used: '45GB' }
// }

Troubleshooting

Issue: Slow queries

  1. Switch to vector.recall: 'fast'
  2. Increase the read cache (storage.cache.maxSize)
  3. Consider the optional native vector provider via @soulcraft/cortex

Issue: Memory pressure

  1. Reduce storage.cache.maxSize
  2. Move to vector.persistMode: 'deferred' to batch writes
  3. Consider the optional native vector provider via @soulcraft/cortex for at-scale index acceleration

Issue: Slow startup after a crash

  1. Use vector.persistMode: 'immediate' so the index file stays in sync with storage
  2. Verify backup integrity periodically

Best Practices

  1. One process = one rootDirectory — never share a directory between processes
  2. Snapshot from your scheduler — Brainy doesn't ship cloud SDKs; use rclone / aws s3 sync / gsutil
  3. Profile before tuningrecall: 'balanced' is right for most workloads
  4. Install the native vector provider only when measured profiling shows it pays off

Summary

  • Brainy 8.0 is a library, not a cluster
  • Storage adapters: filesystem, memory, auto
  • Vector tuning: recall, persistMode
  • Backup is an operator-layer concern — snapshot rootDirectory