rugmuncher-backend / backend /docs /adr /0002-why-five-databases.md
RMI Platform
feat(v3): ship new system β€” skip _legacy_main, mount v1 routers
3cf0daf
|
Raw
History Blame Contribute Delete
2.69 kB

ADR-0002: Use 5 specialized databases instead of one general-purpose store

  • Status: Accepted
  • Date: 2026-06-21
  • Decider: @cryptorugmunch

Context

RMI stores data across multiple categories:

Category Volume Access pattern Query shape
User data, wallets, alerts (relational) 252K rows CRUD + joins SQL
Cache, rate limits, labels (key-value) 82K keys O(1) get/set key lookup
Analytics, cost tracking, legacy logs (columnar) 83K rows (will grow) Aggregate scans SQL OLAP
Wallets, tokens, transfers (graph) 20K nodes Multi-hop traversal Cypher
Embeddings, semantic search (vector) 75 vectors k-NN similarity HNSW

A single Postgres would not serve all five patterns efficiently:

  • Graph queries in Postgres require recursive CTEs that scale O(nΒ²)
  • Vector search in Postgres uses pgvector but is 10Γ— slower than Qdrant
  • OLAP scans in Postgres lock transactional tables
  • Cache in Postgres requires manual eviction policies

Decision

Use five specialized databases:

  1. Postgres 16 β€” source of truth (relational data)
  2. Redis 7.2 β€” cache, rate limits, queues
  3. ClickHouse β€” OLAP, cost tracking, deprecation logs
  4. Neo4j 5 β€” graph queries (cross-chain wallet flows)
  5. Qdrant β€” vector search (RAG semantic retrieval)

Plus DuckDB for local analytics on the laptop (single-file, no server).

Alternatives Considered

  • All Postgres (with extensions): pgvector + recursive CTEs + pg_partman. Rejected β€” graph perf unacceptable, OLAP competes with transactional load.
  • Single MongoDB: Rejected β€” weak analytics, no vector search, no graph.
  • DynamoDB + S3 + Neptune: Rejected β€” vendor lock-in, high cost, no vector.
  • Drop Neo4j, use ClickHouse: Possible. Rejected for now β€” graph queries on 84K nodes are O(seconds), not O(minutes).

Consequences

  • Positive: Each DB does one job well. Optimized for its access pattern. Can scale independently.
  • Negative:
    • 5 things to back up, monitor, patch, version
    • New engineer onboarding: must learn 5 DBs
    • Cross-DB queries require application-level joins
    • 5 different query languages (SQL, Redis commands, SQL/CH, Cypher, REST)
  • Mitigations:
    • DataBus facade unifies access (app/databus/core.py)
    • Container memory limits set on all 5 DB containers
    • Each DB has a runbook in docs/runbooks/

Re-evaluation triggers

  • Neo4j license change (currently community edition, free)
  • Postgres + pgvector catching up to Qdrant perf (current gap: ~10Γ—)
  • ClickHouse memory pressure requiring Memgraph substitution