Deployment Sizing Guide

July 19, 2026 · View on GitHub

This guide gives starting points for controlled self-hosted deployments. Actual requirements depend on feed volume, number of analysts, LLM provider latency, uploaded report size, RAG document/chunk count, embedding dimensions, malware-analysis workload, and Attack Simulation usage. The profiles below do not include CPU/GPU/RAM for a separately deployed local chat or embedding model.

Profiles

ProfileAnalystsCPURAMDiskRecommended Use
Small1-34 vCPU8-12 GiB80-150 GiB SSDLab, evaluation, private analyst workstation
Medium3-108 vCPU24-32 GiB250-500 GiB SSDInternal CTI/detection team with scheduled feeds
Large10-3016 vCPU48-64 GiB1 TiB+ SSDShared team deployment, broad IOC/CVE/feed sync, heavier malware triage

Per-Service Starting Points

ServiceSmallMediumLarge
PostgreSQL1 vCPU / 2 GiB2 vCPU / 4-8 GiB4 vCPU / 16 GiB
API1-2 vCPU / 2 GiB2 vCPU / 4 GiB4 vCPU / 8 GiB
Worker1-2 vCPU / 2-3 GiB2-4 vCPU / 6-8 GiB6-8 vCPU / 16 GiB
Redis0.5 vCPU / 512 MiB1 vCPU / 1 GiB2 vCPU / 2 GiB
MalwareGraph1-2 vCPU / 2 GiB2-4 vCPU / 4-8 GiB4-8 vCPU / 16 GiB
Frontend0.5 vCPU / 256 MiB0.5 vCPU / 512 MiB1 vCPU / 1 GiB

Unified RAG Capacity

RAG reconciliation materializes the selected normalized sources, creates bounded chunks, writes PostgreSQL full-text vectors, and optionally calls the private embedding endpoint in batches. Only one corpus reconciliation is active at a time, but ordinary Celery jobs still share the worker pool.

Use /api/rag/status and /api/rag/index-runs to record:

  • active/tombstoned document count;
  • chunk count and per-source coverage;
  • complete, pending, and failed embedding counts;
  • latest indexed time, run duration, heartbeat, attempts, and failure summary;
  • exact/full-text/vector retrieval mode observed in a representative query.

For pgvector's default 32-bit elements, the raw vector payload is approximately:

$\text{text} \text{chunk\_count} \times \text{embedding\_dimensions} \times 4 \text{bytes} $

This excludes PostgreSQL tuple/WAL overhead, document and text content, GIN and HNSW indexes, dead tuples, backups, and free-space headroom. As a starting budget, reserve at least two to four times the raw vector payload in addition to the lexical/source text footprint, then measure the real database after the first full reconciliation. HNSW index construction and query performance need memory headroom; avoid sizing PostgreSQL so tightly that the OS begins swapping.

At the default 768 dimensions, one raw vector is roughly 3 KiB before database and index overhead. Changing dimensions changes both model compatibility and storage; it is a schema migration plus full-reindex decision, not an online tuning knob.

The embedding service should accept RAG_EMBEDDING_BATCH_SIZE texts within the worker timeout and return exactly the configured dimensions. Reduce the batch size if the service rejects payloads or exhausts accelerator memory. Keep RAG_EMBEDDING_ENABLED=false until the endpoint is measured; exact and PostgreSQL full-text search provide a supported lower-resource mode.

Disk Planning

Plan storage for:

  • PostgreSQL database: ATT&CK/ATLAS, APTs, IOCs, CVEs, reports, cases, users.
  • PostgreSQL RAG data: normalized document copies, chunk text, generated full-text vectors, optional embeddings/HNSW index, assistance provenance, and expiring proposals.
  • adversarygraph_logs: API logs, Attack Simulation logs, observability log tail.
  • malwaregraph_storage: uploaded samples, extracted artifacts, static-analysis output.
  • attck_data: cached ATT&CK/ATLAS bundles.
  • Backups: at least 7-30 logical dumps, depending on retention.

Suggested baseline:

  • Small: 80 GiB SSD plus 80 GiB backup target.
  • Medium: 250 GiB SSD plus 500 GiB backup target.
  • Large: 1 TiB SSD plus 2 TiB backup target.

Operational Notes

  • Keep PostgreSQL data on persistent SSD-backed storage.
  • Keep backups outside the primary data directory.
  • Disable AUTO_IOC_FULL_SYNC_ON_STARTUP in production and run feed sync on a planned schedule.
  • Enable auth before exposing the UI beyond localhost.
  • Use an external reverse proxy or ingress for TLS.
  • Monitor /api/health for process liveness, /api/ready for database-backed traffic readiness, /api/observability/summary, and service logs.
  • Monitor /api/rag/status and recent index runs. Alert on an empty enabled corpus, stale reconciliation, failed embeddings, repeated redispatch, or unexpected growth in tombstoned documents and retained assistance.
  • Schedule the initial/full reconciliation outside peak analyst and feed-sync windows for large databases. The worker must connect directly to PostgreSQL or through PgBouncer session pooling because its advisory lock spans commits on one database session.
  • Size and monitor the private model gateway independently. GPU memory, model context limits, concurrency, latency, and provider logs are outside the table above.