Skip to content

EdgeQuake Architecture Overview

Understanding the system design through first principles


┌─────────────────────────────────────────────────────────────────────────────────┐
│ EdgeQuake System │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ Client Layer ││
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ││
│ │ │ WebUI │ │ REST API │ │ Rust SDK │ ││
│ │ │ (Next.js) │ │ (HTTP/JSON) │ │ (Native) │ ││
│ │ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ ││
│ └───────────┼────────────────────┼────────────────────┼───────────────────────┘│
│ │ │ │ │
│ └────────────────────┼────────────────────┘ │
│ │ │
│ ┌────────────────────────────────▼────────────────────────────────────────────┐│
│ │ API Layer (Axum) ││
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ││
│ │ │ Routes │ │ Handlers │ │ Middleware │ │ OpenAPI │ ││
│ │ │ │ │ │ │ (Auth,Rate)│ │ (Docs) │ ││
│ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ ││
│ └────────────────────────────────┬────────────────────────────────────────────┘│
│ │ │
│ ┌────────────────────────────────▼────────────────────────────────────────────┐│
│ │ Core Orchestration Layer ││
│ │ ││
│ │ ┌───────────────────────────────────────────────────────────────────────┐ ││
│ │ │ EdgeQuake │ ││
│ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ ││
│ │ │ │ insert() │ │ query() │ │ delete() │ │ ││
│ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ ││
│ │ │ │ │ │ │ ││
│ │ │ ▼ ▼ ▼ │ ││
│ │ │ ┌──────────────────────────────────────────────────────────────────┐ │ ││
│ │ │ │ Processing Components │ │ ││
│ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ ││
│ │ │ │ │ Pipeline │ │ QueryEngine │ │ Tasks │ │ │ ││
│ │ │ │ │ (ingest) │ │ (6 modes) │ │ (async) │ │ │ ││
│ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ ││
│ │ │ └──────────────────────────────────────────────────────────────────┘ │ ││
│ │ └───────────────────────────────────────────────────────────────────────┘ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │ │
│ ┌─────────────────────────┼─────────────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ LLM Layer │ │ Storage Layer │ │ PDF Processor │ │
│ │ │ │ │ │ │ │
│ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │
│ │ │ Providers │ │ │ │ Traits │ │ │ │ Extractor │ │ │
│ │ │ ─────────── │ │ │ │ ─────────── │ │ │ │ ─────────── │ │ │
│ │ │ • OpenAI │ │ │ │ • KV │ │ │ │ • Text │ │ │
│ │ │ • Ollama │ │ │ │ • Vector │ │ │ │ • Tables │ │ │
│ │ │ • LM Studio │ │ │ │ • Graph │ │ │ │ • Layout │ │ │
│ │ │ • Mock │ │ │ │ │ │ │ │ │ │ │
│ │ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │ │
│ └─────────────────┘ └────────┬────────┘ └─────────────────┘ │
│ │ │
│ ┌─────────────┴─────────────┐ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Memory (Dev/Test) │ │ PostgreSQL (Prod) │ │
│ │ │ │ │ │
│ │ • Fast, ephemeral │ │ • pgvector (vectors)│ │
│ │ • No persistence │ │ • Apache AGE (graph)│ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘

FactorPython (LightRAG)Rust (EdgeQuake)Impact
Performance~100 docs/min~1000 docs/min10x throughput
Memory2-4GB typical200-400MB10x efficiency
ConcurrencyGIL limitedTrue asyncBetter scaling
Type SafetyRuntime errorsCompile-timeFewer prod bugs
DeploymentPython env + depsSingle binarySimpler ops

Single Responsibility Principle:

┌──────────────┐ Each crate does ONE thing well
│ API │◄─ HTTP handling
├──────────────┤
│ Core │◄─ Orchestration
├──────────────┤
│ Pipeline │◄─ Document processing
├──────────────┤
│ Query │◄─ Search and retrieval
├──────────────┤
│ Storage │◄─ Persistence abstraction
├──────────────┤
│ LLM │◄─ AI provider abstraction
├──────────────┤
│ PDF │◄─ Document extraction
├──────────────┤
│ Auth │◄─ Authentication
├──────────────┤
│ Audit │◄─ Compliance logging
├──────────────┤
│ Tasks │◄─ Background processing
├──────────────┤
│ Rate Limiter│◄─ Throttling
└──────────────┘

Benefits:

  1. Compile-time boundary enforcement — Can’t accidentally use internal types
  2. Parallel compilation — Each crate compiles independently
  3. Selective testing — Run tests for one crate only
  4. Clear dependency graph — Easy to understand data flow
  5. Swappable implementations — Change storage without touching query
// The CORE never knows about concrete implementations
pub struct EdgeQuake {
llm: Arc<dyn LLMProvider>, // Could be OpenAI, Ollama, or Mock
storage: Arc<dyn GraphStorage>, // Could be Memory or PostgreSQL
}

Advantages:

  • Production uses OpenAI, tests use Mock (zero code changes)
  • Add new providers without modifying core
  • Runtime provider switching (dev → prod)

┌────────────────┐
│ edgequake-api │ ← HTTP Server
│ (37,400 LOC) │
└───────┬────────┘
┌────────────────┐
│ edgequake-core │ ← Orchestration
│ (15,500 LOC) │
└───────┬────────┘
┌──────────────────────┼──────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│edgequake-pipeline │ edgequake-query │ │ edgequake-llm │
│ (10,500 LOC) │ │ (11,900 LOC) │ │ (8,500 LOC) │
└────────┬────────┘ └────────┬────────┘ └─────────────────┘
│ │ │
└──────────────────────┼──────────────────────┘
┌─────────────────┐
│edgequake-storage│ ← Persistence
│ (11,900 LOC) │
└─────────────────┘
Specialized Crates (Optional):
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ edgequake-pdf │ │ edgequake-auth │ │ edgequake-tasks │
│ (26,000 LOC) │ │ (2,900 LOC) │ │ (3,400 LOC) │
└─────────────────┘ └─────────────────┘ └─────────────────┘

CratePurposeKey TypesLOC
edgequake-coreCentral orchestrationEdgeQuake, EdgeQuakeConfig, InsertResult15,500
edgequake-pipelineDocument processingPipeline, Chunker, LLMExtractor10,500
edgequake-querySearch and retrievalQueryEngine, QueryMode, QueryContext11,900
edgequake-storagePersistence abstractionKVStorage, VectorStorage, GraphStorage11,900
edgequake-llmAI provider abstractionLLMProvider, EmbeddingProvider8,500
edgequake-apiHTTP REST APIServer, Router, handlers37,400
edgequake-pdfPDF extractionPdfExtractor, TableExtractor26,000
edgequake-authAuthenticationAuthMiddleware, JwtValidator2,900
edgequake-auditCompliance loggingAuditLog, AuditEvent580
edgequake-tasksBackground jobsTaskRunner, Task, TaskStatus3,400
edgequake-rate-limiterRequest throttlingRateLimiter, TenantQuota1,000

Total: ~130,000 lines of Rust


The EdgeQuake struct is a facade that coordinates all RAG operations:

// Simple interface hides complex internals
let eq = EdgeQuake::new(config)
.with_providers(llm, embedder)
.with_storage(kv, vector, graph)
.initialize()
.await?;
// User doesn't know about Pipeline, QueryEngine, etc.
let result = eq.insert("Document content").await?;
let response = eq.query("What is X?").await?;

Six different query strategies, selected at runtime:

┌─────────────────┐
│ QueryEngine │
└────────┬────────┘
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Naive │ │ Local │ │ Global │
│ (vector)│ │ (entity)│ │(commun.)│
└─────────┘ └─────────┘ └─────────┘
│ │ │
└───────────────┴───────────────┘
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Hybrid │ │ Mix │ │ Bypass │
│(L+G) │ │(weighted)│ │(no RAG) │
└─────────┘ └─────────┘ └─────────┘

Sequential processing with configurable stages:

┌─────────────────────────────────────────────────────────┐
│ Pipeline │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────┐ │
│ │ Chunk │──▶│ Extract │──▶│ Merge │──▶│ Store │ │
│ │ │ │ (LLM) │ │ (dedup) │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ └───────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ [config] [config] [config] [config] │
│ chunk_size batch_size threshold backend │
│ overlap timeout strategy namespace│
│ │
└─────────────────────────────────────────────────────────┘

Multiple backends behind unified traits:

┌─────────────────────────────────────────────────────────┐
│ Storage Traits │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ KVStorage │ │VectorStorage │ │ GraphStorage │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
└─────────┼────────────────┼────────────────┼─────────────┘
│ │ │
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
│ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐
│Memory │ │Postgres││Memory │ │pgvector││Memory │ │ AGE │
└───────┘ └───────┘ └───────┘ └───────┘ └───────┘ └───────┘

EdgeQuake supports multi-tenant isolation via tenant_id and workspace_id:

┌─────────────────────────────────────────────────────────┐
│ Request Flow │
│ │
│ Request ──▶ [Middleware] ──▶ [Handler] ──▶ [Storage] │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ Extract tenant Validate Filter by │
│ from header permissions namespace │
│ │
└─────────────────────────────────────────────────────────┘
Isolation enforced at storage layer:
- Tenant A cannot see Tenant B's documents
- Workspace 1 cannot see Workspace 2's entities


ComponentFileLines
EdgeQuake structedgequake-core/src/orchestrator.rs1-300
QueryMode enumedgequake-core/src/types/query.rs-
Pipeline structedgequake-pipeline/src/pipeline.rs1-100
Storage traitsedgequake-storage/src/traits/-
API routesedgequake-api/src/routes.rs-