Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Preface

In the rapidly evolving landscape of data systems, we often find ourselves gluing together disparate technologies to build a complete platform. We use Redis for caching, Neo4j for graphs, Qdrant or Pinecone for vectors, and Spark for analytics. This fragmentation leads to “Frankenstein” architectures—complex, fragile, and hard to maintain.

Samyama (Sanskrit for “Integration” or “Binding together”) was born from a desire to collapse this complexity.

Since its inception, Samyama has evolved from a high-performance research prototype into a production-ready ecosystem. To serve both the open-source community and the demanding needs of global industry, Samyama is now offered in two editions:

  • Community Edition (OSS): The feature-complete, high-performance core for developers and startups.
  • Enterprise Edition: Production-hardened with observability, disaster recovery, and advanced optimization for mission-critical workloads.

This book is the story of building Samyama-Graph, a modern, high-performance graph database written in Rust. It is not just a user manual; it is an architectural deep dive. We will peel back the layers to show you how it works—from the byte-level serialization in RocksDB to the lock-free concurrency of our MVCC engine, and up to the distributed consensus algorithms that keep it alive.

Why Rust?

When building a database in the 2020s, the choice of language is pivotal. We chose Rust not just for its hype, but for its promise: Fearless Concurrency.

A graph database is, by definition, a pointer-chasing engine. It demands random memory access patterns that are notoriously hard to optimize and easy to mess up (hello, segmentation faults!). Rust’s ownership model allowed us to implement complex memory management strategies—like Arena Allocation and localized reference counting—without the overhead of a Garbage Collector or the safety risks of C++.

Who is this book for?

  • System Architects who want to understand the internals of a modern database.
  • Rust Developers curious about real-world patterns for FFI, concurrency, and distributed systems.
  • Data Engineers looking for a unified solution for their graph and AI workloads.

Let’s begin the journey.

About the Project & Author

Samyama.ai: The Vision

Samyama Graph is sponsored and developed by Samyama.ai, a company dedicated to building the future of autonomous, hardware-accelerated knowledge systems. Our mission is to unify the fragmented data landscape of graphs, vectors, and optimization into a single “Mechanical Sympathy” engine.

For enterprise inquiries, partnerships, or support, visit our official website: https://samyama.ai


About the Author: Sandeep Kunkunuru

The architecture and implementation of Samyama Graph, as well as this technical guide, are led by Sandeep Kunkunuru.

Sandeep is a specialist in high-performance Rust systems, distributed consensus, and the application of metaheuristic optimization to large-scale graph data. He is the primary maintainer of the Samyama open-source core and the lead architect behind the Enterprise Hardware-Accelerated edition.

Connect with the Project & Author:

Getting Started with Samyama Graph

A step-by-step guide to install, connect, and explore Samyama Graph using the web visualizer at graph.samyama.cloud.

Demo Video

The demo covers: local Samyama Graph setup, connecting graph.samyama.cloud to a local instance, connecting to the hosted endpoint at api.samyama.dev, running Cypher queries, exploring graph visualizations, and using the Schema Explorer and Dashboard.


Option A — Local Setup (Run on Your Machine)

Step 1 — Install Rust

Open your terminal and run:

Mac / Linux

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Windows

  1. Go to https://rustup.rs
  2. Download and run rustup-init.exe
  3. Follow the installer

After installation, restart your terminal. Verify it worked:

rustc --version
cargo --version

Step 2 — Clone the Repository

git clone https://github.com/samyama-ai/samyama-graph
cd samyama-graph

Step 3 — Build the Engine

cargo build --release

When complete you will see:

Finished `release` profile [optimized] target(s) in Xs

Step 4 — Start the Engine

Mac / Linux

./target/release/samyama

Windows

.\target\release\samyama.exe

You will see:

HTTP server starting on port 8080
Server ready. Press Ctrl+C to stop.

The engine is now running on:

  • Port 8080 — HTTP API (for the visualizer)
  • Port 6379 — Redis protocol (for redis-cli)

Step 5 — Open the Visualizer

  1. Open the Chrome browser

  2. Go to graph.samyama.cloud

  3. Sign up with your email and password (free)

  4. In the connection box, type:

    http://localhost:8080
    
  5. Click Connect

You should see:

  • Status: healthy ✅
  • Version: 1.0.0
  • Nodes and Edges count

Note: If you see a Failed to fetch error, go to the Chrome address bar → click the lock icon → Site SettingsInsecure Content → set to Allow → refresh the page.


Option B — No Local Setup (Explore Instantly)

If you do not want to install anything:

  1. Go to graph.samyama.cloud

  2. Sign up with your email and password (free)

  3. In the connection box, type:

    https://api.samyama.dev
    
  4. Click Connect

You are immediately connected to a live Samyama instance with real data. No installation required.


Running Your First Query

  1. Click Query Console in the left sidebar.

  2. Type this query in the editor:

    MATCH (n) RETURN labels(n), count(n)
    
  3. Click Run (or press Ctrl+Enter).

You will see results in the Table tab showing all node types and their counts.

Switch to Graph View

  1. Click the Graph tab in the results area.
  2. You will see an interactive force-directed graph:
    • Hover over any node to see its properties.
    • Drag nodes to rearrange.
    • Scroll to zoom in or out.

More Queries to Try

-- See all relationships
MATCH ()-[r]->() RETURN type(r), count(r)

-- Browse nodes with their properties
MATCH (n) RETURN n LIMIT 25

-- Find connected nodes
MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 20

Schema Explorer

The Schema Explorer shows you the complete structure of your graph.

Click Schema Explorer in the left sidebar. You will see:

  • Total Nodes — total count across all labels
  • Total Edges — total count across all relationship types
  • Node Types — each label with its count
  • Edge Types — each relationship type with its count

This is useful for understanding what data is in your graph before writing queries.


Dashboard

The Dashboard auto-generates charts from your graph schema — no configuration needed.

Click Dashboard in the left sidebar. You will see panels including:

  • Total Nodes — big number card
  • Total Edges — big number card
  • Node Label Distribution — pie chart
  • Edge Type Distribution — pie chart
  • Top Labels by Count — bar chart
  • Graph Health — connected components, isolated nodes, average degree

Click Open in Console on any panel to see and edit the underlying Cypher query. Every chart is backed by a real Cypher query — you can modify and re-run them in the Query Console.


My Queries (Query History)

All queries you run are automatically saved.

Click My Queries in the left sidebar. You will see three tabs:

  • Recent — all queries grouped by date
  • Bookmarked — queries you starred
  • Frequent — queries you run most often

You can:

  • Click Run on any saved query to execute it again
  • Click the star icon to bookmark a query

Plan Visualizer

See how the query engine executes your query.

  1. Click Plan Visualizer in the left sidebar.
  2. Type a Cypher query.
  3. Click Explain to see the execution plan as a visual tree.
  4. Click Profile to see actual execution times per operator.

Common Issues

Failed to fetch on graph.samyama.cloud

Chrome → Lock Icon → Site Settings → Insecure Content → Allow

Port 8080 already in use

lsof -ti :8080 | xargs kill -9

Then restart Samyama.

Build takes too long

The first build normally takes 5–15 minutes on a typical laptop. Subsequent builds are much faster.

No data after connecting

Your graph is empty. Create a sample node:

CREATE (n:Person {name: 'Alice'}) RETURN n

Next Steps


That’s it — you’re up and running with Samyama Graph. Happy querying!

Knowledge Graph Catalog

Samyama ships with 8 pre-built knowledge graphs spanning biomedicine, public health, sports, and industrial operations — the 8 packaged snapshots cataloged below total ~8.7M nodes / ~30M edges of curated, open-license content. Each KG is available as a portable .sgsnap snapshot that loads in seconds, stored on S3 (s3://samyama-data/snapshots/) and GitHub Releases, and cataloged in the Supabase kg_registry table.

For the federated mega-benchmark workload — the 8 packaged KGs plus PubMed, OpenFDA FAERS, and OHDSI OMOP — the combined graph reaches ~138M nodes / 1.3B edges across 11 sources. See the Mega Benchmark for the full federated query suite.


Catalog Overview

graph TB
    subgraph "Biomedical Trifecta"
        PKG["🧬 Pathways KG<br/>119K nodes · 835K edges"]
        CTKG["💊 Clinical Trials KG<br/>7.8M nodes · 27M edges"]
        DIKG["💉 Drug Interactions KG<br/>245K nodes · 388K edges"]
    end

    subgraph "Public Health Trifecta"
        DSKG["🦠 Disease Surveillance KG<br/>217K nodes · 241K edges"]
        HDKG["📊 Health Determinants KG<br/>286K nodes · 286K edges"]
        HSKG["🏥 Health Systems KG<br/>20K nodes · 19K edges"]
    end

    subgraph "Sports"
        CKG["🏏 Cricket KG<br/>36K nodes · 1.4M edges"]
    end

    subgraph "Industrial"
        AOKG["🏭 AssetOps KG<br/>781 nodes · 955 edges"]
    end

    PKG -.->|"Gene · Protein"| DIKG
    DIKG -.->|"Drug · Intervention"| CTKG
    DSKG -.->|"Disease · Condition"| CTKG
    DSKG -.->|"Drug · AMR"| DIKG
    DSKG -.->|"Region"| HDKG
    DSKG -.->|"Region"| HSKG

    style CKG fill:#3b82f6,stroke:#333,color:#fff
    style PKG fill:#10b981,stroke:#333,color:#fff
    style CTKG fill:#8b5cf6,stroke:#333,color:#fff
    style DIKG fill:#ec4899,stroke:#333,color:#fff
    style AOKG fill:#f59e0b,stroke:#333,color:#fff
    style DSKG fill:#06b6d4,stroke:#333,color:#fff
    style HDKG fill:#84cc16,stroke:#333,color:#fff
    style HSKG fill:#f97316,stroke:#333,color:#fff
KGNodesEdgesLabelsEdge TypesSnapshotSourceStatus
Cricket KG36,6191,392,01761221 MBCricsheetLive
Pathways KG118,686834,785599 MBReactome, STRING, GOLive
Clinical Trials KG7,774,44626,973,9971525711 MBAACT, MeSH, RxNormLive
Drug Interactions KG245,000388,000898.1 MBDrugBank, SIDER, ChEMBL, DGIdb, OpenFDALive
AssetOps KG781955810< 1 MBSynthetic (AssetOpsBench)Live
Disease Surveillance KG216,553241,084655.7 MBWHO GHOLive
Health Determinants KG285,635285,628766.5 MBWorld Bank WDI, WHO Air Quality, WHO WASHLive
Health Systems KG19,66119,428320.5 MBWHO SPAR, WHO NHWALive

Cross-KG Federation

The biomedical trifecta (Pathways + Clinical Trials + Drug Interactions) enables queries spanning molecular biology, translational medicine, and pharmacogenomics. With PubMed: 74.3M nodes, 1.07B edges — 96/100 queries pass. BiomedQA benchmark: 98% accuracy with MCP tools.

The public health trifecta (Disease Surveillance + Health Determinants + Health Systems) enables queries from disease outbreaks to population vulnerability to health system capacity — 40/40 queries pass. Bridges to the biomedical trifecta via Country.iso_code, Drug.drugbank_id, and Gene.gene_name.

Together, the 6-KG federation spans molecular biology to population health in a single OpenCypher query. See Cross-KG Federation for details.


Cricket KG

21K international cricket matches from Cricsheet — ball-by-ball data spanning T20, ODI, and Test formats.

Cricket KG Demo

Click for full demo (1:56) — Dashboard, Cypher Queries, and Graph Simulation

Schema

graph LR
    Player -->|BATTED_IN| Match
    Player -->|BOWLED_IN| Match
    Player -->|DISMISSED| Player
    Player -->|FIELDED_DISMISSAL| Player
    Player -->|PLAYED_FOR| Team
    Player -->|PLAYER_OF_MATCH| Match
    Team -->|COMPETED_IN| Match
    Team -->|WON| Match
    Team -->|WON_TOSS| Match
    Match -->|HOSTED_AT| Venue
    Match -->|IN_SEASON| Season
    Match -->|PART_OF| Tournament

    style Player fill:#3b82f6,stroke:#333,color:#fff
    style Match fill:#8b5cf6,stroke:#333,color:#fff
    style Team fill:#ef4444,stroke:#333,color:#fff
    style Venue fill:#f59e0b,stroke:#333,color:#fff
    style Tournament fill:#10b981,stroke:#333,color:#fff
    style Season fill:#ec4899,stroke:#333,color:#fff
LabelCountKey Properties
Match21,324date, match_type, season, winner
Player12,933name
Tournament1,053name
Venue877name, city
Team383name
Season49name

Example Queries

-- Top 10 run scorers across all formats
MATCH (p:Player)-[b:BATTED_IN]->(m:Match)
RETURN p.name AS player, sum(b.runs) AS total_runs
ORDER BY total_runs DESC LIMIT 10

-- Bowler-batsman rivalries
MATCH (bowler:Player)-[d:DISMISSED]->(victim:Player)
RETURN bowler.name, victim.name, count(d) AS times
ORDER BY times DESC LIMIT 10

-- Venue-team affinity (home advantage)
MATCH (t:Team)-[:WON]->(m:Match)-[:HOSTED_AT]->(v:Venue)
WITH t, v, count(m) AS wins WHERE wins >= 5
RETURN t.name, v.name, wins ORDER BY wins DESC LIMIT 15

Repository: samyama-ai/cricket-kg Snapshot: kg-snapshots-v1 (cricket.sgsnap, 21 MB)


Pathways KG

Biological pathways knowledge graph combining 5 open-license data sources — Reactome, STRING, Gene Ontology, WikiPathways, and UniProt. Human-only (organism 9606).

Pathways KG Demo

Click for full demo (2:06) — Dashboard, Cypher Queries, and Graph Simulation

Schema

graph LR
    Protein -->|PARTICIPATES_IN| Pathway
    Protein -->|CATALYZES| Reaction
    Protein -->|COMPONENT_OF| Complex
    Protein -->|ANNOTATED_WITH| GOTerm
    Protein -->|INTERACTS_WITH| Protein
    Pathway -->|CHILD_OF| Pathway
    GOTerm -->|IS_A| GOTerm
    GOTerm -->|PART_OF| GOTerm
    GOTerm -->|REGULATES| GOTerm

    style Protein fill:#3b82f6,stroke:#333,color:#fff
    style Pathway fill:#10b981,stroke:#333,color:#fff
    style GOTerm fill:#8b5cf6,stroke:#333,color:#fff
    style Reaction fill:#f59e0b,stroke:#333,color:#fff
    style Complex fill:#ef4444,stroke:#333,color:#fff
LabelCountKey Properties
GOTerm51,897go_id, name, namespace, definition
Protein37,990uniprot_id, name, gene_name
Complex15,963reactome_id, name
Reaction9,988reactome_id, name
Pathway2,848reactome_id, name, source
Edge TypeCountDescription
ANNOTATED_WITH265,492Protein → GO term annotation
INTERACTS_WITH227,818Protein-protein interaction (STRING, score ≥ 700)
PARTICIPATES_IN140,153Protein → Pathway membership
CATALYZES121,365Protein → Reaction catalysis
IS_A58,799GO term hierarchy
COMPONENT_OF8,186Protein → Complex membership
PART_OF7,122GO term part-of relation
REGULATES2,986GO term regulation
CHILD_OF2,864Pathway hierarchy

Repository: samyama-ai/pathways-kg Snapshot: kg-snapshots-v3 (pathways.sgsnap, 9 MB)


Clinical Trials KG

575K+ clinical studies from ClinicalTrials.gov enriched with MeSH disease hierarchy, RxNorm drug normalization, ATC drug classification, OpenFDA adverse events, and PubMed publications.

Schema

graph LR
    ClinicalTrial -->|STUDIES| Condition
    ClinicalTrial -->|TESTS| Intervention
    ClinicalTrial -->|HAS_ARM| ArmGroup
    ClinicalTrial -->|MEASURES| Outcome
    ClinicalTrial -->|SPONSORED_BY| Sponsor
    ClinicalTrial -->|CONDUCTED_AT| Site
    ClinicalTrial -->|REPORTED| AdverseEvent
    ClinicalTrial -->|PUBLISHED_IN| Publication
    ArmGroup -->|USES| Intervention
    Intervention -->|CODED_AS_DRUG| Drug
    Condition -->|CODED_AS_MESH| MeSHDescriptor
    Drug -->|TARGETS| Protein
    Drug -->|CLASSIFIED_AS| DrugClass
    Drug -->|TREATS| Condition
    Gene -->|ENCODES| Protein
    Gene -->|ASSOCIATED_WITH| Condition
    MeSHDescriptor -->|BROADER_THAN| MeSHDescriptor

    style ClinicalTrial fill:#8b5cf6,stroke:#333,color:#fff
    style Condition fill:#ef4444,stroke:#333,color:#fff
    style Intervention fill:#3b82f6,stroke:#333,color:#fff
    style Drug fill:#10b981,stroke:#333,color:#fff
    style Protein fill:#f59e0b,stroke:#333,color:#fff
    style Gene fill:#ec4899,stroke:#333,color:#fff
    style MeSHDescriptor fill:#06b6d4,stroke:#333,color:#fff
    style Publication fill:#84cc16,stroke:#333,color:#fff
LabelKey PropertiesSource
ClinicalTrialnct_id, title, phase, overall_status, enrollmentClinicalTrials.gov
Conditionname, mesh_id, icd10_codeClinicalTrials.gov
Interventionname, type (DRUG/DEVICE/…), rxnorm_cuiClinicalTrials.gov
Drugrxnorm_cui, name, drugbank_idRxNorm
Proteinuniprot_id, name, functionUniProt
Genegene_id, symbol, nameLinked ontologies
MeSHDescriptordescriptor_id, name, tree_numbersMeSH (NLM)
Sponsorname, class (INDUSTRY/NIH/…)ClinicalTrials.gov
Sitefacility, city, country, latitude, longitudeClinicalTrials.gov
Publicationpmid, title, journal, doiPubMed
AdverseEventterm, organ_system, is_seriousOpenFDA
ArmGrouplabel, type (EXPERIMENTAL/…)ClinicalTrials.gov
Outcomemeasure, time_frame, typeClinicalTrials.gov
DrugClassatc_code, name, levelATC
LabTestloinc_code, nameLOINC

Repository: samyama-ai/clinicaltrials-kg (private) Snapshot: kg-snapshots-v1 (clinical-trials.sgsnap, 711 MB)


Drug Interactions KG

Drug-gene interactions, side effects, indications, bioactivities, and adverse events from 5 open pharmacology databases. Bridges to Pathways KG (via gene name) and Clinical Trials KG (via DrugBank ID).

Schema

graph LR
    Drug -->|INTERACTS_WITH_GENE| Gene
    Drug -->|HAS_SIDE_EFFECT| SideEffect
    Drug -->|HAS_INDICATION| Indication
    Drug -->|HAS_BIOACTIVITY| Bioactivity
    Drug -->|HAS_ADVERSE_EVENT| AdverseEvent
    Drug -->|CLASSIFIED_AS| DrugClass
    Bioactivity -->|BIOACTIVITY_TARGET| Target

    style Drug fill:#ec4899,stroke:#333,color:#fff
    style Gene fill:#3b82f6,stroke:#333,color:#fff
    style SideEffect fill:#ef4444,stroke:#333,color:#fff
    style Indication fill:#10b981,stroke:#333,color:#fff

Performance

  • Rust native loader: 245,000 nodes + 388,000 edges in 7.7s
  • Snapshot: 8.1 MB (druginteractions.sgsnap)
  • BiomedQA benchmark: 98% accuracy with MCP tools

Sources (5 of 6)

SourceLicenseContent
DrugBank CC0CC019,842 drug vocabulary + synonym mappings
DGIdbOpenDrug-gene interactions from 4,182 genes
SIDERCC-BY-SASide effects + indications
ChEMBLCC-BY-SA208K bioactivity records
OpenFDA FAERSPublic1.7K adverse event reports

Repository: samyama-ai/druginteractions-kg Rust loader: examples/druginteractions_loader.rs in samyama-graph Snapshot: druginteractions.sgsnap (8.1 MB)


Disease Surveillance KG

WHO Global Health Observatory data — disease case/death counts, vaccine coverage, and health indicators across 234 countries.

Schema

graph LR
    Country -->|IN_REGION| Region
    Country -->|REPORTED| DiseaseReport
    DiseaseReport -->|REPORT_OF| Disease
    Country -->|HAS_COVERAGE| VaccineCoverage
    Country -->|HAS_INDICATOR| HealthIndicator

    style Country fill:#06b6d4,stroke:#333,color:#fff
    style Region fill:#84cc16,stroke:#333,color:#fff
    style Disease fill:#ef4444,stroke:#333,color:#fff
    style DiseaseReport fill:#8b5cf6,stroke:#333,color:#fff
    style VaccineCoverage fill:#f59e0b,stroke:#333,color:#fff
    style HealthIndicator fill:#ec4899,stroke:#333,color:#fff
LabelCountSource
Country234WHO GHO
Region6WHO regions (AFR, AMR, SEAR, EUR, EMR, WPR)
Disease15Cholera, Malaria, TB, HIV, Meningitis, etc.
DiseaseReport~49KAnnual case/death counts per country per disease
VaccineCoverage~10KDTP3, MCV1, BCG, Polio3 coverage per country per year
HealthIndicator~164KLife expectancy, infant mortality, sanitation, water

Repository: samyama-ai/surveillance-kg Rust loader: examples/surveillance_loader.rs in samyama-graph Snapshot: surveillance.sgsnap (5.7 MB) Data source: WHO GHO OData API — 30 indicators across infectious diseases, vaccines, and health metrics


Health Determinants KG

Population vulnerability indicators from World Bank WDI, WHO Air Quality, and WHO Water/Sanitation — 80 curated indicators across 211 countries (1990–2024).

Schema

graph LR
    Country -->|IN_REGION| Region
    Country -->|HAS_INDICATOR| SocioeconomicIndicator
    Country -->|ENVIRONMENT_OF| EnvironmentalFactor
    Country -->|NUTRITION_STATUS| NutritionIndicator
    Country -->|DEMOGRAPHIC_OF| DemographicProfile
    Country -->|WATER_RESOURCE_OF| WaterResource

    style Country fill:#84cc16,stroke:#333,color:#fff
    style Region fill:#06b6d4,stroke:#333,color:#fff
    style SocioeconomicIndicator fill:#f59e0b,stroke:#333,color:#fff
    style EnvironmentalFactor fill:#ef4444,stroke:#333,color:#fff
    style NutritionIndicator fill:#10b981,stroke:#333,color:#fff
    style DemographicProfile fill:#8b5cf6,stroke:#333,color:#fff
    style WaterResource fill:#3b82f6,stroke:#333,color:#fff
CategoryNodesIndicatorsExamples
Countries211ISO 3166-1 alpha-3, income level, WB region
Regions7South Asia, Sub-Saharan Africa, etc.
Socioeconomic52,36716GDP, GNI, poverty, Gini, unemployment, literacy, health expenditure
Environmental35,66710 + PM2.5PM2.5 exposure, forest area, renewable energy, CO2
Nutrition14,07310Stunting, wasting, obesity, undernourishment, anemia
Demographic107,08815Population, fertility, life expectancy, infant mortality, urbanization
Water76,22210 + WASHDrinking water, sanitation, freshwater withdrawal, water stress

Performance

  • Rust native loader: 285,635 nodes + 285,628 edges in 2.4s
  • Snapshot: 6.5 MB (health-determinants.sgsnap)
  • Benchmark: 40/40 queries pass (median 15ms)

Sources

SourceLicenseContent
World Bank WDICC-BY 4.080 indicators, 211 countries, 1990–2024
WHO GHO Air QualityOpenPM2.5 annual mean (1,880 records)
WHO GHO WASHOpenWater/sanitation (47K records)

Repository: samyama-ai/health-determinants-kg Rust loader: examples/health_determinants_loader.rs in samyama-graph-enterprise Snapshot: health-determinants.sgsnap (6.5 MB)


Health Systems KG

Health system capacity — IHR emergency preparedness and health workforce density from WHO, across 233 countries.

Schema

graph LR
    EmergencyResponse -->|CAPACITY_FOR| Country
    HealthWorkforce -->|SERVES| Country

    style Country fill:#f97316,stroke:#333,color:#fff
    style EmergencyResponse fill:#ef4444,stroke:#333,color:#fff
    style HealthWorkforce fill:#3b82f6,stroke:#333,color:#fff
LabelCountSource
Country233WHO GHO
EmergencyResponse8,430WHO SPAR v2 — 15 IHR capacities per country per year
HealthWorkforce10,998WHO NHWA — physicians, nurses, dentists, pharmacists

Performance

  • Rust native loader: 19,661 nodes + 19,428 edges in 149ms
  • Snapshot: 0.5 MB (health-systems.sgsnap)
  • Benchmark: 40/40 queries pass (cross-KG with Health Determinants)

Sources

SourceLicenseContent
WHO SPAR v2Open15 IHR capacity scores, 233 countries
WHO NHWAOpenHealth workforce density per 10K population

Pending sources (loaders built, data not yet downloaded): GAVI vaccine supply, Global Fund disbursements, IHME health expenditure

Repository: samyama-ai/health-systems-kg Rust loader: examples/health_systems_loader.rs in samyama-graph-enterprise Snapshot: health-systems.sgsnap (0.5 MB)


AssetOps KG

Synthetic industrial operations graph from the AssetOpsBench benchmark. Models assets, sensors, maintenance schedules, and failure modes for industrial IoT.

LabelCountExamples
Asset~200Pumps, compressors, turbines
Sensor~150Temperature, vibration, pressure
WorkOrder~100Maintenance tasks
FailureMode~80Bearing failure, seal leak
Component~100Bearings, seals, impellers
Location~50Plants, areas, units
Operator~50Maintenance technicians
Schedule~50Maintenance windows

Repository: samyama-ai/assetops-kg (private)


Quick Start — Loading Any Snapshot

All snapshots follow the same load pattern:

# 1. Start Samyama Graph (v1.0.0+)
./target/release/samyama

# 2. Create a tenant
curl -X POST http://localhost:8080/api/tenants \
  -H 'Content-Type: application/json' \
  -d '{"id":"TENANT_ID","name":"TENANT_NAME"}'

# 3. Import snapshot into the tenant
curl -X POST http://localhost:8080/api/tenants/TENANT_ID/snapshot/import \
  -F "file=@snapshot.sgsnap"

# 4. Query
curl -X POST http://localhost:8080/api/query \
  -H 'Content-Type: application/json' \
  -d '{"query":"MATCH (n) RETURN labels(n), count(n)","graph":"TENANT_ID"}'

# 5. Explore in Insight
cd samyama-insight && npm run dev
# → http://localhost:5173 (select tenant from dropdown)
# → http://localhost:5173/simulation/TENANT_ID

Note: Use /api/tenants/:id/snapshot/import (tenant-specific endpoint), NOT /api/snapshot/import. The generic endpoint always loads into the default tenant.

Cross-KG Federation

When multiple knowledge graphs share entity types — the same proteins, drugs, or genes appear in different datasets — loading them into the same Samyama tenant creates a federated graph where a single Cypher query can traverse across data sources.

This chapter shows how to combine the Pathways KG and Clinical Trials KG into a single biomedical graph and answer questions that neither KG can answer alone.


Why Federation?

The Pathways KG knows molecular biology — which proteins interact, what pathways they participate in, which GO processes they’re annotated with. The Clinical Trials KG knows translational medicine — which drugs are in trials, what conditions they treat, what adverse events they cause.

Neither KG alone can answer:

“Which biological pathways are disrupted by drugs currently in Phase 3 trials for breast cancer?”

This query requires traversing:

ClinicalTrial (phase='Phase 3') → STUDIES → Condition (name contains 'breast cancer')
ClinicalTrial → TESTS → Intervention → CODED_AS_DRUG → Drug
Drug → TARGETS → Protein
Protein → PARTICIPATES_IN → Pathway

The first two hops live in the Clinical Trials KG. The last two hops live in the Pathways KG. The Drug → TARGETS → Protein edge is the bridge.

graph LR
    subgraph "Clinical Trials KG"
        CT["ClinicalTrial<br/>(Phase 3)"]
        COND["Condition<br/>(Breast Cancer)"]
        INT["Intervention"]
        DRUG_CT["Drug"]
    end

    subgraph "Bridge Entities"
        DRUG["Drug<br/>(drugbank_id)"]
        PROT["Protein<br/>(uniprot_id)"]
        GENE["Gene<br/>(gene_id)"]
    end

    subgraph "Pathways KG"
        PROT_PW["Protein"]
        PATHWAY["Pathway"]
        GOTERM["GOTerm"]
    end

    CT -->|STUDIES| COND
    CT -->|TESTS| INT
    INT -->|CODED_AS_DRUG| DRUG_CT
    DRUG_CT -.->|"same drugbank_id"| DRUG
    DRUG -->|TARGETS| PROT
    PROT -.->|"same uniprot_id"| PROT_PW
    GENE -->|ENCODES| PROT
    GENE -->|ASSOCIATED_WITH| COND
    PROT_PW -->|PARTICIPATES_IN| PATHWAY
    PROT_PW -->|ANNOTATED_WITH| GOTERM

    style CT fill:#8b5cf6,stroke:#333,color:#fff
    style COND fill:#ef4444,stroke:#333,color:#fff
    style INT fill:#3b82f6,stroke:#333,color:#fff
    style DRUG_CT fill:#10b981,stroke:#333,color:#fff
    style DRUG fill:#10b981,stroke:#333,color:#fff
    style PROT fill:#f59e0b,stroke:#333,color:#fff
    style GENE fill:#ec4899,stroke:#333,color:#fff
    style PROT_PW fill:#f59e0b,stroke:#333,color:#fff
    style PATHWAY fill:#10b981,stroke:#333,color:#fff
    style GOTERM fill:#8b5cf6,stroke:#333,color:#fff

Join Points

Three entity types appear in both KGs with matching identifiers:

EntityPathways KG PropertyClinical Trials KG PropertyJoin Key
ProteinProtein.uniprot_idProtein.uniprot_idUniProt accession (e.g., P04637)
DrugDrug.drugbank_idDrug.drugbank_idDrugBank ID (e.g., DB00072)
GeneGene.gene_idGene.gene_idNCBI Gene ID (e.g., 7157)

Loading Multiple Snapshots into One Tenant

Step 1: Start the server

./target/release/samyama

Step 2: Create a combined tenant

curl -X POST http://localhost:8080/api/tenants \
  -H 'Content-Type: application/json' \
  -d '{"id":"biomedical","name":"Biomedical (Pathways + Clinical Trials)"}'

Step 3: Load snapshots sequentially

Load the smaller snapshot first, then the larger one. Each import appends to the existing graph — nodes and edges accumulate.

# Pathways first (9 MB, ~119K nodes)
curl -X POST http://localhost:8080/api/tenants/biomedical/snapshot/import \
  -F "file=@pathways.sgsnap"
# Expected: 118,686 nodes, 834,785 edges

# Clinical Trials second (711 MB, ~7.7M nodes)
curl -X POST http://localhost:8080/api/tenants/biomedical/snapshot/import \
  -F "file=@clinical-trials.sgsnap"
# Expected: 7,711,965 nodes, 27,069,085 edges

Step 4: Verify the combined graph

curl -X POST http://localhost:8080/api/query \
  -H 'Content-Type: application/json' \
  -d '{"query":"MATCH (n) RETURN labels(n) AS label, count(n) AS count ORDER BY count DESC","graph":"biomedical"}'

You should see labels from both KGs:

LabelSourceExpected Count
ClinicalTrialClinical Trials~575,000
ConditionClinical Trialsvaries
InterventionClinical Trialsvaries
GOTermPathways51,897
ProteinBoth37,990 + Clinical Trials
DrugBothClinical Trials + Pathways
GeneBothClinical Trials + Pathways
ComplexPathways15,963
ReactionPathways9,988
PathwayPathways2,848
MeSHDescriptorClinical Trialsvaries

Important: Snapshot import creates new nodes — it does not merge on matching properties. This means a Protein like TP53 may exist as two separate nodes (one from each snapshot) with the same uniprot_id. Cross-KG queries must join on properties, not on node identity.


Cross-KG Federated Queries

Since nodes from different snapshots are not merged, cross-KG queries use property-based joins — matching on shared identifiers like uniprot_id or drugbank_id.

Query 1: Pathways disrupted by drugs in Phase 3 breast cancer trials

-- Find drugs in Phase 3 breast cancer trials
MATCH (ct:ClinicalTrial)-[:STUDIES]->(cond:Condition)
WHERE ct.phase = 'Phase 3'
  AND cond.name CONTAINS 'Breast'
WITH ct
MATCH (ct)-[:TESTS]->(int:Intervention)-[:CODED_AS_DRUG]->(drug:Drug)
WITH DISTINCT drug

-- Bridge to pathways via protein targets (property join)
MATCH (drug)-[:TARGETS]->(prot1:Protein)
MATCH (prot2:Protein)-[:PARTICIPATES_IN]->(pw:Pathway)
WHERE prot1.uniprot_id = prot2.uniprot_id

RETURN pw.name AS pathway,
       count(DISTINCT drug.name) AS drugs_targeting,
       collect(DISTINCT drug.name) AS drug_names
ORDER BY drugs_targeting DESC
LIMIT 15

Query 2: GO processes affected by trial drugs

-- Drugs being tested in active trials
MATCH (ct:ClinicalTrial)-[:TESTS]->(int:Intervention)-[:CODED_AS_DRUG]->(drug:Drug)
WHERE ct.overall_status = 'RECRUITING'
WITH DISTINCT drug

-- Bridge to GO annotations via protein targets
MATCH (drug)-[:TARGETS]->(prot1:Protein)
MATCH (prot2:Protein)-[:ANNOTATED_WITH]->(go:GOTerm)
WHERE prot1.uniprot_id = prot2.uniprot_id
  AND go.namespace = 'biological_process'

RETURN go.name AS biological_process,
       count(DISTINCT drug.name) AS drugs,
       count(DISTINCT prot2.name) AS proteins
ORDER BY drugs DESC
LIMIT 10

Query 3: PPI neighbors of clinical drug targets

-- Find proteins targeted by a specific drug
MATCH (drug:Drug {name: 'Trastuzumab'})-[:TARGETS]->(target:Protein)
WITH target

-- Find interaction partners in pathways PPI network
MATCH (pw_prot:Protein)-[:INTERACTS_WITH]-(partner:Protein)
WHERE pw_prot.uniprot_id = target.uniprot_id

RETURN target.name AS drug_target,
       partner.name AS ppi_neighbor,
       count(*) AS interaction_strength
ORDER BY interaction_strength DESC
LIMIT 20

Query 4: Disease ↔ Pathway connections through genes

-- Genes associated with a disease (from clinical trials KG)
MATCH (gene:Gene)-[:ASSOCIATED_WITH]->(cond:Condition)
WHERE cond.name CONTAINS 'Diabetes'
WITH gene

-- Gene's protein → pathways (from pathways KG)
MATCH (gene)-[:ENCODES]->(prot1:Protein)
MATCH (prot2:Protein)-[:PARTICIPATES_IN]->(pw:Pathway)
WHERE prot1.uniprot_id = prot2.uniprot_id

RETURN pw.name AS pathway,
       count(DISTINCT gene.symbol) AS genes,
       collect(DISTINCT gene.symbol) AS gene_list
ORDER BY genes DESC
LIMIT 10

Query 5: Adverse events linked to pathway disruption

-- Drugs with serious adverse events
MATCH (drug:Drug)<-[:CODED_AS_DRUG]-(int:Intervention)<-[:TESTS]-(ct:ClinicalTrial)
MATCH (ct)-[:REPORTED]->(ae:AdverseEvent)
WHERE ae.is_serious = true
WITH drug, count(DISTINCT ae.term) AS ae_count
WHERE ae_count >= 5

-- What pathways do these drugs target?
MATCH (drug)-[:TARGETS]->(prot1:Protein)
MATCH (prot2:Protein)-[:PARTICIPATES_IN]->(pw:Pathway)
WHERE prot1.uniprot_id = prot2.uniprot_id

RETURN drug.name AS drug,
       ae_count AS serious_adverse_events,
       collect(DISTINCT pw.name) AS targeted_pathways
ORDER BY ae_count DESC
LIMIT 10

Testing Instructions

Prerequisites

  • Samyama Graph Enterprise v1.0.0+ running on localhost:8080
  • Snapshots downloaded:
  • At least 8 GB free RAM (Clinical Trials KG is large)

Step-by-step test script

#!/bin/bash
# test_cross_kg_federation.sh
# Tests cross-KG federation between Pathways and Clinical Trials

set -e
API="http://localhost:8080"

echo "=== Step 1: Create biomedical tenant ==="
curl -s -X POST "$API/api/tenants" \
  -H 'Content-Type: application/json' \
  -d '{"id":"biomedical","name":"Biomedical Federation"}' | python3 -m json.tool

echo -e "\n=== Step 2: Load Pathways KG ==="
curl -s -X POST "$API/api/tenants/biomedical/snapshot/import" \
  -F "file=@pathways.sgsnap" | python3 -c "
import sys,json; d=json.load(sys.stdin)
print(f'  Pathways: {d[\"nodes_imported\"]:,} nodes, {d[\"edges_imported\"]:,} edges')"

echo -e "\n=== Step 3: Load Clinical Trials KG ==="
echo "  (This may take 1-2 minutes for the 711 MB snapshot)"
curl -s -X POST "$API/api/tenants/biomedical/snapshot/import" \
  -F "file=@clinical-trials.sgsnap" | python3 -c "
import sys,json; d=json.load(sys.stdin)
print(f'  Clinical Trials: {d[\"nodes_imported\"]:,} nodes, {d[\"edges_imported\"]:,} edges')"

echo -e "\n=== Step 4: Verify combined graph ==="
curl -s -X POST "$API/api/query" \
  -H 'Content-Type: application/json' \
  -d '{"query":"MATCH (n) RETURN labels(n) AS label, count(n) AS count ORDER BY count DESC","graph":"biomedical"}' | python3 -c "
import sys,json
for r in json.load(sys.stdin)['records']:
    print(f'  {r[0][0]:20s} {r[1]:>10,}')"

echo -e "\n=== Step 5: Check join points ==="

echo "  Proteins with uniprot_id (Pathways):"
curl -s -X POST "$API/api/query" \
  -H 'Content-Type: application/json' \
  -d '{"query":"MATCH (p:Protein) WHERE p.uniprot_id IS NOT NULL RETURN count(p) AS proteins_with_uid","graph":"biomedical"}' | python3 -c "
import sys,json; print(f'    {json.load(sys.stdin)[\"records\"][0][0]:,}')"

echo "  Drugs with drugbank_id:"
curl -s -X POST "$API/api/query" \
  -H 'Content-Type: application/json' \
  -d '{"query":"MATCH (d:Drug) WHERE d.drugbank_id IS NOT NULL RETURN count(d) AS drugs_with_dbid","graph":"biomedical"}' | python3 -c "
import sys,json; print(f'    {json.load(sys.stdin)[\"records\"][0][0]:,}')"

echo -e "\n=== Step 6: Cross-KG query — Pathways disrupted by Phase 3 breast cancer drugs ==="
curl -s -X POST "$API/api/query" \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "MATCH (ct:ClinicalTrial)-[:STUDIES]->(cond:Condition) WHERE ct.phase = '\"'\"'Phase 3'\"'\"' AND cond.name CONTAINS '\"'\"'Breast'\"'\"' WITH ct MATCH (ct)-[:TESTS]->(int:Intervention)-[:CODED_AS_DRUG]->(drug:Drug) WITH DISTINCT drug MATCH (drug)-[:TARGETS]->(prot1:Protein) MATCH (prot2:Protein)-[:PARTICIPATES_IN]->(pw:Pathway) WHERE prot1.uniprot_id = prot2.uniprot_id RETURN pw.name AS pathway, count(DISTINCT drug.name) AS drugs ORDER BY drugs DESC LIMIT 10",
    "graph": "biomedical"
  }' | python3 -c "
import sys,json
d=json.load(sys.stdin)
if 'error' in d:
    print(f'  Error: {d[\"error\"]}')
else:
    print(f'  Columns: {d[\"columns\"]}')
    for r in d.get('records',[])[:10]:
        print(f'    {r}')"

echo -e "\n=== Step 7: Simpler cross-KG validation — shared proteins ==="
curl -s -X POST "$API/api/query" \
  -H 'Content-Type: application/json' \
  -d '{"query":"MATCH (p1:Protein)-[:PARTICIPATES_IN]->(pw:Pathway) MATCH (p2:Protein)<-[:TARGETS]-(d:Drug) WHERE p1.uniprot_id = p2.uniprot_id RETURN count(DISTINCT p1.uniprot_id) AS shared_proteins, count(DISTINCT d.name) AS drugs, count(DISTINCT pw.name) AS pathways","graph":"biomedical"}' | python3 -c "
import sys,json
d=json.load(sys.stdin)
if 'error' in d:
    print(f'  Error: {d[\"error\"]}')
else:
    r=d['records'][0]; print(f'  Shared proteins: {r[0]}, Drugs: {r[1]}, Pathways: {r[2]}')"

echo -e "\n=== Done ==="

Expected results

If both snapshots loaded correctly:

  1. Label distribution should show labels from both KGs (Pathway, GOTerm, Protein from Pathways; ClinicalTrial, Condition, Intervention from Clinical Trials)
  2. Join points should show thousands of proteins with uniprot_id and hundreds of drugs with drugbank_id
  3. Cross-KG query should return pathways like “Signal Transduction”, “Immune System”, “Disease” that are targeted by Phase 3 breast cancer drugs
  4. Shared proteins count should be > 0, confirming the bridge works

Troubleshooting

IssueCauseFix
Import times outClinical Trials snapshot is 711 MBIncrease curl timeout: curl --max-time 600 ...
Out of memoryCombined graph needs ~8 GBUse Mac Mini (16 GB) or reduce to pathways-only
Cross-KG query returns 0 rowsProtein IDs don’t overlapVerify with simpler query: MATCH (p:Protein) WHERE p.uniprot_id = 'P04637' RETURN p
Property join slowNo index on uniprot_idCreate index: redis-cli GRAPH.QUERY biomedical "CREATE INDEX FOR (p:Protein) ON (p.uniprot_id)"

Architecture Notes

Why Property Joins (Not Node Merging)?

Snapshot import creates fresh nodes with auto-assigned IDs. Two Protein nodes from different snapshots with the same uniprot_id are distinct graph nodes. We join them via WHERE p1.uniprot_id = p2.uniprot_id.

Trade-offs:

ApproachProsCons
Property join (current)Simple, no ETL changes, snapshots stay independentSlower on large joins, duplicate nodes
ETL-time mergeFastest queries, single node per proteinRequires custom loader, order-dependent
Post-load MERGEClean graph, works with any snapshotsExpensive for millions of nodes

For production workloads, consider building a dedicated cross-KG ETL that uses MERGE on shared identifiers during loading. For exploration and prototyping, property joins work well.

Future: Native Cross-Tenant Queries

A future Samyama release may support cross-tenant query federation natively, allowing:

-- Hypothetical future syntax
MATCH (drug:Drug)-[:TARGETS]->(p:Protein)
  ON TENANT 'clinical'
MATCH (p2:Protein)-[:PARTICIPATES_IN]->(pw:Pathway)
  ON TENANT 'pathways'
WHERE p.uniprot_id = p2.uniprot_id
RETURN pw.name, drug.name

Until then, loading into a single tenant with property joins is the recommended approach.

Ontology & Standards Catalog

This catalog surveys 147 publicly available ontologies, knowledge graphs, and standards relevant to Samyama Graph’s knowledge graph ecosystem — organized by domain, ranked by relevance tier.

Source of truth: data/ontology_catalog.csv — machine-readable, importable into any tool or pipeline.


Relevance Tiers

TierMeaningCount
1 — CriticalDirectly maps to an active Samyama KG, evaluation workflow, or partner need67
2 — HighStrong alignment; likely needed within 6 months61
3 — ModerateUseful reference for broader evaluation scenario generation20

A. Public Health & Epidemiology (31)

Core ontologies for disease classification, surveillance, epidemiology, and LMIC health systems.

AbbrevNameMaintainerSizeLicenseTier
ICD-11International Classification of DiseasesWHO55K+ entitiesCC BY-ND 3.0 IGO1
MeSHMedical Subject HeadingsNLM/NIH29K descriptorsPublic domain1
SNOMED CTSystematized Nomenclature of MedicineSNOMED International350K+ conceptsAffiliate license1
GHOGlobal Health ObservatoryWHO2,300+ indicatorsOpen access1
DHSDemographic and Health SurveysUSAID/ICF400+ surveys, 90+ countriesOpen (registration)1
GBDGlobal Burden of DiseaseIHME369 diseases, 204 countriesIHME free license1
IDOInfectious Disease OntologyOBO Foundry~3K classesCC BY 4.02
OBIOntology for Biomedical InvestigationsOBO Foundry~4.5K classesCC BY 4.02
EPOEpidemiology OntologyCommunity (OBO)~500 classesCC BY 4.02
HL7 FHIRFast Healthcare Interoperability ResourcesHL7 International150+ resourcesCC0 1.02
IHRInternational Health RegulationsWHO196 partiesOpen standard2
GLASSGlobal AMR Surveillance SystemWHO127+ countriesOpen data1
WUENICNational Immunization Coverage EstimatesWHO/UNICEF196 countriesOpen data1
HPOHuman Phenotype OntologyMonarch Initiative18K+ termsCustom open2
NCItNCI ThesaurusNational Cancer Institute180K+ conceptsPublic domain1
PopHOPopulation Health OntologyUniv. of Victoria~1K classesOpen2
VOVaccine OntologyUniv. of Michigan~10K classesCC BY 3.02
APOLLO_SVApollo Structured VocabularyUniv. of Pittsburgh~700 classesCC BY 4.01
HSOHealth Surveillance OntologyData-Driven SurveillanceEmergingCC BY 4.01
TRANSPathogen Transmission OntologyUniv. of Maryland32 termsCC0 1.01
AROAntibiotic Resistance OntologyMcMaster Univ./CARD5K+ termsCC BY 4.01
SYMPSymptom OntologyUniv. of Maryland~900 termsCC0 1.01
NTDONeglected Tropical Disease OntologyUFPE Brazil20+ diseasesOpen1
OMOP CDMOHDSI Common Data ModelOHDSI10M+ conceptsApache 2.01
DHIS2District Health Information System 2Univ. of Oslo2.4B+ people servedBSD 3-Clause1
OpenMRSOpen Medical Record SystemOpenMRS community50K+ conceptsMPL 2.01
WHO DON eKGWHO Disease Outbreak News KGAcademic (2025)Decades of reportsOpen1
ECTOEnvironmental Exposures OntologyOBO Foundry/Monarch12K+ classesCC BY 4.01
3MMicro-Meso-Macro SDOH OntologyAcademic (JMIR)383 classesOpen1
FHIR SDOHHL7 FHIR SDOH ProfileHL7 InternationalProfile/guideHL7 license1
MHOMental Health OntologyAcademic consortiumIn developmentOpen2

B. Social Determinants & Environmental Health (14)

Ontologies mapping environmental exposures, social factors, and their health impacts.

AbbrevNameMaintainerSizeLicenseTier
WDIWorld Development IndicatorsWorld Bank1,600+ indicatorsCC BY 4.01
HDIHuman Development IndexUNDP191 countriesOpen access1
ENVOEnvironment OntologyOBO Foundry~7K classesCC BY 4.01
ExOExposure OntologyOBO Foundry~1K classesCC BY 4.01
AQDWHO Air Quality DatabaseWHO6,000+ citiesOpen access1
AQUASTATFAO Water ResourcesFAO200+ countriesOpen access1
SDoHOSocial Determinants of Health OntologyAcademic~500 classesOpen1
ChEBIChemical Entities of Biological InterestEMBL-EBI60K+ entitiesCC BY 4.02
TXPOToxicology OntologyOBO Foundry~2K classesCC BY 4.02
FoodOnFood OntologyOBO Foundry~30K classesCC BY 3.02
SDGIOSDG Interface OntologyOBO/UN~1.5K classesCC BY 4.02
UMEPUrban Environmental PredictorAcademicModularOpen source3
GEMS/WaterGlobal Water QualityUNEP4M+ entriesOpen access2
CTDComparative Toxicogenomics DatabaseNC State2.6M interactionsOpen2

C. Biomedical & Clinical (32)

Disease, drug, genomics, clinical, and anatomy ontologies plus major biomedical knowledge graphs.

AbbrevNameMaintainerSizeLicenseTier
GOGene OntologyGO Consortium47K+ termsCC BY 4.01
UMLSUnified Medical Language SystemNLM/NIH4.5M+ conceptsUMLS license1
DrugBankDrugBankOMx/Univ. Alberta15K+ drugsCC BY-NC 4.01
RxNormRxNormNLM/NIH115K+ conceptsUMLS license1
MONDOMondo Disease OntologyMonarch Initiative35K+ classesCC BY 4.02
DOIDHuman Disease OntologyUniv. Maryland~12K classesCC0 1.02
LOINCLab Observation IdentifiersRegenstrief Institute99K+ termsFree (registration)2
ATCAnatomical Therapeutic ChemicalWHO6,300+ codesWHO license2
HetionetHetionetHimmelstein/UPenn47K nodes, 2.25M edgesCC0 1.02
PrimeKGPrecision Medicine KGHarvard/Zitnik Lab129K nodes, 8M edgesCC BY-NC-SA 4.01
SPOKEUCSF Knowledge EngineUCSF27M nodes, 53M edgesAPI access2
PROProtein OntologyGeorgetown Univ.~40K classesCC BY 4.03
SOSequence OntologyOBO Foundry~2.5K termsCC BY-SA 4.03
FMAFoundational Model of AnatomyUniv. Washington83K+ classesCreative Commons3
UBERONMulti-Species Anatomy OntologyOBO Foundry16K+ classesCC BY 3.03
CLCell OntologyOBO Foundry~2.7K classesCC BY 4.03
CDISCClinical Data StandardsCDISC100+ domainsFree (membership)2
ORDOOrphanet Rare Disease OntologyINSERM10K+ diseasesCC BY 4.03
PATOPhenotype and Trait OntologyOBO Foundry~2.7K classesCC BY 3.03
DINTODrug-Drug Interaction OntologyUniv. Murcia~28K classesCC BY 3.01
PharmGKBPharmacogenomics KBStanford~700 drug labelsCC BY-SA 4.02
OMIMOnline Mendelian InheritanceJohns Hopkins~16.9K entriesAcademic free2
DisGeNETGene-Disease AssociationsIMIM Barcelona1.1M associationsCC BY-NC-SA 4.01
Open TargetsDrug Target PlatformEMBL-EBI/Sanger63K targetsApache 2.0/CC02
Monarch KGMonarch Initiative KGNIH700K nodes, 7M edgesCC BY 4.02
BiolinkBiolink ModelMonarch/NIH NCATS~300 classesCC0 1.01
CKGClinical Knowledge GraphNovo Nordisk/Copenhagen16M nodes, 220M relsMIT2
KEGGKyoto EncyclopediaKanehisa Labs560 pathwaysAcademic free2
SIDERSide Effect ResourceEMBL1.4K drugs, 5.9K SEsCC BY-NC-SA 4.01
BioKGAstraZeneca BioKGAstraZeneca~2M entitiesMIT2
EFOExperimental Factor OntologyEMBL-EBI~52K classesApache 2.02
KG-HubKnowledge Graph HubMonarch/LBNLMultiple KGsBSD-33

D. AI Safety, Ethics & Evaluation (24)

Risk taxonomies, regulatory frameworks, fairness definitions, and adversarial threat models.

AbbrevNameMaintainerSizeLicenseTier
AI RMFNIST AI Risk Management FrameworkNIST4 functions, 72 subcatsPublic domain1
EU AI ActEU AI Act Risk ClassificationEuropean Commission4 risk tiersEU regulation1
ISO 42001AI Management System StandardISO/IECClauses + Annex APaid standard2
ISO 23894AI Risk ManagementISO/IECProcess modelPaid standard2
IEEE 7000Ethical System Design StandardIEEE10 clausesIEEE license2
MLCommonsAILuminate Safety BenchmarkMLCommons12 hazard categoriesOpen1
MIT AIRRAI Risk RepositoryMIT FutureTech1,700+ risksOpen access1
OWASP AIAI Security & Privacy GuideOWASP10+ attack categoriesCC BY-SA 4.02
ATLASAdversarial Threat Landscape for AIMITRE12 tactics, 30+ techniquesOpen2
OECD.AIAI Policy ObservatoryOECD5 principlesOpen access2
PAIPartnership on AI FrameworkPAIThematic pillarsOpen access2
FairnessFairness-Aware ML TaxonomyAcademic20+ definitionsAcademic1
AIIDAI Incident DatabaseResponsible AI Collaborative3,000+ incidentsOpen access1
RAI-MMResponsible AI Maturity ModelVarious5 maturity levelsVarious3
ATRSAlgorithmic Transparency StandardAda Lovelace Institute20+ fieldsOpen3
AI BOMAI Bill of MaterialsNTIA/CISAMetadata fieldsPublic domain2
AI Atlas NexusIBM Graph-Native Risk OntologyIBM Research8+ taxonomiesApache 2.01
AIR 2024AI Risk Categorization DecodedAcademic (NeurIPS)314 risk categoriesOpen1
AILuminateMLCommons Safety BenchmarkMLCommons24K+ prompts/langOpen1
OECD AI ClassAI System ClassificationOECD5 dimensionsOpen access1
OWASP LLMTop 10 for LLM ApplicationsOWASP10 risk categoriesCC BY-SA 4.01
CSETAI Harm TaxonomyGeorgetown10 harm categoriesOpen1
FRIAFundamental Rights Impact AssessmentAcademic (EU)EmergingOpen2
FairlearnFairness Metrics ToolkitMicrosoft10+ metricsMIT1

E. Human Rights & Humanitarian (19)

Human rights instruments, humanitarian standards, GBV taxonomies, and crisis data.

AbbrevNameMaintainerSizeLicenseTier
UDHRUniversal Declaration of Human RightsUN30 articlesPublic domain1
ICCPRIntl Covenant on Civil & Political RightsUN OHCHR53 articlesPublic domain1
UNGPsUN Guiding Principles on Business & HRUN OHCHR31 principlesPublic domain1
HXLHumanitarian Exchange LanguageOCHA300+ hashtagsOpen standard1
ReliefWebOCHA ReliefWeb TaxonomyUN OCHA100+ termsOpen2
SphereSphere StandardsSphere Association4 sectors, 20+ standardsCC BY-NC-ND 4.02
IHL-OntoIntl Humanitarian Law OntologyAcademic~800 classesResearch2
PIMProtection Incident ClassificationUNHCR50+ incident typesOpen standard1
TF-GBVTech-Facilitated GBV TaxonomyHI/Tattle/Academic20+ categoriesVaries1
HSPHumanitarian Standards PartnershipCHS Alliance9 commitmentsCC BY-NC-ND 3.03
CVIClimate Vulnerability IndexND-GAIN192 countriesOpen access2
CPOConflict and Peace OntologyUCDP/PRIO2.5K+ conflictsOpen access2
OntoRightsHuman Rights OntologyAcademic~500 classesOpen1
UwaziHURIDOCS Documentation PlatformHURIDOCS10K+ templatesOpen source1
GBVIMSGBV Information Management SystemUNFPA/UNICEF/IRC6 GBV typesOpen standard1
OGBVOnline Gender-Based Violence OntologyAcademic~200 classesOpen2
CAREIndigenous Data Governance PrinciplesGIDA4 principlesOpen standard1
PROV-OProvenance OntologyW3CW3C RecommendationW3C License2
IASC GBVGBV Guidelines FrameworkIASCGuidelinesOpen2

F–J. Additional Domains

F. Agriculture & Food Security (8)

AbbrevNameTier
AGROVOCFAO Multilingual Agricultural Thesaurus (40K+ concepts, 40+ languages)1
COCGIAR Crop Ontology (5K+ traits, 30+ crops)2
POPlant Ontology (~2K classes)3
IPCFAO Food Security Classification (5 phases)1
LPOLivestock Product Ontology3
IKOIndigenous Knowledge Ontology (emerging)2
GACSGlobal Agricultural Concept Scheme (15K+ concepts)2
AgroPortalAgronomic Ontology Repository (150+ ontologies)2

G. Accessibility & Disability (6)

AbbrevNameTier
WCAG 2.2Web Content Accessibility Guidelines (78 success criteria)1
ICFWHO Classification of Functioning & Disability (1,454 categories)2
MFOEMEmotion Ontology (~800 classes)2
WAI-ARIAAccessible Rich Internet Applications (200+ roles)2
NCPNeurodiversity Cognitive Profile Frameworks (emerging)2
ISO 9999Assistive Technology Classification (11 classes)3

H. Education & Workforce (5)

AbbrevNameTier
ISCEDUNESCO Education Classification (9 levels)2
Open BadgesVerifiable Digital Credentials (open standard)3
DigComp 2.2Digital Literacy Framework (5 areas, 21 competences)2
O*NETOccupational Information Network (1,016 occupations)3
ESCOEuropean Skills & Competences (13.9K skills, 30 languages)3
AbbrevNameTier
ELIEuropean Legislation Identifier3
LKIFLegal Knowledge Interchange Format (~200 classes)3
GDBGlobal Data Barometer (109 countries, 80+ indicators)2
DPVW3C Data Privacy Vocabulary (800+ concepts)2
NIST PFNIST Privacy Framework (5 functions, 18 categories)2

J. Geospatial & Infrastructure (4)

AbbrevNameTier
GeoNamesGeographical Database (12M+ entries)2
ISO 3166Country Codes (249 countries)1
OSMOpenStreetMap (10B+ features)2
HealthsitesHealth Facility Locations (160K+ facilities)1

How These Connect to Samyama KGs

Currently Loaded (code-verified)

graph LR
    subgraph "Samyama KGs"
        PKG["Pathways KG"]
        CTKG["Clinical Trials KG"]
        DIKG["Drug Interactions KG"]
        DSKG["Surveillance KG"]
    end

    subgraph "Loaded via API/Download"
        GO["Gene Ontology<br/>go.json.gz + annotations"]
        Reactome["Reactome<br/>5 data files"]
        STRING["STRING v12<br/>PPI, score≥700"]
        UniProt["UniProt<br/>REST API, human reviewed"]
        WikiP["WikiPathways<br/>.gmt file"]
        MeSH["MeSH<br/>NLM API"]
        RxNorm["RxNorm<br/>rxnav.nlm.nih.gov API"]
        ATC["ATC<br/>from RxNorm properties"]
        OpenFDA["OpenFDA<br/>api.fda.gov"]
        PubMed["PubMed<br/>NCBI E-utilities"]
        DrugBank["DrugBank CC0<br/>vocabulary CSV"]
        DGIdb["DGIdb<br/>interactions TSV"]
        SIDER["SIDER<br/>MedDRA side effects"]
        GHO["WHO GHO<br/>OData API"]
    end

    GO -->|"47K terms"| PKG
    Reactome -->|"pathways"| PKG
    STRING -->|"PPI"| PKG
    UniProt -->|"proteins"| PKG
    WikiP -->|"pathways"| PKG
    MeSH -->|"conditions"| CTKG
    RxNorm -->|"drugs"| CTKG
    ATC -->|"drug classes"| CTKG
    OpenFDA -->|"adverse events"| CTKG
    PubMed -->|"publications"| CTKG
    DrugBank -->|"drug vocab"| DIKG
    DGIdb -->|"drug-gene"| DIKG
    SIDER -->|"side effects"| DIKG
    GHO -->|"indicators"| DSKG

    style PKG fill:#10b981,stroke:#333,color:#fff
    style CTKG fill:#8b5cf6,stroke:#333,color:#fff
    style DIKG fill:#ec4899,stroke:#333,color:#fff
    style DSKG fill:#06b6d4,stroke:#333,color:#fff

Logical Map (full vision including planned)

graph LR
    subgraph "Live KGs"
        PKG["Pathways KG<br/>119K nodes"]
        CTKG["Clinical Trials KG<br/>7.7M nodes"]
        DIKG["Drug Interactions KG<br/>245K nodes"]
        DSKG["Surveillance KG<br/>217K nodes"]
        HDKG["Health Determinants KG<br/>286K nodes"]
        HSKG["Health Systems KG<br/>20K nodes"]
    end

    subgraph "Loaded"
        GO["Gene Ontology"]
        Reactome["Reactome"]
        STRING["STRING"]
        UniProt["UniProt"]
        MeSH["MeSH"]
        RxNorm["RxNorm"]
        ATC["ATC"]
        DrugBank["DrugBank"]
        DGIdb["DGIdb"]
        SIDER["SIDER"]
        GHO["WHO GHO"]
    end

    subgraph "Planned Integrations"
        SNOMED["SNOMED CT"]
        ICD["ICD-11"]
        LOINC["LOINC"]
        UMLS["UMLS"]
        WDI["World Bank WDI"]
        AQUASTAT["FAO AQUASTAT"]
        GAVI["GAVI"]
        SPAR["WHO SPAR"]
    end

    GO --> PKG
    Reactome --> PKG
    STRING --> PKG
    UniProt --> PKG
    MeSH --> CTKG
    RxNorm --> CTKG
    ATC --> CTKG
    DrugBank --> DIKG
    DGIdb --> DIKG
    SIDER --> DIKG
    GHO --> DSKG

    SNOMED -.->|"planned"| CTKG
    ICD -.->|"planned"| DSKG
    LOINC -.->|"planned"| CTKG
    UMLS -.->|"planned"| CTKG
    WDI -.->|"planned"| HDKG
    AQUASTAT -.->|"planned"| HDKG
    GAVI -.->|"planned"| HSKG
    SPAR -.->|"planned"| HSKG

    DSKG -.->|"Region"| HDKG
    DSKG -.->|"Region"| HSKG
    DSKG -.->|"Disease"| CTKG
    DIKG -.->|"Gene"| PKG
    DIKG -.->|"Drug"| CTKG

    style PKG fill:#10b981,stroke:#333,color:#fff
    style CTKG fill:#8b5cf6,stroke:#333,color:#fff
    style DIKG fill:#ec4899,stroke:#333,color:#fff
    style DSKG fill:#06b6d4,stroke:#333,color:#fff
    style HDKG fill:#84cc16,stroke:#333,color:#fff,stroke-dasharray: 5 5
    style HSKG fill:#f97316,stroke:#333,color:#fff,stroke-dasharray: 5 5

Not Yet Loaded

OntologyWhere ReferencedStatus
SNOMED CTClinical Trials test schemaNo download or parser code
ICD-11Catalog descriptionNot downloaded; ICD-10 codes pass through from AACT but no enrichment
LOINCSchema has LabTest(loinc_code)No LOINC data loader
UMLSTest schema stringNo code at all
World Bank WDIHealth Determinants KG (planned)KG not yet built
FAO AQUASTATHealth Determinants KG (planned)KG not yet built
WHO SPARHealth Systems KG (planned)KG not yet built
GAVIHealth Systems KG (planned)KG not yet built

Data source: data/ontology_catalog.csv — 147 entries across 10 categories.

Real-world Use Cases

Samyama is not just a research project; it is designed to solve complex, real-world problems. We include several fully functional demos in the examples/ directory of the repository.

Here are three key scenarios where Samyama shines.

1. Banking: Fraud Detection

Source: examples/banking_demo.rs

Financial fraud often involves complex networks of transactions that traditional SQL databases struggle to uncover.

The Scenario: A money laundering ring moves illicit funds through a series of “mule” accounts to hide the origin, eventually depositing it back into a clean account. This creates a cycle.

The Solution: We model the data as:

  • Nodes: Account
  • Edges: TRANSFER (with properties amount, date)

The Query:

MATCH (a:Account)-[t1:TRANSFER]->(b:Account)-[t2:TRANSFER]->(c:Account)-[t3:TRANSFER]->(a)
WHERE t1.amount > 10000 
  AND t2.amount > 9000 
  AND t3.amount > 8000
RETURN a.id, b.id, c.id

This simple query instantly reveals circular transaction patterns that would require massive, slow JOINs in SQL.

2. Supply Chain: Dependency Analysis

Source: examples/supply_chain_demo.rs

Modern supply chains are fragile. Knowing “who supplies my supplier” is critical for risk management.

The Scenario: A factory produces a “Car”. It needs an “Engine”, which needs “Pistons”, which needs “Steel”. If a strike hits the Steel mill, how does it affect Car production?

The Solution: We use the Graph Algorithms module (specifically Breadth-First Search or custom traversal).

The Logic:

  1. Start at the “Steel Mill” node.
  2. Traverse all outgoing SUPPLIES edges recursively.
  3. Identify all downstream Factory nodes.
  4. Calculate the “Risk Score” based on the dependency depth.

Developer Tip: You can run this exact scenario locally: cargo run --example supply_chain_demo. It builds the graph, calculates risks, and outputs a JSON tree of cascading failures.

3. Knowledge Graph: Clinical Trials

Source: examples/clinical_trials_demo.rs + examples/knowledge_graph_demo.rs

Medical research is unstructured. Trials, drugs, and conditions are buried in text documents.

The Scenario: A researcher wants to find “Drugs used for Hypertension that have a mechanism similar to ACE inhibitors.”

The Solution (Graph RAG):

  1. Ingest: Load ClinicalTrials.gov data into Samyama.
  2. Embed: Use the “Auto-Embed” pipeline to turn the “Mechanism of Action” text into vectors.
  3. Query:
    • Vector Search: Find drugs with description similar to “ACE inhibitor”.
    • Graph Filter: MATCH (drug)-[:TREATS]->(c:Condition {name: 'Hypertension'}).

4. Smart Manufacturing: Production Optimization

Source: examples/smart_manufacturing_demo.rs

In a modern factory, thousands of variables must be balanced: machine speed, energy cost, and maintenance schedules.

The Solution: Samyama uses its built-in Jaya or GWO (Grey Wolf Optimizer) to adjust production rates across the graph. The objective is to maximize output while keeping total energy consumption below a specific threshold (the constraint).

5. Enterprise SOC: Threat Hunting

Source: examples/enterprise_soc_demo.rs

Security Operations Centers (SOC) deal with millions of events (logins, file access, network traffic).

The Solution: By modeling logs as a graph, security analysts can run Pathfinding algorithms to trace the “Lateral Movement” of an attacker.

  • Graph RAG: Use vector search to find “unusual login behavior” semantically similar to known attack patterns.

6. Healthcare: Resource Allocation

Source: examples/clinical_trials_demo.rs (Resource management variant)

Hospitals must constantly balance budget constraints with patient wait times across departments like ER, ICU, and Surgery.

The Solution: Samyama models each department as a node with properties for current staffing (Doctors, Nurses) and equipment (Beds).

  • Optimization: Using the Jaya algorithm, Samyama calculates the optimal distribution of 1,000+ staff members across the entire hospital network.
  • The Result: Minimize “Total Weighted Wait Time” while ensuring no department falls below “Minimum Staffing” regulations.

7. Social Network Analysis

Source: examples/social_network_demo.rs

Model and analyze social graphs with community detection, influence propagation, and friend-of-friend recommendations. Demonstrates how PageRank and CDLP algorithms identify key influencers and natural communities within large networks.

8. PCA & Dimensionality Reduction

Source: examples/pca_demo.rs

Demonstrates Principal Component Analysis on node feature vectors. Reduces high-dimensional property data (e.g., user profiles with 10+ numeric attributes) down to 2-3 principal components for visualization and clustering. Showcases both the Randomized SVD and Power Iteration solvers.

The Interactive Experience: run_all_examples.sh

To make these use cases accessible, Samyama includes a comprehensive, menu-driven script: scripts/run_all_examples.sh. This script allows users to:

  1. Build the entire engine and its dependencies.
  2. Start the Samyama server with a single keystroke.
  3. Run any of the embedded Rust demos (Banking, Supply Chain, etc.).
  4. Execute the new Python Client Demo (examples/simple_client_demo.py), which showcases the high-performance Python bindings over the RESP protocol.

This interactive tool, combined with our Graph Visualizer (scripts/visualize.py), allows developers to see the graph structure and optimization results in real-time, bridging the gap between abstract algorithms and concrete business value.

Mega Benchmark: 500 Queries Across 11 Knowledge Graphs

500 queries. 11 knowledge graphs. 138 million nodes. 1.22 billion edges. One graph, one query language, one server.

Samyama Graph Enterprise v1.0.0 runs the full 500-query mega benchmark across eleven independently-sourced knowledge graphs loaded into a single federated graph — on a single commodity EC2 spot instance.

Headline

500 / 500 pass (100%)468 full-pass + 32 data_dependent zero-row matches whose corpus-gap reasons are recorded in the oracle (NCT bridge absent, drug-name casing, no Depression cohort in the OMOP slice, etc.). 0 errors. 0 unexplained empties.

  • Total runtime 78 min; query runtime 28 min; load ~50 min
  • Six prefixes hit 100% including all three cross-KG categories (XK, PH, MB)

Reproduction caveat: this result was obtained by importing per-KG .sgsnap files via the binary’s startup load path. The HTTP /api/snapshot/import endpoint is capped at 2 GB and cannot ingest pubmed-v2.sgsnap (11 GB) or trifecta-pubmed.sgsnap (12 GB). Reproducing via the HTTP path requires the body-limit fix tracked in samyama-graph.

The Dataset

Knowledge GraphSourceNodesEdgesKey Entities
PubMed/MEDLINENLM66.2M1.04BArticle, Author, MeSHTerm, Chemical, Journal, Grant
Clinical TrialsAACT/ClinicalTrials.gov7.8M27MClinicalTrial, Intervention, AdverseEvent, Site, Sponsor
PathwaysReactome119K835KProtein, Pathway, Complex, Reaction, GOTerm
Drug InteractionsDrugBank, ChEMBL, SIDER, DGIdb245K388KDrug, Gene, SideEffect, Indication, Bioactivity
FAERSFDA Adverse Events10.4M90MAdverseEventCase, Reaction, Drug, Outcome
UniProtEBI618K3.9MProtein, Organism, GOTerm
OMOPMIMIC-IV (115K patients)51.9M54MPerson, Visit, ConditionOccurrence, DrugExposure, Measurement
SurveillanceWHO SPAR217K241KCountry, CapacityIndicator
Health DeterminantsWorld Bank + WHO286K286KCountry, SocioeconomicIndicator, EnvironmentalFactor
Health SystemsWHO20K19KCountry, HealthWorkforce, VaccineCoverage
NCT BridgeAACT study_references747KREFERENCED_IN (Article → ClinicalTrial)
Total137.7M1.22B

How the engine clears the workload

Three execution patterns carry the bulk of the 500 queries:

  • Adjacency-aware aggregation (ADR-017)count(neighbor) over a degree-bounded match set walks per-node adjacency lists rather than scanning every edge. Without this, top-N degree queries time out on PubMed-scale data.
  • Streaming WITH … LIMITWithBarrier stops scanning upstream after N rows when no ORDER BY / WHERE / DISTINCT follows. Pipeline stages no longer materialize their full input when the next stage only needs a few rows.
  • Cypher three-valued logicIS NOT NULL AND <bool> short-circuits per spec; chained WHERE clauses AND-combine cleanly. The query author can write what they mean without the engine silently dropping predicates.

Together these shift the bottleneck from engine correctness to corpus coverage. The expected_rows.yaml oracle records each data_dependent empty with a specific corpus reason — so the remaining work is loader, not engine.

What data_dependent covers (32 queries)

These return zero rows but are expected to — the dataset, not the engine, is the constraint:

ClassCountExamples
Drug-name casing7FAERS uses 'ASPIRIN', DrugBank uses 'Aspirin' — pre-rewrite queries assume one form
Loader coverage gaps14:CODED_AS_DRUG, WaterResource, Bioactivity, HealthWorkforce, SPAR C01 not yet emitted
Cohort gaps in slices~6OMOP slice has no Depression cohort; some MIMIC-IV strata absent in the 115K-patient slice
NCT bridge absences~5Articles without REFERENCED_IN edges to ClinicalTrials in the AACT study_references snapshot

Infrastructure

Instancer7i.16xlarge (64 vCPU, 495 GB RAM)
RegionAWS ap-south-1 (Mumbai), spot pricing
Disk500 GB gp3
Peak memory~299 GB (60% utilization)
Load time~50 min (11 snapshots + NCT bridge + indexes via startup-load path)
Query runtime28 min
Total runtime78 min
BuildSamyama Graph Enterprise v1.0

Reproducing

# On r7i.16xlarge ap-south-1, AMI ami-0d219aaceb19e2c84
./target/release/examples/unified_benchmark \
  --pubmed-snap ~/snapshots/pubmed-v2.sgsnap \
  --ct-snap ~/snapshots/clinical-trials.sgsnap \
  --pw-snap ~/snapshots/pathways.sgsnap \
  --faers-snap ~/snapshots/faers-full.sgsnap \
  --uniprot-snap ~/snapshots/uniprot.sgsnap \
  --omop-snap ~/snapshots/omop-115k.sgsnap \
  --di-snap ~/snapshots/druginteractions.sgsnap \
  --surv-snap ~/snapshots/surveillance.sgsnap \
  --hd-snap ~/snapshots/health-determinants.sgsnap \
  --hs-snap ~/snapshots/health-systems.sgsnap \
  --study-refs ~/study_references.txt \
  --queries ~/benchmark-queries

Snapshots are public at s3://samyama-data/snapshots/. Query CSVs and the raw run output live in this repo under src/data/benchmark/ (benchmark-v100-results.csv).

Hero Run — 187.5M nodes, 1.29B edges, 99% pass (2026-04-30)

Two weeks after the 500/500 mega-benchmark, we ran a larger sweep: a 1000-query corpus against a 187.5M-node / 1.29B-edge graph stitched from the same 11 KGs at full scale (PubMed at 100%, FAERS at full extract, OMOP via Synthea-generated synthetic patients).

Nodes187.5M
Edges1.29B
Queries1000-query corpus
Pass rate99%
InstanceAWS r7i-class spot, ap-south-1
Total cost~$1.85
BuildSamyama Graph Enterprise v1.0 (pre-merge, hero branch)

Two engine fixes landed during the run (2026-05-01) and are now in main:

  • String-fn NULL-property handling (a small surfaced gap in 3VL coverage).
  • Snapshot multi-label index rebuild after import (closed a latent bug when bridge-loading multiple snapshots into one tenant).

The hero run also produced our first cross-KG entity dedup in production — ChEMBL ↔ UniProt joined on the accession property via ADR-019’s import_tenant_with_dedup path.

The hero run is the workload that validates the v1.0 architectural decisions at the scale we care about. The 500-query mega benchmark is the correctness floor (must hit 100% on a curated set); the 1000-query hero run is the stress ceiling (pass rate under real-world noise on a >1B-edge graph).

Biomedical Knowledge Graph Benchmark

100 queries. 4 knowledge graphs. 74 million nodes. 1 billion edges. One query language.

Samyama’s biomedical benchmark demonstrates real-world cross-knowledge-graph queries across the largest open biomedical dataset we know of — unified in a single queryable graph on commodity hardware.

The 100-query workload below is the four-KG biomedical subset. The Mega Benchmark extends it to 500 queries across 11 KGs (adding FAERS, OMOP, UniProt, and the public-health trifecta), with 500/500 passing on the current engine.

The Dataset

Knowledge GraphSourceNodesEdgesKey Entities
PubMed/MEDLINENLM66.2M1.04BArticle, Author, MeSHTerm, Chemical, Journal, Grant
Clinical TrialsAACT/ClinicalTrials.gov7.8M27MClinicalTrial, Intervention, AdverseEvent, Site, Outcome, Sponsor, Condition, Drug
PathwaysReactome119K835KProtein, Pathway, Complex, Reaction, GOTerm
Drug InteractionsDrugBank + ChEMBL + SIDER + DGIdb245K388KDrug, Gene, SideEffect, Indication, AdverseEvent, Bioactivity
NCT BridgeAACT study_references1M+REFERENCED_IN (Article → ClinicalTrial)
Total74.3M1.07B

Results Summary

100 queries executed. 96 returned data. 3 returned empty (specific data not in snapshot). 1 timed out.

CategoryQueriesPassEmptyError
PubMed353311
Clinical Trials201910
Pathways151500
Drug Interactions151410
Cross-KG151500
Total1009631

Infrastructure

  • Instance: r6a.8xlarge (32 vCPU, 256 GB RAM, AMD EPYC)
  • Cost: ~$2.50 (AWS spot, ap-south-1)
  • Import time: 31 minutes from v2 snapshots
  • NCT bridge: 1,018,483 REFERENCED_IN edges created in 109 seconds
  • Index creation: 10 indexes in ~320 seconds

PubMed Queries (35)

Point Lookups

IDQueryTimeRowsResult
PM01Article PMID=1234567819.6s1“Denpasar Declaration on Population and Development” (1994)
PM02Article PMID=250000001.3s1“How to measure technology assessment: an introduction”
PM03Article PMID=350000001.3s1“Hypusinated EIF5A as a feasible drug target…” (2022)
PM04Article PMID=1 (oldest)1.3s1“Formate assay in body fluids: application in methanol poisoning”

1-Hop Traversals

IDQueryTimeRowsResult
PM06Article → Authors13.3s1Arie Hasman
PM07Article → MeSH terms2.4s6Attitude of Health Personnel, Consumer Behavior, Health Information Systems, Medical Informatics, Technology Assessment
PM09Article → Journal1.3s1Studies in health technology and informatics
PM11Author → Articles (reverse)1.3s10Arie Hasman’s publications
PM12MeSH → Articles2.0s10Articles annotated with “Neoplasms”
PM13Chemical → Articles1.4s10Articles mentioning “Aspirin”
PM14Journal → Articles1.4s10Articles in “Nature”
PM17Articles citing a specific article1.3s1Citation found

Multi-Hop Analytics

IDQueryTimeRowsTop Result
PM15Co-authors of an article1.3s10Co-author network for PMID 25000000
PM19MeSH co-occurrence (Neoplasms)17.5s10Humans (513,845), Female (138,966), Animals (127,482)
PM20MeSH co-occurrence (Diabetes)6.2s10Humans (139,986)
PM21Chemical co-occurrence (Aspirin)2.3s10Platelet Aggregation Inhibitors (12,722)
PM22Author collaboration network1.3s10Jan Talmon (10 co-authored papers)

Aggregations

IDQueryTimeRowsTop Result
PM23Top authors (Smith*)32.1s10Smith Giri (233 papers)
PM24Most cited articles42.7s10PMID 20000334 (461 citations)
PM25ML publication trend8.4s182020: 4,974 papers
PM26Top cancer journals5.3s10Cancer (6,059 articles)
PM27Cancer funding agencies3.9s10NCI NIH HHS (46,137 papers)
PM29Diabetes funding agencies8.7s10NIDDK NIH HHS (5,123 papers)
PM30Most published journals6.0s10Nature (140,152 articles)
PM31Chemical mentions in Nature2.3s10DNA (3,726 mentions)
PM32MeSH terms for NCI articles63.7s10Humans (438,053)
PM35ML prolific authors5.4s10Wei Wang (149 papers)

Clinical Trials Queries (20)

Sample Queries

IDQueryTimeRowsResult
CT01Trial interventions2.2s10NCT05524376 → no intervention, NCT03092076 → Ticagrelor
CT02Trial adverse events1.6s10NCT02028182 → Pruritus, NCT03790111 → Nausea
CT03Trial sites1.6s10Switzerland, Canada, China, Denmark
CT05Trial sponsors1.6s10Sun Yat-Sen Memorial Hospital
CT06Trial conditions1.6s10Sepsis

Aggregations

IDQueryTimeRowsTop Result
CT08Trials per country15.0s15United States (190,879 trials)
CT09Most common interventions10.1s15Placebo (41,155 trials)
CT10Most common adverse events16.3s15Headache (28,130 trials)
CT11Most studied conditions8.2s15Healthy (10,898 trials)
CT12Top sponsors7.1s10Assiut University (4,547 trials)

Complex Queries

IDQueryTimeRowsTop Result
CT13Cancer trial interventions159s10Placebo (1,597)
CT14Diabetes trial adverse events150s10Headache (970)
CT16Condition → Intervention → AE chain120s10Hypertension → Placebo → Headache (116)
CT17Cancer trial sponsors163s10National Cancer Institute (1,320)
CT20Multi-arm trials with AE142s10NCT01682876 (4 arms) → Nausea

Pathways Queries (15)

IDQueryTimeRowsTop Result
PW01Protein interactions9.7s10IGKV2D-28 → IGHV3-11, IL17A
PW03Insulin pathways1.4s9Insulin effects on Xylulose-5-Phosphate synthesis
PW04Protein lookup (TP53)1.2s1TP53 found
PW05Largest pathways1.8s10Signal Transduction (2,614 proteins), Disease (2,575), Immune System (2,330)
PW06Most connected proteins1.7s10TP53 (571 interactions) — the “guardian of the genome”
PW08GO term annotations1.4s10IGKV2D-28 → adaptive immune response
PW11Pathway hierarchy1.4s102-LTR circle formation → Integration of provirus
PW14Immune system proteins1.3s20Full list
PW15Protein interaction depth 21.3s102-hop interaction network from IGKV2D-28

Drug Interactions Queries (15)

IDQueryTimeRowsTop Result
DI01Drug side effects1.3s10Bivalirudin → Abdominal pain, Anaemia
DI02Drug-gene interactions1.3s10Cetuximab → gene targets
DI03Drug indications1.3s10Bivalirudin → Haemorrhage
DI04Drug adverse events1.3s10Cetuximab → adverse events
DI06Drugs with most side effects1.4s10Pregabalin (839 side effects)
DI07Most common side effects1.5s10Nausea (985 drugs)
DI08Drugs sharing gene targets1.3s10Cetuximab ↔ Erythropoietin (shared gene)
DI09Drugs for diabetes1.4s10Desmopressin → Diabetes insipidus
DI13Drug indications + side effects103s10Bivalirudin: Haemorrhage (indication) + Abdominal pain (side effect)

Cross-Knowledge-Graph Queries (15)

These traverse REFERENCED_IN edges connecting 747,505 PubMed articles to clinical trials via PMID↔NCT ID mapping from AACT study_references.

The Headline Results

-- XK02: What drugs are tested in cancer research trials?
-- Spans: MeSH → Article → ClinicalTrial → Intervention (3 KGs)
MATCH (m:MeSHTerm)<-[:ANNOTATED_WITH]-(a:Article)
      -[:REFERENCED_IN]->(t:ClinicalTrial)-[:TESTS]->(i:Intervention)
WHERE m.name = 'Neoplasms'
RETURN i.name, count(DISTINCT t) AS trials ORDER BY trials DESC LIMIT 10
InterventionTrials
Placebo521
Pembrolizumab137
Carboplatin106
Paclitaxel106
Cyclophosphamide98

Time: 5.2s — Pembrolizumab (Keytruda) is the most-tested non-placebo cancer drug.


-- XK03: What drugs are tested in diabetes research trials?
MATCH (m:MeSHTerm)<-[:ANNOTATED_WITH]-(a:Article)
      -[:REFERENCED_IN]->(t:ClinicalTrial)-[:TESTS]->(i:Intervention)
WHERE m.name = 'Diabetes Mellitus'
RETURN i.name, count(DISTINCT t) AS trials ORDER BY trials DESC LIMIT 10
InterventionTrials
Placebo324
Metformin70
Usual care50
Insulin25
Exercise23

Time: 2.4s


-- XK04: What adverse events appear in heart disease trials?
MATCH (m:MeSHTerm)<-[:ANNOTATED_WITH]-(a:Article)
      -[:REFERENCED_IN]->(t:ClinicalTrial)-[:REPORTED]->(ae:AdverseEvent)
WHERE m.name = 'Heart Diseases'
RETURN ae.term, count(DISTINCT t) AS trials ORDER BY trials DESC LIMIT 10
Adverse EventTrials
Headache60
Nausea56
Syncope51
Pneumonia49

Time: 2.0s


-- XK06: What adverse events appear in Metformin-linked trials?
-- Spans: Chemical → Article → ClinicalTrial → AdverseEvent (4 entities)
MATCH (c:Chemical)<-[:MENTIONS_CHEMICAL]-(a:Article)
      -[:REFERENCED_IN]->(t:ClinicalTrial)-[:REPORTED]->(ae:AdverseEvent)
WHERE c.name = 'Metformin'
RETURN ae.term, count(DISTINCT t) AS trials ORDER BY trials DESC LIMIT 10
Adverse EventTrials
Headache215
Nausea207
Nasopharyngitis186
Diarrhoea185

Time: 2.1s — Diarrhoea is a known Metformin side effect, confirmed across PubMed + ClinicalTrials.gov.


All Cross-KG Results

IDQueryTimeRowsTop Result
XK01Article → Trial links39.8s10PMID 1 → NCT03260829
XK02Cancer → Trial interventions5.2s10Pembrolizumab (137 trials)
XK03Diabetes → Trial interventions2.4s10Metformin (70 trials)
XK04Heart disease → Trial AE2.0s10Headache (60 trials)
XK05Aspirin → Trials1.5s10NCT00000491 “Aspirin MI study”
XK06Metformin → Trial AE2.1s10Headache (215), Diarrhoea (185)
XK07Cancer trial sites3.8s10US (4,062), China (1,170), France (827)
XK08NCI-funded → Interventions19.4s10Placebo (933), Lab biomarker (614), Cyclophosphamide (517)
XK09NCT-linked count98.6s1747,505 articles linked to trials
XK11HIV → Trial sites11.6s10US (2,384)
XK12Alzheimer → Interventions2.4s10Placebo (345)
XK13NHLBI-funded → Trial AE18.3s10Headache (643)
XK14Paclitaxel → Trial sponsors1.9s10NCI (64 trials)
XK15Breast cancer → Outcomes4.0s16,591 outcome measures

What These Results Mean

  1. Pembrolizumab dominates cancer trials — The immunotherapy revolution is visible in the data. Across all PubMed articles annotated with “Neoplasms” that link to clinical trials, Keytruda appears in 137 trials, more than any classic chemotherapy agent.

  2. Metformin’s GI side effects confirmed cross-database — Diarrhoea ranks 4th in Metformin-linked trial adverse events (185 trials), consistent with clinical knowledge. This was found by traversing Chemical → Article → Trial → AdverseEvent — four entities across two databases.

  3. The US conducts 45% of global clinical trials — 190,879 of ~420K total trials. China is second at 1,170 cancer-specific trials.

  4. Nature has 140,152 articles in PubMed — making it the most-indexed journal. DNA is its most-mentioned chemical (3,726 articles).

  5. TP53 is the most connected protein — 571 interaction partners in Reactome, confirming its role as the “guardian of the genome.”

  6. NCI NIH funds 46,137 cancer research papers — and those papers link to 933 placebo-controlled trials.

Query Files

The full query catalog and results are available as CSV for automated benchmarking:

Reproducing

All knowledge graph snapshots and the benchmark runner are included in Samyama Graph Enterprise Edition. Contact us to access the pre-built snapshots and benchmark tooling.

Public Health Knowledge Graph Benchmark

40 queries. 2 knowledge graphs. 305K nodes. 305K edges. Cross-KG federation with health system capacity data.

The public health benchmark demonstrates Samyama’s ability to load, query, and cross-correlate population health determinants with health system capacity data — answering questions from “Why are populations vulnerable?” to “What capacity exists to respond?”

See also: the public-health KGs are also part of the 11-KG Mega Benchmark federation — the HD/HS/PH prefixes there contribute 40 queries to the 500/500-pass v1.0 result, alongside biomedical, FAERS, OMOP, and UniProt content.

The Dataset

Knowledge GraphSourceNodesEdgesKey Entities
Health DeterminantsWorld Bank WDI + WHO Air Quality + WHO Water/Sanitation285,635285,628Country, Region, SocioeconomicIndicator, EnvironmentalFactor, NutritionIndicator, DemographicProfile, WaterResource
Health SystemsWHO SPAR v2 + WHO NHWA (workforce)19,66119,428Country, EmergencyResponse, HealthWorkforce
Total305,296305,056

Data coverage:

  • 211 countries with World Bank indicators across 5 categories (1990–2024)
  • 233 countries with IHR SPAR v2 capacity scores + health workforce density (2020–2023)
  • 80 curated WDI indicators: socioeconomic (16), environmental (10), nutrition (10), demographic (15), water (10)
  • 1,880 country-year PM2.5 air quality records from WHO GHO
  • 47,531 water/sanitation records (safely managed + basic water/sanitation)
  • 11,008 health workforce density records (physicians, nurses, dentists, pharmacists)
  • 15 IHR capacities: legislation, coordination, financing, laboratory, surveillance, human resources, emergency management, health services, IPC, risk communication, points of entry, zoonotic, food safety, chemical, radiation

Results Summary

40 queries executed. 40 returned data. 0 empty. 0 errors.

CategoryQueriesPassEmptyErrorMedian (ms)
Health Determinants20200027.4
Health Systems10100012.2
Cross-KG / Cross-Indicator101000190.7
Total40400015.1

Performance

Infrastructure: MacBook Pro M-series, single process, in-memory graph loaded from .sgsnap snapshots.

MetricValue
Snapshot import (Health Determinants)1.6s (239K nodes, 240K edges)
Snapshot import (Health Systems)0.1s (8.7K nodes, 8.4K edges)
Point lookups1.3–4.2 ms
Single-hop traversals1.8–24.7 ms
Aggregation scans10.6–133.5 ms
Cross-indicator joins105–478 ms
All 40 queries total~3.6s

Query Categories

Health Determinants (HD01–HD20)

Point lookups, indicator traversals, cross-category analysis, and regional aggregations over World Bank WDI data.

IDNameTime (ms)Rows
HD01Country by ISO code4.22
HD02Country by name1.92
HD03All regions1.37
HD04Countries in a region18.16
HD05GNI per capita for India (latest)2.21
HD06India poverty rate trend2.25
HD07PM2.5 air pollution for India1.95
HD08Energy use per capita top 1056.210
HD09Stunting prevalence Nigeria2.05
HD10Countries with high stunting (>30%)36.78
HD11Population top 10 countries133.510
HD12Life expectancy Brazil trend2.510
HD13Infant mortality worst countries119.910
HD14Water stress high countries53.610
HD15Safe drinking water lowest59.610
HD16India all indicators for 20222.311
HD17India environmental profile1.94
HD18Poverty vs life expectancy478.110
HD19Health expenditure vs infant mortality350.910
HD20Regional average GNI per capita238.27

Health Systems (HS01–HS10)

IHR SPAR capacity queries — country profiles, rankings, gaps, and trends.

IDNameTime (ms)Rows
HS01Country by ISO code1.82
HS02SPAR scores for India11.614
HS03SPAR scores for Nigeria11.414
HS04Top 10 by surveillance capacity10.810
HS05Countries with lowest lab capacity11.210
HS06Average SPAR score per country12.210
HS07Countries with lowest avg SPAR10.610
HS08India SPAR trend over years16.04
HS09Risk communication capacity gap (<40)12.710
HS10Count countries per SPAR year18.04

Cross-KG / Cross-Indicator (PH01–PH10)

Queries spanning multiple indicator categories or joining determinants with health system capacity data.

IDNameTime (ms)Rows
PH01India vulnerability + SPAR capacity11.914
PH02High poverty countries SPAR scores105.220
PH03PM2.5 vs surveillance capacity66.35
PH04Water stress + health expenditure274.610
PH05Stunting + infant mortality correlation315.610
PH06Urbanization vs life expectancy404.610
PH07Under-5 mortality + safe water access309.810
PH08Low income full profile + SPAR106.120
PH09Health expenditure vs infant mortality348.510
PH10Nigeria full determinants profile2.08

Sample Query Results

PH02: High poverty countries — do they have health capacity?

MATCH (c1:Country)-[:HAS_INDICATOR]->(pov:SocioeconomicIndicator)
WHERE pov.indicator_code = 'SI.POV.DDAY' AND pov.value > 20
WITH c1.iso_code AS iso, pov.value AS poverty
ORDER BY poverty DESC LIMIT 5
MATCH (e:EmergencyResponse)-[:CAPACITY_FOR]->(c2:Country)
WHERE c2.iso_code = iso AND e.year = 2023
RETURN c2.name, poverty, e.capacity_code, e.score
ORDER BY poverty DESC

This query identifies countries with >20% extreme poverty and correlates with their IHR emergency preparedness scores — answering “Are the most vulnerable populations in countries with the least health system capacity?”

PH07: Under-5 mortality + safe water access

MATCH (c:Country)-[:DEMOGRAPHIC_OF]->(d:DemographicProfile)
WHERE d.indicator_code = 'SH.DYN.MORT' AND d.year = 2022
WITH c, d.value AS u5_mortality
MATCH (c)-[:WATER_RESOURCE_OF]->(w:WaterResource)
WHERE w.indicator_code = 'SH.H2O.SMDW.ZS' AND w.year = 2022
RETURN c.name, u5_mortality, w.value AS safe_water_pct
ORDER BY u5_mortality DESC LIMIT 10

Central African Republic tops both worst lists: 387 under-5 deaths per 1,000 and only 6.1% safely managed drinking water.

6-KG Federation Vision

These two KGs complete the public health trifecta alongside the existing Surveillance KG (217K nodes). Together with the biomedical trifecta (Pathways + Clinical Trials + Drug Interactions), Samyama now supports queries spanning molecular biology to population health:

PUBLIC HEALTH TRIFECTA              BIOMEDICAL TRIFECTA
Surveillance (217K)  ←──────────→  Clinical Trials (7.7M)
         ↓ Country.iso_code               ↑ Drug
Health Determinants (240K)         Drug Interactions (245K)
         ↓ Country.iso_code               ↑ Gene
Health Systems (8.7K) ←─────────→  Pathways (119K)

Bridge property: Country.iso_code (ISO 3166-1 alpha-3) links all public health KGs. Cross-trifecta bridges use Disease.icd_code, Drug.drugbank_id, and Pathogen → Gene mappings.

Data Files

FileDescription
health-determinants-queries.csv20 Health Determinants queries
health-systems-queries.csv10 Health Systems queries
public-health-cross-kg-queries.csv10 Cross-KG queries
public-health-results.csvAll 40 query results with timing

Snapshots

Available for download:

SnapshotSizeSource
health-determinants.sgsnap6.5 MBGitHub Release kg-snapshots-v6
health-systems.sgsnap0.5 MBGitHub Release kg-snapshots-v6
Also on S3s3://samyama-data/snapshots/

Performance & Benchmarks

Samyama is designed for “Mechanical Sympathy”—aligning software data structures with the physical reality of modern CPU caches and high-speed NVMe storage.

Micro-Benchmarks (Mac Mini M4)

All benchmarks run on Mac Mini M4, 16GB RAM, macOS. Comparison between the Community (CPU-only) and Enterprise (GPU-accelerated via wgpu) builds. For workload-level numbers across the full 11-KG federated dataset (138M nodes, 1.22B edges, 500 queries) see the Mega Benchmark.

Ingestion Throughput

Samyama achieves industry-leading ingestion rates on commodity hardware:

OperationCPU-Only (ops/sec)GPU-Enabled (ops/sec)
Node Ingestion255,120412,036
Edge Ingestion4,211,3425,242,096

Note: Edge ingestion is significantly faster because it primarily involves appending to adjacency lists and updating the WAL.

Cypher Query Throughput (OLTP)

For transactional workloads, Samyama’s index-driven execution delivers consistent sub-millisecond latencies:

Graph ScaleQueries/secAvg Latency
10,000 nodes35,360 QPS0.028 ms
100,000 nodes116,373 QPS0.008 ms
1,000,000 nodes115,320 QPS0.008 ms

Index-driven lookups achieve O(1) or O(log n) access. QPS is measured with simple MATCH ... WHERE ... RETURN queries on indexed properties.

These numbers demonstrate that Samyama scales almost linearly—throughput at 1M nodes is comparable to 100K because index-based access eliminates full scans.

GPU Acceleration: The Crossover Point

A key finding from these benchmarks is the impact of memory transfer overhead on GPU acceleration.

AlgorithmScale (Nodes)CPU ComputeGPU (inc. Transfer)Speedup
PageRank10,0000.6 ms9.3 ms0.06x (Slowdown)
PageRank100,0008.2 ms3.1 ms2.6x
PageRank1,000,00092.4 ms11.2 ms8.2x

Conclusion: For subgraphs smaller than 100,000 nodes, the CPU remains faster. Once the scale exceeds this “crossover point,” the GPU parallelism overcomes the memory transfer cost, leading to massive speedups.

Vector Search (HNSW, k=10)

Vector search utilizes hnsw_rs (CPU) for graph traversal. GPU acceleration in Enterprise is used for batch re-ranking after retrieval.

Metric (10K vectors, 128-dim)CPU-OnlyGPU Build
Cosine distance QPS15,872/s11,311/s
L2 distance QPS15,014/s10,429/s
Search 50K vectors10,446 QPS9,428 QPS

Note: The slight slowdown in the GPU build for small vector searches is due to the initialization overhead of the GPU context.

GPU at Scale: S-Size Datasets

On LDBC Graphalytics S-size datasets (millions of vertices), the GPU crossover becomes significant:

AlgorithmDatasetVerticesEdgesCPUGPUSpeedup
LCCcit-Patents3.8M16.5M9.6s4.7s2.0x
CDLPcit-Patents3.8M16.5M9.5s11.1s0.85x
PageRankdatagen-7_5-fb633K68.4MCPU fallback

Note: Extremely dense graphs (e.g., 68M edges on datagen-7_5-fb) trigger CPU fallback due to the 256MB GPU buffer limit on Apple Silicon. Dedicated GPUs with larger VRAM can handle these datasets.

LDBC Graphalytics Validation

Samyama has achieved 100% validation against the LDBC Graphalytics benchmark suite—the industry standard for graph analytics correctness:

AlgorithmXS Datasets (2)S Datasets (3)Total
BFS✅ 2/2✅ 3/35/5
PageRank✅ 2/2✅ 3/35/5
WCC✅ 2/2✅ 3/35/5
CDLP✅ 2/2✅ 3/35/5
LCC✅ 2/2✅ 3/35/5
SSSP✅ 2/2✅ 1/13/3
Total12/1216/1628/28

S-size datasets include cit-Patents (3.8M vertices), datagen-7_5-fb (633K vertices, 68M edges), and wiki-Talk (2.4M vertices). All results match LDBC reference outputs exactly.

Developer Tip: Run the validation yourself with cargo bench --bench graphalytics_benchmark. LDBC datasets are available in data/graphalytics/.

LDBC SNB Interactive & BI Workloads

Beyond Graphalytics (which validates algorithm correctness), Samyama includes benchmark harnesses for the LDBC Social Network Benchmark (SNB) — the industry-standard workload for graph database query performance.

SNB Interactive Workload

21 queries adapted for Samyama’s OpenCypher engine, plus 8 update operations:

CategoryQueriesDescription
Interactive ShortIS1–IS7Point lookups: person profile, posts, friends
Interactive ComplexIC1–IC14Multi-hop traversals: friend-of-friend, common interests, shortest paths
Insert OperationsINS1–INS8Concurrent writes: new persons, posts, comments, friendships
cargo bench --bench ldbc_benchmark                    # All 21 queries
cargo bench --bench ldbc_benchmark -- --query IC6     # Single query
cargo bench --bench ldbc_benchmark -- --updates       # Include writes

SNB Business Intelligence (BI) Workload

20 complex analytical queries testing OLAP-style aggregation over the social network graph:

CategoryQueriesDescription
BI QueriesBI-1 to BI-20Heavy aggregation, multi-hop analytics, temporal filtering

Note: Several BI queries require features beyond current OpenCypher coverage (APOC, CASE, list comprehensions). These are adapted to simplified Cypher that captures the analytical intent using supported constructs.

cargo bench --bench ldbc_bi_benchmark
cargo bench --bench ldbc_bi_benchmark -- --query BI-1

Both workloads operate on the LDBC SF1 dataset loaded via cargo run --example ldbc_loader.

LDBC FinBench Workload

Samyama also includes a harness for the LDBC Financial Benchmark (FinBench) — modeling financial transaction networks with accounts, persons, companies, loans, and mediums.

CategoryQueriesDescription
Complex ReadsCR1–CR12Multi-hop fund transfers, blocked account detection, loan chains
Simple ReadsSR1–SR6Account lookups, transfer history, sign-in records
Read-WritesRW1–RW3Mixed read-write transactions
WritesW1–W19Account creation, transfers, loan operations

40+ queries total, covering both OLTP and analytical patterns for financial graph workloads.

cargo bench --bench finbench_benchmark
cargo bench --bench finbench_benchmark -- --query CR-1
cargo bench --bench finbench_benchmark -- --writes    # Include write operations

Data is loaded via cargo run --example finbench_loader, which can generate synthetic FinBench-compatible datasets.

The Power of Late Materialization

One of our most impactful architectural choices remains Late Materialization.

Latency Impact (1M nodes)

Query TypeLatency (Before)Latency (After)Improvement
1-Hop Traversal164.11 ms41.00 ms4.0x
2-Hop Traversal1,220.00 ms259.00 ms4.7x

Bottleneck Analysis

Profiling our query engine reveals a shift in where time is spent:

ComponentTime% of 1-Hop
Parse (Pest grammar)~22ms54%
Plan (AST → Operators)~18ms44%
Execute (Iteration)<1ms2%

Conclusion: The actual execution of the graph traversal is sub-millisecond. The remaining overhead is in the language frontend (parsing and planning). Our roadmap includes AST Caching and Plan Memoization to bring warm-query latency down to the ~10ms range.

Note: These timings reflect cold-start conditions (first query execution). Subsequent queries benefit from OS-level page cache and instruction cache warmth, reducing total latency significantly.

The Query Engine

The heart of Samyama is its query engine. It translates the user’s intent (expressed in OpenCypher) into actionable operations on the GraphStore.

From String to Execution Plan

When a user sends a query, it travels through a meticulously optimized pipeline:

graph TD
    Query["MATCH (p:Person)-[:KNOWS]->(f) WHERE p.age > 30 RETURN f.name"]
    Query --> Parser[pest Parser]
    Parser -- "Abstract Syntax Tree (AST)" --> Logical[QueryPlanner]
    
    subgraph "Cost-Based Optimizer"
        Logical -- "Generates Logical Plan" --> CBO[Optimizer]
        CBO -. "Reads GraphStatistics" .-> Stats["GraphStatistics"]
        CBO -- "Chooses Index over Full Scan" --> Physical["Physical Execution Plan"]
    end
    
    Physical --> Exec[QueryExecutor]
  1. Parsing (cypher.pest): The query string is converted into an Abstract Syntax Tree (AST).
  2. Logical Planning: The QueryPlanner processes the AST into an ExecutionPlan.
  3. Optimization: The planner uses GraphStatistics to perform cost-based optimization (CBO), such as choosing the correct IndexManager scan instead of a full sequential scan.

Execution Model: The Volcano Iterator & Vectorized Processing

Samyama implements a hybrid Volcano Iterator model utilizing Vectorized Execution.

graph LR
    subgraph "Vectorized Pipeline"
        Scan[IndexScanOperator] -- "Batch of 1024 NodeIds" --> Expand[ExpandOperator]
        Expand -- "Batch of (SrcId, DstId)" --> Filter[FilterOperator]
        Filter -- "Filtered Batch" --> Project[ProjectOperator]
    end
#![allow(unused)]
fn main() {
pub struct QueryExecutor<'a> {
    store: &'a GraphStore,
    planner: QueryPlanner,
}

pub trait PhysicalOperator {
    /// High-performance batch path
    fn next_batch(&mut self, store: &GraphStore, batch_size: usize) -> Option<RecordBatch>;
}
}

(Simplified for clarity; the actual trait includes error handling via ExecutionResult and additional methods like describe() and name() for plan introspection.)

Instead of fetching one row at a time, each PhysicalOperator processes a RecordBatch.

All 35 Physical Operators

Samyama implements 35 physical operators, organized by function:

CategoryOperators
ScanNodeScanOperator, IndexScanOperator, NodeByIdOperator
TraversalExpandOperator, ExpandIntoOperator, ShortestPathOperator
Filter & TransformFilterOperator, ProjectOperator, UnwindOperator, WithBarrierOperator
JoinJoinOperator, LeftOuterJoinOperator, CartesianProductOperator
Aggregation & SortAggregateOperator, SortOperator, LimitOperator, SkipOperator
Write (Mutating)CreateNodeOperator, CreateEdgeOperator, CreateNodesAndEdgesOperator, MatchCreateEdgeOperator, MergeOperator, DeleteOperator, SetPropertyOperator, RemovePropertyOperator, ForeachOperator
Index & ConstraintsCreateIndexOperator, CompositeCreateIndexOperator, CreateVectorIndexOperator, DropIndexOperator, CreateConstraintOperator
Schema InspectionShowIndexesOperator, ShowConstraintsOperator
SpecializedVectorSearchOperator, AlgorithmOperator

By processing batches:

  • Amortized Overhead: Calling virtual functions per batch instead of per row drops L1 instruction cache misses significantly.
  • Late Materialization: We pass lightweight NodeId arrays within RecordBatch columns. Actual properties are fetched from ColumnStore at the very end of the pipeline (ProjectOperator).

Advanced Profiling (EXPLAIN)

A key enterprise feature is the ability to inspect the Execution Plan without executing it. When a query starts with EXPLAIN, the QueryExecutor intercepts it:

#![allow(unused)]
fn main() {
if query.explain {
    return Ok(Self::explain_plan_with_stats(&plan, Some(self.store)));
}
}

The system returns a detailed tree of OperatorDescription instances combined with current GraphStatistics (null fractions, selectivity estimations). This allows database administrators to visualize exactly why the query planner chose a specific index over a graph traversal, enabling deep query tuning.

Query Optimization (Explain)

As queries grow in complexity—involving multiple hops, filters, and vector searches—it becomes impossible to optimize performance by guessing. Samyama provides EXPLAIN for query introspection, backed by a cost-based optimizer that uses graph statistics to choose efficient execution plans.

The Cost-Based Optimizer

Before a query is executed, the QueryPlanner transforms the AST into a physical execution plan. This involves selecting operators, ordering joins, and choosing between index scans and full scans—all based on real-time statistics.

graph TD
    AST["Parsed AST"] --> CBO["Cost-Based Optimizer"]
    CBO -. "Reads" .-> Stats["GraphStatistics"]

    subgraph "GraphStatistics"
        LC["Label Counts<br>Person: 10,000"]
        EC["Edge Type Counts<br>KNOWS: 50,000"]
        PS["Property Stats<br>age: 2% null, selectivity 0.01"]
    end

    CBO --> Plan["Optimized Physical Plan"]

    Plan --> IndexScan["IndexScan<br>(if selective filter)"]
    Plan --> NodeScan["NodeScan<br>(if no useful index)"]

How Statistics Are Gathered

GraphStore::compute_statistics() builds a GraphStatistics struct with:

StatisticSourceUse
Label countsO(1) from label_indexEstimate scan cardinality
Edge type countsO(1) from edge_type_indexEstimate expand cardinality
Average degreeComputed from edge/node ratioEstimate join fan-out
Property statsSampled from first 1,000 nodes per labelEstimate filter selectivity

Property stats include null_fraction, distinct_count, and selectivity—enabling the optimizer to predict how many rows survive a WHERE filter.

Cost Estimation Formulas

The optimizer uses these key estimation methods:

  • estimate_label_scan(label): Returns the number of nodes with that label. For :Person with 10,000 nodes, cost = 10,000.
  • estimate_expand(edge_type): Returns the number of edges of that type. For :KNOWS with 50,000 edges, cost = 50,000.
  • estimate_equality_selectivity(label, property): Returns the fraction of nodes that match a given property value. For age = 30 on a label with 100 distinct age values, selectivity ≈ 0.01.

The planner multiplies these estimates through the operator tree to predict row counts at each stage.

Index Selection Heuristics

The optimizer decides between scan strategies based on selectivity:

ConditionStrategyWhy
Equality filter on indexed propertyIndexScan (O(1) hash or O(log n) B-tree)Direct lookup, skips full scan
Range filter on indexed propertyB-Tree IndexScan (O(log n + k))Efficient range iteration
Low-selectivity filter (> 30% of rows)NodeScan + FilterFull scan is cheaper than index overhead
No filter on scan variableNodeScanNo alternative
Label with < 100 nodesNodeScanNot worth index overhead

Join Ordering

When a query involves multiple MATCH patterns (e.g., MATCH (a)-[:R]->(b)-[:S]->(c)), the optimizer orders joins to minimize intermediate result sizes:

  1. Start with the pattern that produces the fewest rows (most selective label + filter)
  2. Expand along edges with the lowest fan-out first
  3. Apply filters as early as possible (predicate pushdown)

EXPLAIN: Visualizing the Plan

The EXPLAIN prefix tells the engine to parse and plan the query, but not execute it. It returns the operator tree that the physical executor will follow.

Example 1: Simple Traversal

EXPLAIN MATCH (n:Person)-[:KNOWS]->(m:Person)
WHERE n.age > 30
RETURN m.name

Output:

+----------------------------------+----------------+
| Operator                         | Estimated Rows |
+----------------------------------+----------------+
| ProjectOperator (m.name)         |             50 |
|   FilterOperator (n.age > 30)    |             50 |
|     ExpandOperator (-[:KNOWS]->) |            500 |
|       NodeScanOperator (:Person) |            100 |
+----------------------------------+----------------+

--- Statistics ---
Label 'Person': 100 nodes
Edge type 'KNOWS': 500 edges
Property 'age': null_fraction=0.02, distinct=40, selectivity=0.025

Example 2: Index-Driven Lookup

EXPLAIN MATCH (n:Person {name: 'Alice'})-[:KNOWS]->(m)
RETURN m.name

Output:

+----------------------------------------------+----------------+
| Operator                                     | Estimated Rows |
+----------------------------------------------+----------------+
| ProjectOperator (m.name)                     |              5 |
|   ExpandOperator (-[:KNOWS]->)               |              5 |
|     IndexScanOperator (:Person, name='Alice') |              1 |
+----------------------------------------------+----------------+

Notice the optimizer chose IndexScanOperator instead of NodeScanOperator + FilterOperator because name has an index and high selectivity.

Example 3: Aggregation with Sort

EXPLAIN MATCH (n:Person)-[:KNOWS]->(m:Person)
RETURN m.name, count(*) AS friends
ORDER BY friends DESC
LIMIT 10

Output:

+----------------------------------+----------------+
| Operator                         | Estimated Rows |
+----------------------------------+----------------+
| LimitOperator (10)               |             10 |
|   SortOperator (friends DESC)    |            100 |
|     AggregateOperator (count)    |            100 |
|       ExpandOperator (-[:KNOWS]->)|            500 |
|         NodeScanOperator (:Person)|            100 |
+----------------------------------+----------------+

Reading EXPLAIN Output

Key things to look for:

  • Operator ordering: Filters should appear as close to the scan as possible (predicate pushdown)
  • IndexScan vs. NodeScan: If you have an indexed property in your WHERE clause and see NodeScanOperator instead of IndexScanOperator, the optimizer may lack statistics—run a query first to populate stats
  • Estimated Rows: Large drops between operators indicate selective filters. If estimated rows increase at an ExpandOperator, the graph has high fan-out at that relationship type
  • Statistics section: Shows the raw data the optimizer used for its decisions

Optimization Techniques Applied

Samyama’s optimizer applies several rule-based and cost-based optimizations:

TechniqueDescription
Predicate PushdownMove WHERE filters below ExpandOperator when possible
Index SelectionChoose hash/B-tree index when selectivity < 30%
Join ReorderingStart with the most selective pattern
Late MaterializationPass NodeRef(id) instead of full nodes; resolve properties only at ProjectOperator
Limit PropagationPush LIMIT into scan operators to stop early

Future: PROFILE (Runtime Statistics)

Status: PlannedPROFILE is on the roadmap but not yet implemented. Currently, only EXPLAIN is available.

A future PROFILE command would execute the query and collect timing and row-count data for every operator, adding Actual Rows and Time (ms) columns alongside the estimates. This would enable:

  • Identifying the actual bottleneck operator (not just estimated)
  • Comparing estimated vs. actual cardinality to detect stale statistics
  • Measuring late materialization savings at the ProjectOperator

Developer Tip: Use EXPLAIN before running expensive queries. If the plan looks suboptimal, try adding a property index with CREATE INDEX ON :Label(property) and re-run EXPLAIN to see if the optimizer switches to an IndexScanOperator.

Picasso — Plan-Space Visualisation

Picasso is the plan-space visualiser for Samyama Graph. Given a Cypher pattern (or template), it sweeps a parameter or schema dimension, runs EXPLAIN at every grid point, colours each cell by the plan signature the planner chose, and reports a plan-stability score for the sweep.

Picasso ships as a page in samyama-insight at /picasso, backed by the engine’s HTTP EXPLAIN endpoint. No JDBC, no separate tool — it is part of the management UI.

What it answers

  • Does the planner change its mind across a selectivity range? A stable plan-diagram means the cost model produces consistent decisions across the parameter space.
  • Where are the plan boundaries? Adjacent cells with different signatures expose the selectivity points where the planner flips between strategies.
  • How many physical plans does the planner actually consider for this pattern? The “Distinct Plans” metric counts the unique plan signatures observed during the sweep.

Two modes

Graph Pattern Mode

Sweep schema dimensions for a fixed Cypher pattern.

  • Inputs: Label, EdgeType, optional second Label.
  • Per grid cell, the page sends EXPLAIN MATCH (a:Label1)-[:EdgeType]->(b:Label2) ... and records the plan signature.
  • Useful for understanding which label/edge-type combinations the planner treats as “the same plan shape” vs. distinct.

Parameter Sweep Mode

Sweep a numeric range for $param1 (and optionally $param2) in a Cypher template.

  • Input: a Cypher template like MATCH (n:Person) WHERE n.age > $param1 RETURN n and a (min, max, step) range.
  • 1D sweep produces a line; 2D sweep produces a heatmap.
  • Useful for stressing the planner’s selectivity estimation: at low $param1 the predicate is highly selective and IndexScan should fire; at high $param1 it should fall back to NodeScan + filter. The grid makes the transition visible.

Metrics surfaced

MetricWhat it tells you
Distinct PlansUnique plan signatures observed in the sweep. Higher = more strategy diversity.
Plan Stability ScoreFraction of adjacent cells that share the same plan. High score = stable, predictable cost model. Low score = many plan flips.
Plan signature colouringEach unique signature gets a colour from a 20-colour palette so flips are visually obvious.

Why we did not adopt IISc Picasso

The original Picasso project at IISc (Bangalore) is a JDBC-driven plan-diagram tool for PostgreSQL / Oracle / SQL Server / DB2. It runs a sweep, pulls each EXPLAIN over JDBC, and renders the result.

A JDBC adapter for a RESP/HTTP Rust engine would have meant a multi-week protocol-bridge project. The native alternative — connect the Picasso UI directly to the existing HTTP EXPLAIN endpoint — was simpler, kept the toolchain Rust-end-to-end, and ships every time the management UI ships. So Picasso lives in samyama-insight, talks HTTP, and inherits the planner improvements from each release without a separate integration step.

What’s behind the plan diversity

The planner enumerates up to 64 candidate plans per MATCH via plan_enumerator.rs (ADR-015). For each pattern node it tries that node as the entry point, picks a traversal direction by comparing avg_out_degree vs avg_in_degree from GraphCatalog, and chooses Expand vs ExpandInto based on which endpoints are bound at expansion time. Selectivity-aware predicate pushdown via the IndexManager (ADR-029) further differentiates plans.

So the plan diagram Picasso paints is not a single “this is the only plan” verdict — it’s a window into the cost-driven choice across the candidate space.

Remaining gaps

  • Histograms / MCV lists — range and inequality predicates today fall back to default selectivity constants (0.33 and 0.1). Adding equi-depth histograms would tighten the cost-driven plan choice and make Picasso’s reduction-factor analysis (the ratio of chosen-plan-cost to cheapest-plan-cost) meaningful.
  • Cost-vs-actual annotationsPROFILE produces actual row counts per operator; the Picasso grid does not yet overlay that delta on the plan diagram.
  • 3D cost surface — the classic IISc Picasso renders a 3D surface of estimated cost across selectivity space; the Samyama page surfaces distinct-plan count and stability score but not the cost surface itself.
  • Plan-diagram regression tests — there is no test today that asserts “this schema/parameter grid produces exactly N distinct plans”. Worth adding to catch silent planner regressions.

Pointers

  • UI: samyama-insight/src/pages/Picasso.tsx
  • E2E: samyama-insight/e2e/06-picasso.spec.ts
  • Planner: samyama-graph/src/query/executor/plan_enumerator.rs
  • ADRs: ADR-015 (graph-native query planning), ADR-017 (adjacency-aware aggregation), ADR-027 (aggregation pushdown), ADR-029 (IndexManager)
  • Deeper assessment: samyama-cloud/papers/picasso-assessment.md

Persistence at Scale

Every database must answer a fundamental question: How do we not lose data?

For an in-memory graph database like Samyama, this is doubly critical. While we prioritize speed by keeping the active dataset in RAM, we need a robust, battle-tested persistence layer to ensure durability (the ‘D’ in ACID) and to support datasets larger than memory.

We chose RocksDB.

Why RocksDB?

RocksDB, originally forked from Google’s LevelDB by Facebook, is an embedded key-value store based on a Log-Structured Merge-Tree (LSM-Tree). It is the industry standard for high-performance storage engines, powering systems like CockroachDB, TiKV, and Kafka Streams.

The LSM-Tree Advantage

Graph workloads are write-heavy. Creating a single “relationship” between two nodes might involve updating adjacency lists on both ends, updating indices, and writing to the transaction log.

Traditional B-Tree storage suffers from Write Amplification—changing a few bytes can require rewriting entire 4KB or 8KB pages.

LSM-Trees solve this by turning random writes into sequential ones. Here is how Samyama flows data into RocksDB:

graph TD
    Client[Client Write Request] --> WAL[(Write-Ahead Log)]
    WAL --> MemTable[In-Memory MemTable]
    MemTable -- "Flushes when full (64MB)" --> L0[SSTable Level 0]
    L0 -- "Background Compaction" --> L1[SSTable Level 1]
    L1 -- "Background Compaction" --> L2[SSTable Level 2]
    
    style WAL fill:#f9f,stroke:#333,stroke-width:2px
    style MemTable fill:#bbf,stroke:#333,stroke-width:2px
    style L0 fill:#dfd,stroke:#333
    style L1 fill:#dfd,stroke:#333
    style L2 fill:#dfd,stroke:#333

This architecture allows Samyama to sustain massive ingestion rates, as seen in benches/full_benchmark.rs where we achieve over 250,000 nodes/second (CPU) and over 400,000 nodes/second (GPU-accelerated) in raw write throughput.

Schema Design: Mapping Graphs to Key-Value

How do you store a graph (nodes and edges) in a Key-Value store? We use Column Families (logical partitions within RocksDB) to separate different types of data, preventing them from slowing each other down during compaction.

graph LR
    DB[(RocksDB Instance)]
    DB --> CF_Default["CF: default <br> Metadata & Versioning"]
    DB --> CF_Nodes["CF: nodes <br> NodeId -> StoredNode"]
    DB --> CF_Edges["CF: edges <br> EdgeId -> StoredEdge"]
    DB --> CF_Indices["CF: indices <br> B-Tree Property Indices"]

Key Structure

We use a simple, efficient binary encoding for keys. All IDs are u64 integers.

  • Node Key: [u8; 8] -> Big-Endian representation of NodeId.
  • Edge Key: [u8; 8] -> Big-Endian representation of EdgeId.

Value Serialization

For the values (the actual data), we need a format that is compact and fast to deserialize. We chose Bincode.

Bincode is a Rust-specific binary serialization format that effectively dumps the memory representation of a struct to disk. It is significantly faster than JSON, Protobuf, or MsgPack for Rust-to-Rust communication.

#![allow(unused)]
fn main() {
#[derive(Serialize, Deserialize)]
struct StoredNode {
    id: u64,
    labels: Vec<String>,
    properties: Vec<u8>, // Compressed property map
    created_at: i64,
    updated_at: i64,
}
}

The Persistence Code

The integration lives in src/persistence/storage.rs. Here is a simplified view of how we initialize RocksDB with optimal settings for graph workloads:

#![allow(unused)]
fn main() {
pub fn open(path: impl AsRef<Path>) -> StorageResult<Self> {
    let mut opts = Options::default();
    opts.create_if_missing(true);
    
    // Performance Tuning
    opts.set_write_buffer_size(64 * 1024 * 1024); // 64MB batches
    opts.set_compression_type(rocksdb::DBCompressionType::Lz4);

    let cf_descriptors = vec![
        ColumnFamilyDescriptor::new("default", Options::default()),
        ColumnFamilyDescriptor::new("nodes", Self::node_cf_options()),
        ColumnFamilyDescriptor::new("edges", Self::edge_cf_options()),
        ColumnFamilyDescriptor::new("indices", Self::index_cf_options()),
    ];

    let db = DB::open_cf_descriptors(&opts, &path, cf_descriptors)?;
    Ok(Self { db: Arc::new(db), /* ... */ })
}
}

Developer Tip: Check out examples/persistence_demo.rs to see a full working example of how to configure Samyama to persist data to disk, write millions of edges, shut down the server, and seamlessly recover state on the next boot.

Durability vs. Performance

We allow users to configure the sync behavior.

  • Strict Mode: Every write calls fsync, guaranteeing data is on disk. Slower but safest.
  • Background Mode: Writes are acknowledged once in the OS buffer cache. Faster, but risks data loss on power failure (process crash is still safe).

In Samyama, we default to a balanced approach: the Raft log (for consensus) is always fsync’d, while the RocksDB state machine catches up asynchronously. This ensures cluster-wide consistency even if a single node fails.

Managing State (MVCC & Memory)

In a high-performance database, “State” is the enemy of speed. Managing it requires locks, and locks kill concurrency.

If User A is reading a graph to compute a shortest path between two cities, and User B updates a road in the middle of that calculation, what should happen?

  1. Locking: User B waits until User A finishes. Safe but slow.
  2. Dirty Read: User A sees the half-updated state and crashes. Fast but broken.
  3. MVCC: User A sees the old version of the road, while User B writes the new version. Both proceed in parallel.

Samyama implements Multi-Version Concurrency Control (MVCC) with cache-friendly, arena-style storage for nodes and copy-on-write semantics for edges, giving lock-free reads under concurrent writes.

The data model

GraphStore (in src/graph/store.rs) is the single authority for graph state. Two design choices shape everything else:

  • The ID is the index. A NodeId is a direct u64 index into the node arena — not a hash key, not a UUID. NodeId(5) means “slot 5”. This is O(1) without hashing and keeps adjacency walks contiguous in memory.
  • Topology is separated from properties. The arena holds the structural skeleton (id, label, version chain); property values live in column-oriented storage (ColumnStore) keyed by id. Traversals can scan adjacency lists for millions of edges without ever touching property bytes.
graph TD
    subgraph "GraphStore"
        Nodes["nodes: NodeArena<br/>(versioned slots)"]
        EdgeStore["edge store<br/>(COW, EdgeView)"]
        Outgoing["outgoing: Vec&lt;Vec&lt;EdgeId&gt;&gt;"]
        Incoming["incoming: Vec&lt;Vec&lt;EdgeId&gt;&gt;"]
        NodeCols["node_columns: ColumnStore"]
        EdgeCols["edge_columns: ColumnStore"]
    end

    subgraph "Node version chain"
        V1["v1 (old)"] --> V2["v2"]
        V2 --> V3["v3 (latest)"]
    end

    Nodes -.-> V1

Snapshot Isolation for reads

Each node slot keeps a short version chain. When a query begins, it captures the current MVCC version Vq. To read a node, the engine walks the chain backward until it finds the newest version ≤ Vq. No locks. No coordination with writers. Reads at any concurrency level cost a vector indirection plus a tiny linear scan over recent versions.

Edges follow a complementary pattern: the engine no longer keeps a per-edge in-memory arena. Edges are addressed through EdgeView — a lightweight handle that resolves endpoints and properties on demand from columnar storage and the node-side adjacency lists. Edge updates use copy-on-write: an in-flight update produces a new view; readers continue to see the old one until they advance to a fresh snapshot.

The combination — versioned node arena plus COW edges — keeps steady-state memory close to the data’s information-theoretic minimum and makes reads cache-friendly even under sustained write load.

Isolation levels and write-write conflicts

BEGIN ... COMMIT transactions support two isolation levels:

  • Read Committed — each statement sees the latest committed state at statement start. Cheap and the right default for write-heavy workloads.
  • Snapshot Isolation — the entire transaction sees the snapshot taken at BEGIN. Concurrent writers to the same node or edge are detected at commit time; the later committer aborts with a write-write conflict and can retry.

Long-running readers don’t block writers and writers don’t block readers; the only synchronization is the conflict check at commit, which touches just the keys that the transaction wrote.

Version GC

Old versions don’t accumulate forever. A background reclaimer drops node versions older than the oldest live snapshot, and the WAL itself is versioned so log replay can reconstruct the right state on restart. The result is bounded memory regardless of write rate.

Columnar properties

graph LR
    subgraph "ColumnStore (per label)"
        Age["age: Vec&lt;i64&gt;"]
        Name["name: Vec&lt;String&gt;"]
        Salary["salary: Vec&lt;f64&gt;"]
    end

    Query[Query Engine] -- "SIMD aggregation" --> Age
    Query -- "Late materialization" --> Name

Property columns are stored once per label, indexed by node id. The query engine reads them only when the user explicitly references them in WHERE or RETURN. The same column layout supports SIMD-friendly aggregation paths (SUM, AVG, COUNT(*) WHERE ...) without per-row dispatch.

Statistics for the optimizer

GraphStore maintains label counts, edge-type counts, and per-property statistics (null fraction, distinct count, selectivity). The cost-based planner consults these to choose join orders, pick between adjacency walks and edge scans, and decide whether to use an index. See Query Optimization for how the planner uses them.

ACID guarantees

PropertyStatusMechanism
AtomicityRocksDB WriteBatch + WAL — all-or-nothing per transaction
ConsistencySchema validation; Raft quorum acknowledges writes
IsolationMVCC: Read Committed and Snapshot Isolation, with write-write conflict detection at commit
DurabilityRocksDB persistence + Raft replication to majority before acknowledgment

CAP trade-off

Samyama’s Raft-based clustering chooses CP — consistency and partition tolerance:

  • During a network partition, the minority partition refuses writes.
  • Reads from the majority partition remain consistent.
  • Availability is sacrificed during partitions in favor of correctness.

Analytical Power (CSR & Algorithms)

Transactional queries (OLTP) usually touch a small subgraph: “Find Alice’s friends.” Analytical queries (OLAP) touch the entire graph: “Rank every webpage by importance (PageRank).”

The pointer-chasing structure of a standard graph database (Adjacency Lists) is excellent for OLTP but suboptimal for OLAP due to cache misses.

Samyama solves this by introducing a dedicated Analytics Engine in the samyama-graph-algorithms crate. This crate is decoupled from the core storage engine, allowing it to iterate independently and even be used as a standalone library.

The CSR (Compressed Sparse Row) Format

When you run an algorithm like PageRank or Weakly Connected Components, Samyama doesn’t run it directly on the GraphStore. Instead, it “projects” the relevant subgraph into a highly optimized read-only structure called CSR.

A Graph $G=(V, E)$ in CSR format is represented by three contiguous arrays:

  1. out_offsets: Indices indicating where each node’s neighbor list starts in the out_targets array.
  2. out_targets: A massive, flat array containing all neighbor NodeIds.
  3. weights: (Optional) Edge weights corresponding to the out_targets list.
#![allow(unused)]
fn main() {
pub struct GraphView {
    pub out_offsets: Vec<usize>,
    pub out_targets: Vec<NodeId>,
    pub weights: Vec<f32>,
}
}
graph LR
    subgraph "GraphStore (OLTP)"
        AdjList["Adjacency Lists<br>Vec of Vec of EdgeId"]
        Props["Property Maps<br>HashMap per Node"]
    end

    Project["Project to CSR<br>(read-only snapshot)"]

    subgraph "GraphView (OLAP)"
        Offsets["out_offsets: [0, 2, 5, 7, ...]"]
        Targets["out_targets: [1, 3, 0, 2, 4, 1, 3, ...]"]
        Weights["weights: [1.0, 0.5, 1.0, ...]"]
    end

    AdjList --> Project --> Offsets
    Project --> Targets
    Project --> Weights

Why CSR?

  • Memory Efficiency: CSR eliminates the memory overhead of adjacency lists (which are Vec<Vec<EdgeId>> in the core engine).
  • Sequential Memory Access: Iterating through a node’s neighbors becomes a simple sequential scan of the out_targets array, which the CPU can prefetch with nearly 100% accuracy.
  • Zero-Lock Parallelism: Since the CSR structure is immutable once built, algorithms can scale across all available CPU cores using Rayon without a single mutex or atomic lock.

The Algorithm Library (samyama-graph-algorithms)

The samyama-graph-algorithms crate includes an extensive range of graph analytical operations. Every algorithm accesses the graph through the GraphView representation (CSR Format).

Supported algorithms currently include:

  1. Centrality & Importance:

    • pagerank: Global node importance ranking.
    • lcc (Local Clustering Coefficient): Measuring “tight-knitness” around individual nodes.
  2. Community Detection & Connectivity:

    • weakly_connected_components (WCC): Identifying isolated clusters ignoring edge direction.
    • strongly_connected_components (SCC): Finding subgraphs where every node is mutually reachable.
    • cdlp (Community Detection via Label Propagation): Discovering overlapping and non-overlapping dense networks.
    • count_triangles: Analyzing social cohesion.
  3. Pathfinding & Network Flow:

    • bfs: Breadth-first traversal.
    • dijkstra: Finding shortest paths with edge weights.
    • bfs_all_shortest_paths: Resolving every potential path of minimum distance between entities.
    • edmonds_karp: Calculating the absolute maximum flow rate between a source and a sink node.
    • prim_mst: Determining the Minimum Spanning Tree of the graph.
  4. Statistical & Dimensionality Reduction:

    • pca (Principal Component Analysis): Reduces high-dimensional node features to their principal components. Supports two solvers:
      • Randomized SVD (default): Uses the Halko-Martinsson-Tropp algorithm for efficient dimensionality reduction on large datasets. Automatically selected when n > 500.
      • Power Iteration (legacy): Deflation-based eigenvector computation with Gram-Schmidt re-orthogonalization.

PCA Configuration

#![allow(unused)]
fn main() {
pub struct PcaConfig {
    pub n_components: usize,      // Number of components (default: 2)
    pub max_iterations: usize,    // For Power Iteration only (default: 100)
    pub tolerance: f64,           // Convergence threshold (default: 1e-6)
    pub center: bool,             // Subtract column means (default: true)
    pub scale: bool,              // Divide by std dev (default: false)
    pub solver: PcaSolver,        // Auto, Randomized, or PowerIteration
}
}

The PcaResult includes principal components, explained variance ratios, and transform() / transform_one() methods for projecting new data points.

Enterprise Note: GPU-accelerated PCA is available in Samyama Enterprise for datasets exceeding 50,000 nodes (see the Enterprise Edition chapter).

SDK Integration

The same CSR-based algorithms are accessible through the Samyama SDK ecosystem. The Rust SDK’s AlgorithmClient trait provides direct method access, while the Python and TypeScript SDKs execute algorithms via Cypher queries.

from samyama import SamyamaClient

# Embedded mode: algorithms run in-process at Rust speeds
client = SamyamaClient.embedded()

# Execute PageRank via Cypher
result = client.query("""
    MATCH (n:Person)-[:KNOWS]->(m:Person)
    RETURN n.name, n.pagerank
""")

Note: The Rust SDK’s AlgorithmClient provides direct Rust API access to all algorithms (e.g., client.page_rank(config, "Person", "KNOWS")) without going through Cypher. See the SDKs, CLI & API chapter for details.

This architecture allows Samyama to replace dedicated graph analytics frameworks like NetworkX (which is slow) or GraphFrames (which requires Spark), providing a single engine for storage and analysis.

In-Database Optimization (Metaheuristics)

Most graph databases stop at “Retrieval.” They help you find data. Samyama goes a step further into Prescription.

By integrating a suite of highly concurrent metaheuristic solvers directly into the engine via the samyama-optimization crate, we allow users to solve complex Operation Research (OR) problems where the graph is the model.

Supported Solvers

Unlike exact solvers (like CPLEX), metaheuristics are nature-inspired algorithms that search for “good enough” solutions in massive, complex search spaces. The samyama-optimization crate implements an exhaustive list of state-of-the-art algorithms:

  • Metaphor-less: Jaya, QOJAYA (Quasi-Oppositional), RAO (Variants 1, 2, 3), TLBO (Teaching-Learning), ITLBO (Improved TLBO), GOTLBO.
  • Swarm & Evolutionary: PSO (Particle Swarm), DE (Differential Evolution), GA (Genetic Algorithms), GWO (Grey Wolf Optimizer), ABC (Artificial Bee Colony), BAT, Cuckoo, Firefly, GSA (Gravitational Search), FPA (Flower Pollination Algorithm).
  • Physics-based & Other: SA (Simulated Annealing), HS (Harmony Search), BMR, BWR.
  • Multi-Objective: NSGA-II and MOTLBO for determining Pareto frontiers when solving problems with conflicting goals (e.g., “Minimize Cost” vs. “Maximize Safety”).

The Graph-to-Optimization Bridge

Samyama allows you to define an optimization problem directly using Cypher. The database seamlessly maps node properties to decision variables and edges to constraints.

// Example: Optimize Factory production using Particle Swarm Optimization
CALL algo.or.solve({
  algorithm: 'PSO',
  label: 'Factory',
  property: 'production_rate',
  min: 10.0,
  max: 100.0,
  cost_property: 'unit_cost',
  budget: 50000.0,
  population_size: 50,
  iterations: 200
}) 
YIELD fitness, variables

Developer Tip: You can explore the raw performance of these native solvers by running the optimization benchmarks: cargo bench --bench graph_optimization_benchmark. This benchmarks algorithms like PSO and Jaya running concurrently via Rayon.

Solver Convergence

All solvers follow a common iterative pattern: initialize a population, evaluate fitness, evolve, and converge:

graph TD
    Init["Initialize Population<br>(random candidates)"] --> Eval["Evaluate Fitness<br>(against graph properties)"]
    Eval --> Converge{"Converged?<br>OR max iterations?"}
    Converge -- "No" --> Evolve["Evolve Population<br>(algorithm-specific rules)"]
    Evolve --> Eval
    Converge -- "Yes" --> Result["Return Best Solution<br>(YIELD fitness, variables)"]

Each algorithm differs in the “Evolve” step: PSO uses velocity vectors, GWO uses wolf hierarchy, Jaya uses best/worst comparisons, and NSGA-II uses non-dominated sorting with crowding distance.

Parallel Evolution: The Power of Rust

Metaheuristic algorithms are computationally intensive as they evaluate entire populations of candidate solutions. Samyama’s engine handles this at the Rust level:

  • Rayon Integration: Evaluates all candidate solutions in a population in parallel across all CPU cores.
  • SIMD Fitness: Calculates the “fitness” of multiple solutions simultaneously.
  • Zero-Copy Execution: Solutions are directly evaluated against the in-memory GraphStore structures without intermediate mapping.

This unique integration makes Samyama the ideal choice for Smart Manufacturing, Logistics, and Healthcare Management.

Constrained Multi-Objective Optimization

The samyama-optimization crate (included in the open-source Community Edition) provides full support for multi-objective optimization, including NSGA-II and MOTLBO with the Constrained Dominance Principle for handling complex real-world constraints.

Note: All 22 metaheuristic solvers—including the multi-objective solvers NSGA-II and MOTLBO—are available in the OSS edition. The Enterprise edition adds GPU-accelerated constraint evaluation for large-scale problems.

The Reality of Constraints

In academic problems, objectives like “Minimize Cost” and “Maximize Quality” are often explored in a vacuum. In industry, these objectives must be solved while adhering to hard physical or regulatory constraints:

  • Supply Chain: Minimize lead time AND maximize profit, but total warehouse volume cannot exceed 5,000m³.
  • Energy: Maximize grid stability AND minimize carbon output, but no single plant can operate at >95% capacity for more than 4 hours.

Constrained Dominance Principle

The samyama-optimization crate implements this principle in the NSGA-II and MOTLBO solvers. Instead of a simple “penalty” approach (which often struggles to find feasible solutions in tight spaces), the selection logic follows a strict hierarchy:

graph TD
    Compare["Compare Solution A vs B"] --> FeasCheck{"Both<br>Feasible?"}

    FeasCheck -- "Yes" --> Pareto["Standard Pareto<br>Dominance"]
    FeasCheck -- "No" --> MixCheck{"One Feasible,<br>One Not?"}

    MixCheck -- "Yes" --> FeasWins["Feasible Solution<br>Always Wins"]
    MixCheck -- "No (both infeasible)" --> Violation["Lower Total<br>Constraint Violation Wins"]

    Pareto --> Select["Selected for<br>Next Generation"]
    FeasWins --> Select
    Violation --> Select
  1. Feasibility First: A solution that satisfies all constraints is always preferred over one that violates any constraint.
  2. Comparative Violation: Between two infeasible solutions, the one with the lower total constraint violation is preferred.
  3. Standard Dominance: Between two feasible solutions, standard Pareto dominance rules apply.

Defining Constraints in Cypher

The algo.or.solve procedure allows for explicit constraint definitions:

CALL algo.or.solve({
  algorithm: 'NSGA2',
  label: 'Generator',
  objectives: ['cost', 'emissions'],
  constraints: [
    { property: 'load', max: 500.0 },
    { property: 'temperature', max: 100.0 }
  ],
  population_size: 100
})
YIELD pareto_front

This advanced logic ensures that the “Pareto Front” returned by the solver contains solutions that are not only optimal but also physically executable, making Samyama a powerful tool for industrial decision-making.

Technology Choices (The “Why”)

Building a database is an exercise in trade-offs. In this chapter, we explore the specific technology choices that define Samyama and why we chose them over popular alternatives.

Rust vs. The World

Why not C++? Why not Go?

As documented in our internal benchmarks, Rust provides a unique combination of Memory Safety and Zero-Cost Abstractions.

The Performance Gap

In a pure graph traversal benchmark on 1 million nodes (execution only, excluding parse/plan overhead):

  • Rust: 12ms (with 450MB RAM)
  • Go: 45ms (with 850MB RAM + GC Pauses)
  • Java: 38ms (with 1200MB RAM + GC Pauses)

Note: These numbers measure raw traversal execution time. End-to-end Cypher query latency (including parsing and planning) is higher—see the Performance & Benchmarks chapter for full breakdowns.

The “Cautionary Tale of InfluxDB” served as a warning to us. Originally written in Go, the InfluxDB team eventually rewrote their core query engine in Rust to eliminate unpredictable garbage collection pauses that were impacting P99 latencies. We chose to start with Rust to avoid that “technical debt” from day one.

RocksDB vs. B-Trees

We chose an LSM-Tree (RocksDB) over a B-Tree (LMDB).

Graph workloads are naturally write-heavy—every relationship creation involves multiple index updates. B-Trees suffer from “Write Amplification,” where changing a few bytes requires rewriting entire pages. RocksDB turns these random writes into sequential appends, allowing Samyama to sustain over 255,000 node writes per second (CPU) and over 412,000 node writes per second (GPU-accelerated), significantly outperforming LMDB in write-heavy scenarios.

Optimized Serialization: Bincode

Traditional serialization formats like JSON or Protobuf introduce significant overhead. For a performance-first database like Samyama, we needed a format that could serialize and deserialize data with minimal CPU cycles.

We chose Bincode.

Bincode is a compact, binary serialization format specifically optimized for Rust-to-Rust communication. It effectively takes the memory layout of a Rust struct and dumps it to disk.

  • Speed: Deserializing a StoredNode from RocksDB takes nanoseconds.
  • Compactness: No field names or metadata overhead; only the raw values are stored.
  • Safety: Integrated with serde, it ensures that even if the disk format is corrupted, the database won’t crash on invalid memory access.

Mechanical Sympathy: Custom Columnar Storage

For property-heavy analytical queries, even Bincode is too slow because it still requires “hydrating” a full node object. To solve this, Samyama uses a custom Columnar Property Storage for high-performance property access.

By storing properties in a columnar format (e.g., all “ages” together), we achieve Mechanical Sympathy:

  1. Cache Locality: The CPU can prefetch thousands of values at once into the L1 cache.
  2. SIMD-Friendly Layout: The columnar layout is designed to be SIMD-friendly, enabling auto-vectorization by the Rust compiler and future integration with explicit SIMD intrinsics.
  3. Late Materialization: We avoid fetching properties from disk until the very last stage of a query, reducing I/O and CPU overhead by orders of magnitude.

Hardware Acceleration: Why wgpu?

When deciding how to add GPU acceleration to Samyama, we evaluated several options including CUDA, OpenCL, and Vulkan. We ultimately chose wgpu, the Rust implementation of the WebGPU API.

The Portability Advantage

Unlike CUDA (limited to NVIDIA) or OpenCL (which can be temperamental across platforms), wgpu offers a common abstraction layer that targets the most performant native API of the host system:

  • Metal on macOS and iOS.
  • Vulkan on Linux and Android.
  • DirectX 12 on Windows.

Native Performance with WGSL

By writing our compute shaders in WGSL (WebGPU Shading Language), we can offload intensive graph algorithms like PageRank and community detection to the GPU’s thousands of cores. This allows Samyama to remain “Hardware Agnostic” while still delivering hardware-native performance on any modern cloud instance or local machine with a GPU.

Samyama vs. The Giants: A Comparison

How does Samyama compare to industry leaders like Neo4j (the veteran) and FalkorDB (the high-performance alternative, formerly RedisGraph)?

FeatureNeo4jFalkorDBSamyama
LanguageJava (JVM)C (Redis Module)Rust (Native)
Storage ModelPointer-heavy (Adjacency)Sparse Matrices (GraphBLAS)Hybrid (MVCC + CSR + Columnar)
ExecutionInterpreted/JITMatrix MathVectorized (Auto-vectorized)
Vector SearchBolt-on (Index)Native (HNSW)
OptimizationBuilt-in (Metaheuristics)
Memory ManagementGC-HeavyFixed (Redis)Zero-Pause (Arena/RAII)

Why Samyama Wins on Modern Hardware

  • Neo4j suffers from the “GC Tax”—large heaps lead to long garbage collection pauses. Its pointer-heavy structure is also prone to cache misses during multi-hop traversals.
  • FalkorDB (formerly RedisGraph, which was deprecated in 2023) is fast but its dependence on GraphBLAS (Matrix Math) makes it less flexible for complex property-based Cypher queries. It also lacks native AI/Vector capabilities.
  • Samyama represents a “Third Way”: The flexibility of a property graph, the speed of native Rust, and the analytical power of a dedicated CSR-based engine. By focusing on Mechanical Sympathy (aligning with CPU cache lines), Samyama delivers 10x the performance with 1/4 the memory footprint of traditional engines.

Distributed Consensus & Sharding

A single node can only go so far. To scale beyond a single machine’s memory and CPU, Samyama employs a distributed architecture built on the Raft consensus algorithm.

Consistency via Raft

We use the openraft crate, a modern, asynchronous implementation of the Raft protocol.

Raft provides Strong Consistency by ensuring that a cluster of nodes agrees on the order of operations (the Log) before applying them to the state machine (the Graph).

The Raft Cluster Architecture

sequenceDiagram
    participant Client
    participant Leader
    participant Follower1
    participant Follower2

    Client->>Leader: "Write: CREATE (n:Node)"
    Leader->>Leader: "Append to Local Log"
    Leader->>Follower1: "AppendEntries RPC"
    Leader->>Follower2: "AppendEntries RPC"
    
    Follower1-->>Leader: "Ack (Log Appended)"
    
    Note over Leader: "Quorum Reached (2/3)"
    
    Leader->>Leader: "Commit to GraphStore"
    Leader-->>Client: "OK"
    
    Follower2-->>Leader: "Ack (Log Appended)"
    Leader->>Follower1: "Commit RPC (Async)"
    Leader->>Follower2: "Commit RPC (Async)"

The Raft Loop

  1. Leader Election: Nodes elect a Leader.
  2. Log Replication: All write requests go to the Leader. The Leader appends the request to its log and sends it to Followers.
  3. Commit: Once a majority (Quorum) acknowledges the log entry, the Leader commits it.
  4. Apply: The committed entry is applied to the GraphStore.

This ensures that if a client receives an “OK” response, the data is durable on at least $N/2 + 1$ nodes.

Developer Tip: You can run a fully functional 3-node in-memory cluster locally to observe Leader Election and Log Replication by running cargo run --example cluster_demo.

Sharding Strategy

Samyama implements Tenant-Level Sharding.

In a multi-tenant environment (e.g., a SaaS platform serving many companies), data from different tenants is naturally isolated.

  • Shard: A logical partition of the data.
  • Routing: The Router component (src/sharding/router.rs) maps a TenantId to a specific Raft Cluster (Shard).
#![allow(unused)]
fn main() {
// Simplified Routing Logic
pub fn route(&self, tenant_id: &str) -> ClusterId {
    let hash = seahash::hash(tenant_id.as_bytes());
    hash % self.num_shards
}
}

This approach avoids the complexity of distributed graph partitioning (cutting edges across machines) while offering infinite horizontal scale for multi-tenant workloads.

Failure Modes & Recovery

Raft provides well-defined behavior for common failure scenarios:

ScenarioBehavior
Follower failureCluster continues with remaining quorum; failed node catches up on rejoin
Leader failureRemaining nodes elect a new leader (typically within 1-2 heartbeat intervals)
Network partitionMajority partition continues serving; minority partition stops accepting writes (CP trade-off)
Split-brain preventionRaft’s term numbers ensure only one leader per term—stale leaders step down when they see a higher term

See also: The Production-Grade High Availability chapter for Enterprise-specific hardening (HTTP/2 transport, snapshot streaming, cluster metrics).

Future: Graph Partitioning

For single-tenant graphs that exceed one machine, we are researching “Graph-Aware Partitioning” using METIS, but for now, Tenant Sharding is the production-ready strategy.

Production-Grade High Availability

Building a distributed consensus cluster that works in a controlled environment is easy. Building one that survives network partitions, flapping connections, and storage corruption in a production data center is much harder.

Samyama Enterprise builds upon the core Raft implementation with several production-hardened enhancements.

Hardened Network Transport

While the OSS version uses a simulated or basic TCP transport, Enterprise implements a high-performance HTTP/2 based RPC layer (via Axum and Hyper).

  • Encryption: All inter-node traffic is encrypted with TLS by default, ensuring that data replicated across the cluster is safe from interception.
  • Multiplexing: HTTP/2 allows multiple concurrent Raft messages (heartbeats, append entries, votes) to share a single connection, significantly reducing latency and overhead.
  • Keep-Alive: Intelligent probing detects “silent” network failures faster, triggering leader re-election before the application layer experiences a timeout.

Robust Snapshot Synchronization

In a large cluster, a node that has been offline for a long time cannot catch up by replaying millions of individual log entries. It needs a Snapshot.

Samyama Enterprise automates the entire snapshot lifecycle:

graph LR
    subgraph "Leader"
        L1["1. Generate Snapshot<br>(RocksDB + GraphStore)"]
        L2["2. Compress (LZ4)"]
        L3["3. Stream Chunks<br>(HTTP/2 chunked transfer)"]
    end

    subgraph "Lagging Follower"
        F1["4. Receive Chunks"]
        F2["5. Verify Checksum"]
        F3["6. Atomic Install<br>(replace old state)"]
        F4["7. Resume Log<br>Replication"]
    end

    L1 --> L2 --> L3 --> F1 --> F2 --> F3 --> F4
  1. Generation: The Leader creates a consistent point-in-time image of the GraphStore and RocksDB.
  2. Streaming: The snapshot is compressed and streamed to the lagging Follower using a chunked transfer protocol to avoid memory spikes.
  3. Atomic Installation: The Follower installs the snapshot atomically, replacing its old state only after verifying the snapshot’s checksum.

Cluster Metrics & Health

Maintaining a healthy Raft cluster requires deep visibility into node roles and replication lag. Enterprise exports specific metrics for each node:

  • raft_role: Is this node a Leader, Follower, or Candidate?
  • raft_term: The current logical clock value.
  • raft_replication_lag: The distance (in sequence numbers) between the Leader’s log and this node’s log.

By monitoring these metrics, SREs can proactively identify lagging nodes or cluster instability before they impact service availability.

AI & Vector Search

The “Vector Database” hype train has led to many specialized tools (Pinecone, Weaviate). But a vector is just a property of a node. Separating vectors from the graph creates data silos.

Samyama treats Vectors as First-Class Citizens.

The HNSW Index & VectorIndexManager

We use the Hierarchical Navigable Small World (HNSW) algorithm (via the hnsw_rs crate) to index high-dimensional vectors. In Samyama, this is orchestrated by the VectorIndexManager defined in src/vector/manager.rs.

  • Storage: Vectors are stored persistently via ColumnStore or a dedicated RocksDB column family.
  • Indexing: The HNSW graph (VectorIndex) is maintained in memory for millisecond-speed nearest neighbor search.
#![allow(unused)]
fn main() {
pub struct VectorIndex {
    dimensions: usize,
    metric: DistanceMetric, // Cosine, L2, or DotProduct
    hnsw: Hnsw<'static, f32, CosineDistance>,
}
}

The system natively supports multiple distance metrics out-of-the-box (Cosine, L2, DotProduct) depending on the embedding model used, automatically matching the metric type to the specific index (IndexKey).

Developer Tip: See benches/vector_benchmark.rs to observe how Samyama achieves over 15,000 queries per second (QPS) for 128-dimensional Cosine distance searches on commodity hardware.

Graph RAG (Retrieval Augmented Generation)

The true power of Samyama comes from combining Vector Search with Graph Traversal in a single query.

Scenario: You want to find legal precedents that are semantically similar to a case file AND cited by a specific judge.

If using a pure Vector DB:

  1. Query Vector DB -> Get top 100 docs.
  2. Filter in application -> Keep only those cited by Judge X.
  3. Problem: You might filter out all 100 docs!

The Samyama Graph RAG Architecture

graph TD
    Query["Query Vector: 'Breach of Contract'"] --> HNSW[HNSW Vector Index]
    HNSW -- "Returns Top K NodeIds (Pre-filtering)" --> Engine[Query Engine]
    
    Engine -- "Traverse Outgoing Edges" --> Adjacency[GraphStore Adjacency List]
    Adjacency -- "Filter by Label/Property" --> Filter["Judge = 'Scalia'"]
    
    Filter -- "Yield Results" --> LLM[LLM Context Window]

Samyama achieves this efficiently using the VectorSearchOperator intertwined with standard graph operators:

// 1. Vector Search finds the entry points
CALL db.index.vector.queryNodes('Precedent', 'embedding', $query_vector, 100)
YIELD node, score

// 2. Graph Pattern filters them immediately
MATCH (node)<-[:CITED]-(j:Judge {name: 'Scalia'})

// 3. Return best matches
RETURN node.summary, score
ORDER BY score DESC LIMIT 5

This “Pre-filtering” happens directly inside the execution engine, minimizing memory transfers and enabling highly efficient Retrieval-Augmented Generation workflows.

Embedding Providers

Samyama stores and indexes vectors — but generating them (turning text, images, or other data into vectors) is a separate concern. The database is intentionally embedding-model-agnostic: you choose the provider that fits your stack.

Provider Options

ProviderLanguageModel ExampleUse Case
Mock (default)Rust/PythonRandom vectorsTesting, CI, development
sentence-transformersPythonall-MiniLM-L6-v2Production Python apps
ONNX RuntimeRust (ort crate)Same models, ONNX formatProduction Rust apps
OpenAI APIAny (HTTP)text-embedding-3-smallCloud-hosted, no GPU needed
OllamaAny (HTTP)nomic-embed-textLocal, private, no API keys

Why Mock is the Default

Samyama ships with a Mock embedding provider that generates random vectors. This is deliberate:

  • Zero dependencies: No model downloads, no Python, no GPU drivers
  • Fast CI: Tests and benchmarks run without external services
  • Small binary: No +30MB ONNX Runtime or ML framework bundled
  • Your choice: Embedding models evolve fast — we don’t lock you in

For production, you bring your own embeddings. The database doesn’t care how the vectors were generated — it indexes and searches them the same way.

Python SDK with sentence-transformers

The most common path for Python applications. Install sentence-transformers alongside the Samyama Python SDK:

pip install samyama sentence-transformers
from samyama import SamyamaClient
from sentence_transformers import SentenceTransformer

# Load embedding model (downloads ~80MB on first run)
model = SentenceTransformer("all-MiniLM-L6-v2")  # 384 dimensions

client = SamyamaClient.embedded()

# Create vector index
client.create_vector_index("Document", "embedding", 384, "cosine")

# Generate and store embeddings
texts = ["Graph databases unify structure and search",
         "Knowledge graphs power industrial operations"]
embeddings = model.encode(texts)

for i, emb in enumerate(embeddings):
    node_id = client.query("default",
        f"CREATE (d:Document {{title: '{texts[i]}'}}) RETURN id(d)")[0][0]
    client.add_vector("Document", "embedding", node_id, emb.tolist())

# Semantic search
query_emb = model.encode("How do graph databases work?").tolist()
results = client.vector_search("Document", "embedding", query_emb, 5)
# Returns: [(node_id, distance), ...]

Rust with ONNX Runtime

For Rust applications that need in-process embeddings without Python, use the ort crate with ONNX-exported models:

# Export a sentence-transformers model to ONNX (one-time, requires Python)
python -c "
from optimum.onnxruntime import ORTModelForFeatureExtraction
model = ORTModelForFeatureExtraction.from_pretrained(
    'sentence-transformers/all-MiniLM-L6-v2', export=True)
model.save_pretrained('./model_onnx')
"
#![allow(unused)]
fn main() {
// In your Rust application
use ort::{Session, Value};

let session = Session::builder()?
    .with_model_from_file("model_onnx/model.onnx")?;

// Tokenize and run inference (simplified — real code needs a tokenizer)
let embeddings = session.run(inputs)?;

// Store in Samyama
client.create_vector_index("Document", "embedding", 384, DistanceMetric::Cosine).await?;
client.add_vector("Document", "embedding", node_id, &embedding_vec).await?;
}

HTTP Embedding Providers

Any service that exposes an embedding endpoint works. Generate vectors externally, store them in Samyama:

# OpenAI
curl -s https://api.openai.com/v1/embeddings \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{"model":"text-embedding-3-small","input":"Graph databases"}' \
  | jq '.data[0].embedding'

# Ollama (local)
curl -s http://localhost:11434/api/embeddings \
  -d '{"model":"nomic-embed-text","prompt":"Graph databases"}' \
  | jq '.embedding'

Then store via Samyama’s HTTP API or SDK. The database is agnostic to the source.

Choosing a Provider

Need real embeddings?
├── Python app? → sentence-transformers (easiest, best model selection)
├── Rust app?   → ort crate + ONNX model (fastest, no Python dep)
├── Any language, cloud OK? → OpenAI API (simplest, pay-per-use)
├── Any language, local/private? → Ollama (free, runs anywhere)
└── Just testing? → Mock (default, zero setup)

See also: The Agentic Enrichment chapter for how vector search powers autonomous knowledge graph expansion, and the SDKs, CLI & API chapter for the VectorClient API.

Agentic Enrichment

Traditional databases are passive. They store what you give them. If you ask a question and the data isn’t there, you get an empty result.

Samyama introduces Agentic Enrichment—a paradigm shift where the database becomes an active participant in building its own knowledge.

From RAG to GAK

We are all familiar with Retrieval-Augmented Generation (RAG): using a database to help an LLM. Samyama implements Generation-Augmented Knowledge (GAK): using an LLM to help build the database.

The Autonomous Enrichment Loop

Samyama can be configured with Enrichment Policies via AgentConfig. When a new node is created or a specific property is queried, an autonomous agent (managed by AgentRuntime) can “wake up” to fill in the gaps.

sequenceDiagram
    participant User
    participant Engine as Query Engine
    participant Agent as AgentRuntime
    participant LLM as LLM Provider
    participant Web as Web Search

    User->>Engine: "CREATE (d:Drug {name: 'Semaglutide'})"
    Engine->>Engine: Node created
    Engine->>Agent: Event Trigger fires

    Agent->>LLM: "Find clinical trials for Semaglutide"
    LLM->>Agent: Tool call - WebSearchTool

    Agent->>Web: Search "Semaglutide clinical trials"
    Web-->>Agent: Unstructured results

    Agent->>LLM: "Parse results into structured JSON"
    LLM-->>Agent: JSON entities + relationships

    Agent->>Engine: "CREATE (t:Trial {...})-[:STUDIES]->(d)"
    Engine-->>User: Graph enriched automatically

The Runtime Architecture

Inside the engine, the agent loop is implemented in src/agent/mod.rs using a tool-based architecture.

#![allow(unused)]
fn main() {
pub struct AgentRuntime {
    config: AgentConfig,
    llm_client: Arc<NLQClient>,
    tools: HashMap<String, Box<dyn AgentTool>>,
}

#[async_trait]
pub trait AgentTool: Send + Sync {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    async fn execute(&self, input: &Value) -> Result<Value, AgentError>;
}
}

Example: The Research Assistant

Imagine you are building a medical knowledge graph. You create a node for a new drug, Semaglutide.

The Passive Way: You manually search PubMed, find papers, and insert them. The Samyama Way:

  1. You create the Drug node.
  2. An Event Trigger fires an AgentRuntime instance.
  3. The Agent uses a WebSearchTool (implementing the AgentTool trait) to find recent clinical trials.
  4. The Agent interacts with the LLM via NLQClient to parse the unstructured results into structured JSON.
  5. The database automatically executes CREATE commands to link the new papers to the Drug node.

Developer Tip: You can see this GAK paradigm in action by running cargo run --example agentic_enrichment_demo. This demo will automatically reach out to an LLM provider, search the web for missing node properties, and execute the Cypher queries to persist them in the local graph.

Just-In-Time (JIT) Knowledge Graphs

This enables what we call a JIT Knowledge Graph. The graph doesn’t need to be complete on day one. It grows and “heals” itself based on user interaction.

If a user asks: “How does the current Fed interest rate impact my mortgage?” and the Fed Rate node is missing, the database can fetch the live rate, create the node, and then answer the question.

Safety & Validation

Auto-generated Cypher from LLM outputs is validated before execution:

  1. Schema Validation: Generated CREATE commands must target known labels and property types
  2. Query Safety: The NLQPipeline::is_safe_query() method rejects destructive operations (DELETE, DROP) from agent-generated queries
  3. Rate Limiting: The AgentConfig includes limits on enrichment operations per minute to prevent runaway loops
  4. Audit Trail: All agent-generated mutations are logged (Enterprise) for traceability

See also: The AI & Vector Search chapter for the underlying HNSW infrastructure, and the SDKs, CLI & API chapter for how to access AgentRuntime via the SDK.

By integrating LLMs directly into the write pipeline, Samyama transforms from a simple storage engine into a dynamic, self-evolving brain.

RDF & SPARQL Support

Samyama provides native support for the Resource Description Framework (RDF) data model alongside its property graph engine. This enables interoperability with Linked Data ecosystems, ontology-based knowledge graphs, and standards-compliant data exchange.

RDF Data Model

RDF represents knowledge as a collection of triples—statements in the form of Subject-Predicate-Object:

<http://example.org/alice> <http://xmlns.com/foaf/0.1/name> "Alice" .
<http://example.org/alice> <http://xmlns.com/foaf/0.1/knows> <http://example.org/bob> .

Core Types

Samyama’s RDF implementation (built on the oxrdf crate) provides the standard RDF term types:

TypeDescriptionExample
NamedNodeAn IRI-identified resource<http://example.org/alice>
BlankNodeAn anonymous resource_:b1
LiteralA value (with optional language/datatype)"Alice", "42"^^xsd:integer
TripleA Subject-Predicate-Object statement
QuadA Triple + named graph

Triple Patterns

For querying, Samyama supports TriplePattern and QuadPattern with optional wildcards:

#![allow(unused)]
fn main() {
// Find all triples where Alice is the subject
let pattern = TriplePattern::new(
    Some(alice.clone().into()),
    None,  // any predicate
    None,  // any object
);
let results = store.query(pattern);
}

In-Memory RDF Store

The RdfStore provides an efficient in-memory triple store with three-way indexing:

graph LR
    subgraph "RdfStore Indices"
        SPO["SPO Index<br>(Subject → Predicate → Object)"]
        POS["POS Index<br>(Predicate → Object → Subject)"]
        OSP["OSP Index<br>(Object → Subject → Predicate)"]
    end

    Query["Triple Pattern"] --> SPO
    Query --> POS
    Query --> OSP

This triple-indexing strategy enables O(1) lookups for any fixed pattern component:

  • SPO: Efficient for “What does Alice know?”
  • POS: Efficient for “Who has the name ‘Alice’?”
  • OSP: Efficient for “What relates to Alice?”

Named graphs are also supported, allowing triples to be organized into logical collections.

Serialization Formats

Samyama supports reading and writing RDF in four standard formats:

FormatExtensionLibraryReadWrite
Turtle.ttlrio_turtle
N-Triples.ntrio_api
RDF/XML.rdfrio_xml
JSON-LD.jsonldCustom

Example: Loading Turtle Data

#![allow(unused)]
fn main() {
use samyama::rdf::{RdfParser, RdfFormat, RdfStore};

let turtle_data = r#"
    @prefix foaf: <http://xmlns.com/foaf/0.1/> .
    @prefix ex: <http://example.org/> .

    ex:alice foaf:name "Alice" ;
             foaf:knows ex:bob .
    ex:bob   foaf:name "Bob" .
"#;

let triples = RdfParser::parse(turtle_data, RdfFormat::Turtle)?;
let mut store = RdfStore::new();
for triple in triples {
    store.insert(triple)?;
}
}

Example: Serializing to N-Triples

#![allow(unused)]
fn main() {
use samyama::rdf::{RdfSerializer, RdfFormat};

let output = RdfSerializer::serialize_store(&store, RdfFormat::NTriples)?;
// <http://example.org/alice> <http://xmlns.com/foaf/0.1/name> "Alice" .
// <http://example.org/alice> <http://xmlns.com/foaf/0.1/knows> <http://example.org/bob> .
// <http://example.org/bob> <http://xmlns.com/foaf/0.1/name> "Bob" .
}

Namespace Management

The NamespaceManager provides prefix resolution for compact IRIs, pre-loaded with standard ontologies:

PrefixNamespace
rdfhttp://www.w3.org/1999/02/22-rdf-syntax-ns#
rdfshttp://www.w3.org/2000/01/rdf-schema#
xsdhttp://www.w3.org/2001/XMLSchema#
owlhttp://www.w3.org/2002/07/owl#
foafhttp://xmlns.com/foaf/0.1/
dc / dctermsDublin Core
#![allow(unused)]
fn main() {
let ns = NamespaceManager::new();
let expanded = ns.expand("foaf:name");
// → "http://xmlns.com/foaf/0.1/name"
}

SPARQL Query Engine

Status: Foundation — The SPARQL engine infrastructure is in place (parser via spargebra, executor scaffolding, result types), but query execution is not yet fully operational. The current focus is on the property graph / OpenCypher engine.

The SparqlEngine provides the framework for SPARQL 1.1 query processing:

#![allow(unused)]
fn main() {
pub struct SparqlEngine {
    store: RdfStore,
    executor: SparqlExecutor,
}

impl SparqlEngine {
    pub fn query(&self, sparql: &str) -> SparqlResult<SparqlResults>;
    pub fn update(&mut self, sparql: &str) -> SparqlResult<()>;
}
}

Planned Query Forms

FormPurposeStatus
SELECTReturn variable bindingsPlanned
CONSTRUCTBuild new RDF graphsPlanned
ASKBoolean existence checkPlanned
DESCRIBEResource descriptionPlanned

Result Formats

SPARQL results support standard serialization formats:

#![allow(unused)]
fn main() {
pub enum ResultFormat {
    Json,   // SPARQL Results JSON
    Xml,    // SPARQL Results XML
    Csv,    // Tabular CSV
    Tsv,    // Tabular TSV
}
}

Property Graph ↔ RDF Mapping

Samyama includes a mapping layer for converting between its native property graph model and RDF:

Property GraphRDF
Node with label “Person”<node_iri> rdf:type ex:Person
Property name = "Alice"<node_iri> ex:name "Alice"
Edge of type “KNOWS”<src_iri> ex:KNOWS <dst_iri>

Note: The bidirectional mapping infrastructure (via MappingConfig) is defined but the automatic conversion is on the roadmap. Currently, RDF data should be loaded directly via the serialization parsers.

Dependencies

The RDF/SPARQL stack uses these Rust crates:

CrateVersionPurpose
oxrdf0.2RDF primitive types
rio_api0.8RDF I/O API interface
rio_turtle0.8Turtle parser/serializer
rio_xml0.8RDF/XML parser/serializer
spargebra0.3SPARQL 1.1 parser

Predictive Power (GNNs)

Status: Planned — The features described in this chapter are on the Samyama roadmap and are not yet implemented. This chapter outlines the design vision for future GNN integration.

While traditional graph algorithms like PageRank tell you about the importance of a node, Graph Neural Networks (GNNs) would allow the database to make predictions about the future.

Samyama’s philosophy on GNNs is clear: Focus on Inference, not Training.

The Problem: Data Gravity

Training a GNN model (using frameworks like PyTorch Geometric or DGL) requires massive compute power and specialized hardware. However, once a model is trained, moving the entire graph to a Python environment every time you need a prediction is slow and expensive. This is “Data Gravity.”

The Planned Solution: In-Database Inference

The planned approach is to implement an inference engine based on ONNX Runtime (ort).

How it will work:

  1. Export: Train your GNN in Python (where the data science ecosystem is best) and export it to the standard ONNX format.
  2. Upload: Upload the model to Samyama.
  3. Execute: Run predictions directly in Cypher queries.
// Future: Predict the fraud risk for a person based on their connections
CALL algo.gnn.predict('fraud_model_v1', 'Person')
YIELD node, score
SET node.fraud_score = score

Planned: GraphSAGE Aggregators

A future addition would be native GraphSAGE-style Aggregators for “Zero-Config” intelligence.

Instead of an external model, these aggregators would leverage the existing Vector Search (HNSW) infrastructure to compute new node embeddings by aggregating the vectors of neighbors (mean, max, or LSTM pooling).

This would allow the database to act as a Dynamic Feature Store, where embeddings are updated in real-time as the graph evolves, providing a predictive layer that most graph databases offer only through external tooling.

Samyama Enterprise Edition

While the Community Edition (OSS) provides the high-performance core engine, the Samyama Enterprise Edition is designed for mission-critical production environments that require hardware acceleration, 24/7 availability, robust data protection, and deep operational visibility.

The Production Gap

Moving a database from a developer’s laptop to a production cluster involves solving three major challenges:

  1. Observability: Knowing the health of the system before users complain.
  2. Durability: Guaranteeing that data can be recovered even after catastrophic hardware failure.
  3. Hardware Acceleration: Utilizing modern GPUs for massive graph analytical workloads.

Feature Matrix

CategoryFeatureCommunity (OSS)Enterprise
Core EngineProperty Graph (nodes, edges, labels, 7 property types)
OpenCypher Query Engine (~90% coverage)
RESP Protocol (Redis-compatible)
ACID Transactions (local)
MVCC — Snapshot Isolation + Read Committed
PersistenceRocksDB Storage (LZ4/Zstd compression)
Write-Ahead Log (WAL)
Multi-Tenancy (tenant CRUD API, quotas, isolation)
Backup & Restore (Full/Incremental)
Point-in-Time Recovery (PITR)
Scheduled Backups & Retention Policies
MonitoringLogging (tracing crate)
Prometheus Metrics (/metrics)
Health Checks (/health/live, /health/ready)
Slow Query Log & Audit Trail
ADMIN. RESP Commands*
High AvailabilityRaft Consensus (openraft)BasicEnhanced
HTTP Raft Transport (inter-node RPC)
Raft Metrics & Snapshot Recovery
AdvancedVector Search (HNSW)
RDF/SPARQL 1.1 Support
Graph Algorithms (PageRank, BFS, community detection)
Natural Language Query (LLM text-to-Cypher)
GPU Acceleration (wgpu)

1. Hardware Acceleration (wgpu)

Samyama Enterprise includes hardware-accelerated compute via the samyama-gpu crate. Built on wgpu, it provides cross-platform acceleration (Metal on macOS, Vulkan on Linux, DX12 on Windows).

  • GPU Algorithms: PageRank, CDLP (Label Propagation), LCC (Clustering Coefficient), Triangle Counting, and PCA (Principal Component Analysis) are implemented as WGSL compute shaders.
  • Vector Distance: Optimized cosine distance and inner product shaders for batch re-ranking after HNSW retrieval.
  • Query Operators: Parallel reduction for SUM aggregations and bitonic sort for ORDER BY on large result sets (>10,000 rows).

Mechanical Sympathy Note: The engine uses a MIN_GPU_NODES threshold (default 1,000). For PCA specifically, the threshold is higher (MIN_GPU_PCA = 50,000 nodes and d > 32 dimensions) due to the additional overhead of covariance matrix computation. For smaller subgraphs, the CPU remains faster due to memory transfer overhead. The GPU parallelism dominates once the graph scale exceeds ~100,000 nodes.

GPU PCA Shaders

PCA on the GPU uses five specialized WGSL compute shaders:

  1. pca_mean.wgsl: Parallel mean computation across feature columns.
  2. pca_center.wgsl: Mean-centering the data matrix.
  3. pca_covariance.wgsl: Tiled covariance matrix computation (processes 64 samples per tile for cache efficiency).
  4. pca_power_iter.wgsl: Power iteration for eigenvector extraction.
  5. pca_power_iter_norm.wgsl: Fused power iteration with in-GPU normalization—computes matrix-vector multiply, parallel reduction for the norm, and normalization in a single dispatch, avoiding costly CPU↔GPU synchronization per iteration.

2. Monitoring & Observability

Enterprise provides a full-stack observability suite:

  • Prometheus /metrics: Over 200 real-time counters and histograms (queries/sec, P99 latency, connection counts).
  • Health API: JSON-based health status (/api/health) with dedicated Kubernetes liveness/readiness probes.
  • Audit Trail: Cryptographically secure logs of every administrative action and data modification for compliance (GDPR, SOC2).

3. Data Protection (Backup & Recovery)

The Enterprise persistence layer (src/persistence/backup.rs) moves beyond the WAL:

  • Incremental Backups: WAL-based delta backups minimize storage costs.
  • Point-in-Time Recovery (PITR): Restore the database to a specific backup ID, WAL sequence, or microsecond timestamp.
  • Retention Policies: Automated cleanup based on backup age or total count.

4. Enhanced High Availability

The Enterprise edition features a production-hardened Raft implementation (+850 lines of code over OSS):

  • HTTP Transport: Inter-node communication uses encrypted HTTP/2 (Axum-based) instead of simulated local pipes.
  • Snapshot Recovery: Automatically synchronizes lagging nodes by streaming compressed database snapshots.
  • Role Tracking: Advanced metrics for leader election, quorum health, and log replication lag.

5. Licensing & Governance

Enterprise features are gated via an Ed25519-signed JET (JSON Enablement Token).

Token Format

base64(header).base64(payload).base64(signature)

The payload contains: id, org, email, edition, features[], max_nodes, max_cluster_nodes, issued_at, expires_at, and machine fingerprint.

License Hardening

The Enterprise licensing system includes multiple layers of protection:

ProtectionMechanism
Public Key EmbeddingEd25519 public key compiled into the binary via build.rs (release builds only)
Machine FingerprintSHA-256 hash of hostname + primary MAC address binds license to specific hardware
Clock Drift ProtectionPersisted timestamp tracking with 1-hour tolerance prevents system clock manipulation
Usage EnforcementNode count checked before every CREATE at both RESP and HTTP layers
Revocation ListEd25519-signed revocation.jet checked at startup; revoked licenses immediately disabled
TelemetryOptional anonymous heartbeat reporting license health (opt-out via SAMYAMA_TELEMETRY=off)
  • Grace Period: 30-day operation after license expiry with warning logs. On day 31, enterprise features are disabled but the core engine continues operating.
  • Governance: Use ADMIN.TENANTS to monitor per-tenant resource usage and enforce strict memory/storage quotas in multi-tenant environments.

Backup & Disaster Recovery

In an enterprise setting, a database is only as good as its last backup. Samyama Enterprise includes a comprehensive data protection suite that ensures zero data loss and minimal downtime.

Backup Strategies

graph TD
    Strategy["Choose Backup Strategy"] --> Full["Full Snapshot"]
    Strategy --> Incremental["Incremental (WAL Delta)"]
    Strategy --> PITR["Point-in-Time Recovery"]

    Full -- "Complete RocksDB<br>BackupEngine snapshot" --> Store["Backup Store"]
    Incremental -- "Only changed WAL<br>entries since last backup" --> Store
    PITR -- "Snapshot + WAL replay<br>to exact timestamp" --> Restore["Restored Database"]

    Store --> Restore

Samyama supports three distinct levels of backup:

1. Full Snapshots

Leveraging RocksDB’s BackupEngine, Samyama can create a consistent, point-in-time snapshot of the entire database state without blocking incoming queries. These snapshots are stored in a dedicated backup directory and can be moved to off-site storage (e.g., AWS S3).

2. Incremental Backups

To optimize for storage and speed, Samyama can perform incremental backups. It tracks the Write-Ahead Log (WAL) sequence numbers and only archives the data blocks that have changed since the last full or incremental backup.

3. Point-in-Time Recovery (PITR)

This is the most advanced feature of our recovery engine. By replaying the archived WAL entries against a snapshot, Samyama can restore the database to an exact moment in time.

  • Use Case: If a developer accidentally runs a MATCH (n) DELETE n query at 10:30:05 AM, the administrator can restore the system to 10:30:04 AM, undoing the damage with microsecond precision.

The ADMIN.BACKUP Protocol

Backups are managed via the RESP protocol using standard Redis-compatible clients.

# Create a new backup
redis-cli ADMIN.BACKUP CREATE

# List existing backups
redis-cli ADMIN.BACKUP LIST

# Verify the integrity of a backup
redis-cli ADMIN.BACKUP VERIFY 5

Retention Policies

To prevent disk exhaustion, Samyama Enterprise allows administrators to define automatic retention policies:

  • Max Count: Keep only the last $N$ backups.
  • Max Age: Automatically delete backups older than $X$ days.

This automated maintenance ensures that the system remains operational without manual intervention, providing peace of mind for site reliability engineers.

Recovery Guarantees

MetricGuarantee
RPO (Recovery Point Objective)Zero data loss with WAL-based incremental backups; microsecond precision with PITR
RTO (Recovery Time Objective)Minutes for full snapshot restore; seconds for WAL replay of recent changes
ConsistencyBackups use RocksDB’s BackupEngine which creates a consistent snapshot without blocking writes
Concurrent WritesBackup operations do not block incoming queries—RocksDB snapshots are lock-free

Developer Tip: Schedule backups during off-peak hours for minimal performance impact. Use ADMIN.BACKUP VERIFY periodically to ensure backup integrity before you need them.

Administrative Protocol

Samyama Enterprise introduces a dedicated Administrative Protocol implemented via the ADMIN.* RESP command set. This allows database administrators to control and monitor the server using standard Redis clients without resorting to separate APIs or CLI tools.

Server Management

These commands allow operators to inspect the internal state of a Samyama node without leaving their terminal.

  • ADMIN.STATUS: Returns high-level health indicators, including server uptime, total query count, active connection count, and memory usage.
  • ADMIN.METRICS: Dumps the complete internal metrics registry as a JSON object. This is useful for ad-hoc debugging or custom monitoring integration.
  • ADMIN.CONFIG GET/SET: Allows for dynamic reconfiguration of the server without a restart. You can adjust the slow_query_threshold, memory quotas, or log levels on the fly.

Tenant Governance

In a multi-tenant environment, the ADMIN.TENANTS command is critical. It provides a detailed breakdown of resource consumption across the cluster:

FieldDescription
Tenant IDThe unique namespace of the tenant.
Node CountNumber of nodes in this tenant’s graph.
Storage (MB)Disk space consumed in RocksDB.
QPSCurrent queries per second.
Quota StatusShows if the tenant is approaching their memory or storage limits.

Performance Introspection

The ADMIN.SLOWLOG command tracks queries that exceed the execution time threshold. Unlike general logging, this persists in a high-performance ring buffer for quick retrieval.

# Retrieve the last 10 slow queries
redis-cli ADMIN.SLOWLOG 10

Backup & Recovery

The ADMIN.BACKUP suite provides high-level control over the BackupEngine:

  • ADMIN.BACKUP CREATE: Triggers an immediate, synchronous snapshot of the database.
  • ADMIN.BACKUP LIST: Lists all available backups, their IDs, and timestamps.
  • ADMIN.BACKUP VERIFY [id]: Performs a checksum verification of a specific backup’s data files.
  • ADMIN.BACKUP RESTORE [id]: Restores the database to a previous state (requires a restart to finalize).
  • ADMIN.BACKUP DELETE [id]: Manually removes a backup file and its associated metadata.

Governance & Licensing

Every ADMIN.* call is logged to the Audit Trail. The system also uses these commands to interact with the LicenseManager:

  • ADMIN.LICENSE: Returns the details of the currently active license, including the expiry date and enabled features (e.g., gpu, monitoring, backup).

By integrating these controls into the RESP protocol, Samyama allows teams to build automated operational dashboards using their existing Redis-compatible tools and libraries.

Observability & Multi-tenancy

A database in production is a living organism. To keep it healthy, we need to see inside it, and to keep it secure, we need to isolate its users.

Multi-tenancy: Namespace Isolation (Enterprise)

Multi-tenancy is an Enterprise Edition feature. The Community Edition operates with a single "default" namespace — all data lives in one graph, which is simpler and perfectly adequate for single-application deployments.

The Enterprise Edition adds full multi-tenant capabilities: a Tenant Management HTTP API (CRUD + usage tracking), resource quotas, and namespace isolation via RocksDB Column Families.

Logical Separation with RocksDB (Enterprise)

graph TD
    subgraph "Samyama Enterprise Server"
        Router["Tenant Router"]
        Router --> TenantA["Tenant A<br>Quota: 1GB RAM, 10GB Disk"]
        Router --> TenantB["Tenant B<br>Quota: 2GB RAM, 50GB Disk"]
        Router --> TenantC["Tenant C<br>Quota: 512MB RAM, 5GB Disk"]
    end

    subgraph "RocksDB"
        TenantA --> CFA["Column Family: tenant_a<br>Independent compaction"]
        TenantB --> CFB["Column Family: tenant_b<br>Independent compaction"]
        TenantC --> CFC["Column Family: tenant_c<br>Independent compaction"]
    end

Enterprise leverages RocksDB’s Column Families (CF) for isolation. Each tenant is assigned their own CF.

  • Isolation: Tenant A’s keyspace is physically and logically distinct from Tenant B’s.
  • Maintenance: Compaction (the background cleanup process) happens per-tenant. If Tenant A is doing heavy writes, it won’t trigger a slow compaction for Tenant B.
  • Backup: We can snapshot and restore individual tenants without affecting others.
  • HTTP API: GET/POST/PATCH/DELETE /api/tenants for tenant lifecycle management; GET /api/tenants/:id/usage for resource tracking.

Resource Quotas (Enterprise)

To prevent the “Noisy Neighbor” problem, the Enterprise Edition enforces strict resource quotas per tenant:

  • Memory Quota: Max RAM for the in-memory graph.
  • Storage Quota: Max disk space in RocksDB.
  • Query Time: Max duration for a single Cypher query (to prevent “queries from hell” from locking the CPU).

Observability: The Three Pillars

We follow the industry-standard observability stack: Prometheus, OpenTelemetry (OTEL), and Structured Logging.

1. Metrics (Prometheus)

Samyama exports hundreds of metrics in the Prometheus format.

  • QPS: Queries per second (Read vs. Write).
  • Latency Histograms: P50, P95, and P99 response times.
  • Cache Hit Rates: How often we are hitting the in-memory graph versus going to RocksDB.

2. Structured Tracing

For complex queries, metrics aren’t enough. We need to know where the time was spent. Using the tracing crate in Rust, Samyama emits structured spans and events with timing data for every stage of query execution—parsing, planning, and execution. These spans can be collected and visualized using any tracing-compatible subscriber.

Note: Currently, Samyama uses tracing + tracing-subscriber for structured logging and span instrumentation. Full OpenTelemetry export (for visualization in Jaeger or Grafana Tempo) is on the roadmap for a future release.

3. Structured Logging

Gone are the days of parsing text logs. Samyama emits JSON logs.

{
  "timestamp": "2026-02-08T10:30:45Z",
  "level": "INFO",
  "query": "MATCH (n) RETURN n",
  "duration_ms": 12,
  "tenant": "acme_corp"
}

This allows for easy ingestion into ELK (Elasticsearch, Logstash, Kibana) or Loki for powerful log aggregation and searching.

By combining strong tenant isolation (Enterprise) with deep observability, Samyama provides a production-ready experience that allows operators to run massive multi-user clusters with confidence.

SDKs, CLI & API

Samyama provides a comprehensive developer ecosystem beyond the raw RESP and HTTP protocols. This chapter covers the official SDKs (Rust, Python, TypeScript), the command-line interface, and the OpenAPI specification.

Architecture Overview

graph TD
    subgraph "Client Layer"
        CLI["CLI (Rust + clap)"]
        RustSDK["Rust SDK"]
        PySDK["Python SDK (PyO3)"]
        TsSDK["TypeScript SDK (fetch)"]
    end

    subgraph "Transport"
        HTTP["HTTP API (:8080)"]
        Embedded["Embedded (in-process)"]
    end

    subgraph "Server"
        Engine["Query Engine + GraphStore"]
    end

    CLI --> RustSDK
    PySDK --> RustSDK
    RustSDK -- "RemoteClient" --> HTTP
    RustSDK -- "EmbeddedClient" --> Embedded
    TsSDK --> HTTP
    HTTP --> Engine
    Embedded --> Engine

All SDKs connect to the same engine—either over HTTP (remote) or directly in-process (embedded). The Rust SDK serves as the foundation: the CLI wraps it with a terminal interface, and the Python SDK wraps it via PyO3 FFI.

1. Rust SDK (samyama-sdk)

The Rust SDK is a workspace crate at crates/samyama-sdk/ that provides both embedded and remote access to the graph engine.

Core Trait: SamyamaClient

#![allow(unused)]
fn main() {
#[async_trait]
pub trait SamyamaClient: Send + Sync {
    async fn query(&self, graph: &str, cypher: &str) -> SamyamaResult<QueryResult>;
    async fn query_readonly(&self, graph: &str, cypher: &str) -> SamyamaResult<QueryResult>;
    async fn delete_graph(&self, graph: &str) -> SamyamaResult<()>;
    async fn list_graphs(&self) -> SamyamaResult<Vec<String>>;
    async fn status(&self) -> SamyamaResult<ServerStatus>;
    async fn ping(&self) -> SamyamaResult<String>;
}
}

EmbeddedClient — In-Process Access

For applications that want to embed Samyama directly (no network overhead):

#![allow(unused)]
fn main() {
use samyama_sdk::{EmbeddedClient, SamyamaClient};

// Create a fresh graph store
let client = EmbeddedClient::new();

// Or wrap an existing store
let client = EmbeddedClient::with_store(store.clone());

// Execute queries
let result = client.query("default", "CREATE (n:Person {name: 'Alice'})").await?;
let result = client.query_readonly("default", "MATCH (n:Person) RETURN n.name").await?;
}

The EmbeddedClient also provides factory methods for accessing subsystems:

MethodReturnsPurpose
nlq_pipeline(config)NLQPipelineNatural language query
agent_runtime(config)AgentRuntimeAgentic enrichment
persistence_manager(path)PersistenceManagerRocksDB persistence
tenant_manager()TenantManagerMulti-tenancy
store_read()RwLockReadGuard<GraphStore>Direct read access
store_write()RwLockWriteGuard<GraphStore>Direct write access

RemoteClient — HTTP Transport

For connecting to a running Samyama server:

#![allow(unused)]
fn main() {
use samyama_sdk::{RemoteClient, SamyamaClient};

let client = RemoteClient::new("http://localhost:8080");
let status = client.status().await?;
let result = client.query("default", "MATCH (n) RETURN count(n)").await?;
}

Extension Traits (EmbeddedClient Only)

AlgorithmClient provides direct access to graph algorithms without writing Cypher:

#![allow(unused)]
fn main() {
use samyama_sdk::AlgorithmClient;

let scores = client.page_rank(config, "Person", "KNOWS").await;
let components = client.weakly_connected_components("Person", "KNOWS").await;
let path = client.dijkstra(src, dst, "City", "ROAD", Some("distance")).await;
let pca_result = client.pca("Person", &["age", "income", "score"], config).await;
}

Available algorithm methods: page_rank, weakly_connected_components, strongly_connected_components, bfs, dijkstra, edmonds_karp, prim_mst, count_triangles, bfs_all_shortest_paths, cdlp, local_clustering_coefficient, pca.

VectorClient provides vector search operations:

#![allow(unused)]
fn main() {
use samyama_sdk::VectorClient;

client.create_vector_index("Document", "embedding", 384, "cosine").await?;
client.add_vector("Document", "embedding", node_id, vec![0.1, 0.2, ...]).await?;
let results = client.vector_search("Document", "embedding", query_vec, 10).await?;
}

SDK Data Models

#![allow(unused)]
fn main() {
pub struct QueryResult {
    pub nodes: Vec<SdkNode>,
    pub edges: Vec<SdkEdge>,
    pub columns: Vec<String>,
    pub records: Vec<Vec<Value>>,
}

pub struct ServerStatus {
    pub status: String,      // "healthy"
    pub version: String,     // "1.0.0"
    pub storage: StorageStats,
}
}

2. Command-Line Interface (CLI)

The CLI at cli/ is a Rust binary wrapping the Rust SDK with clap for argument parsing and comfy-table for formatted output.

Installation & Usage

# Build from source
cargo build --release -p samyama-cli

# Connect to a running server
samyama-cli --url http://localhost:8080 query "MATCH (n) RETURN count(n)"

# Output formats
samyama-cli --format table query "MATCH (n:Person) RETURN n.name, n.age"
samyama-cli --format json  query "MATCH (n:Person) RETURN n.name"
samyama-cli --format csv   query "MATCH (n:Person) RETURN n.name, n.age"

Subcommands

CommandDescription
query <cypher>Execute a Cypher query (--graph, --readonly flags)
statusGet server status (version, node/edge counts)
pingCheck server connectivity
shellStart an interactive REPL session

Interactive Shell

$ samyama-cli shell
samyama> MATCH (n:Person) RETURN n.name
+----------+
| n.name   |
+----------+
| Alice    |
| Bob      |
+----------+

samyama> :status
Status: healthy | Version: 1.0.0 | Nodes: 2000 | Edges: 11000

samyama> :help
samyama> :quit

Environment Variables

VariableDefaultDescription
SAMYAMA_URLhttp://localhost:8080Server URL

3. Python SDK (PyO3)

The Python SDK at sdk/python/ provides native Python bindings via PyO3, wrapping the Rust SDK as a compiled C extension (cdylib).

Usage

from samyama import SamyamaClient

# Embedded mode (in-process, no server needed)
client = SamyamaClient.embedded()

# Remote mode (connect to running server)
client = SamyamaClient.connect("http://localhost:8080")

# Execute queries
result = client.query("MATCH (n:Person) RETURN n.name")
print(result.columns)   # ['n.name']
print(result.records)    # [['Alice'], ['Bob']]
print(len(result))       # 2

# Server info
status = client.status()
print(status.version)    # '1.0.0'
print(status.nodes)      # 2000

Architecture

The Python SDK uses a shared tokio::Runtime (via OnceLock) to bridge Python’s synchronous API with the Rust SDK’s async internals. JSON serialization via serde_json handles the boundary between Rust types and Python objects.

4. TypeScript SDK

The TypeScript SDK at sdk/typescript/ is a standalone pure-TypeScript implementation using the browser/Node.js fetch API for HTTP transport. It does not wrap the Rust SDK.

Usage

import { SamyamaClient } from 'samyama-sdk';

const client = SamyamaClient.connectHttp('http://localhost:8080');

// Execute queries
const result = await client.query('MATCH (n:Person) RETURN n.name');
console.log(result.columns);  // ['n.name']
console.log(result.records);  // [['Alice'], ['Bob']]

// Server status
const status = await client.status();
console.log(status.version);  // '1.0.0'

5. OpenAPI Specification

The HTTP API is documented in api/openapi.yaml and provides two endpoints:

POST /api/query

Execute a Cypher query against the graph.

Request:

{ "query": "MATCH (n:Person) RETURN n.name, n.age LIMIT 10" }

Response:

{
  "nodes": [{ "id": "1", "labels": ["Person"], "properties": { "name": "Alice" } }],
  "edges": [],
  "columns": ["n.name", "n.age"],
  "records": [["Alice", 30], ["Bob", 25]]
}

GET /api/status

Get server health and statistics.

Response:

{
  "status": "healthy",
  "version": "1.0.0",
  "storage": { "nodes": 2000, "edges": 11000 }
}

SDK Capability Matrix

CapabilityRust (Embedded)Rust (Remote)PythonTypeScript
Cypher Queries
Server Status
Algorithm API
Vector Search API
NLQ Pipeline
Persistence Control
Multi-Tenancy

Developer Tip: All 10 domain-specific examples in the examples/ directory have been migrated to use the SDK’s EmbeddedClient, demonstrating real-world usage patterns for banking, clinical trials, supply chain, and more.

Ecosystem Architecture & Dependency Graph

This chapter maps the full Samyama ecosystem: repositories, modules, features, and knowledge graph projects — with dependency graphs showing how everything connects.


1. Repository Map

graph LR
    subgraph Public ["Public (GitHub)"]
        SG["samyama-graph<br/>(OSS engine)"]
        SI["samyama-insight<br/>(React frontend +<br/>book hosting at /book)"]
        CKG["cricket-kg"]
        CTKG["clinicaltrials-kg"]
    end

    subgraph Private ["Private"]
        SGE["samyama-graph-enterprise"]
        SC["samyama-cloud<br/>(book sources, wiki, deploy)"]
        SR["samyama-research<br/>(papers, reproductions)"]
        AOKG["assetops-kg"]
    end

    SG -->|"sync via PR"| SGE
    SG -->|"Python SDK"| CKG
    SG -->|"Python SDK"| CTKG
    SG -->|"Python SDK"| AOKG
    SG -->|"TS SDK"| SI
    SGE -->|"deploy scripts"| SC
    SC -->|"mdBook build → public/book-static/"| SI
    SR -.->|"published PDFs"| SI

    style SG fill:#4a9eff,stroke:#333,color:#fff
    style SGE fill:#ff6b6b,stroke:#333,color:#fff
    style SI fill:#51cf66,stroke:#333,color:#fff
    style SC fill:#ffd43b,stroke:#333
    style SR fill:#ffd43b,stroke:#333
    style CKG fill:#b197fc,stroke:#333,color:#fff
    style CTKG fill:#b197fc,stroke:#333,color:#fff
    style AOKG fill:#b197fc,stroke:#333,color:#fff
RepositoryVisibilityPurpose
samyama-graphPublicRust graph DB engine (OSS)
samyama-graph-enterprisePrivateEnterprise features (GPU, monitoring, backup, licensing)
samyama-cloudPrivateBook sources, wiki, deployment configs, backlog
samyama-researchPrivateAcademic paper sources, reviewer feedback, reproduction artifacts
samyama-insightPublicReact + Vite frontend; also hosts the book at /book (built mdBook output served as static assets)
cricket-kgPublicCricket knowledge graph (Cricsheet data)
clinicaltrials-kgPublicClinical trials KG (ClinicalTrials.gov / AACT data)
assetops-kgPrivateAsset operations KG (industrial IoT data)

Ecosystem in Action

Graph Simulation — Cricket KG (36K nodes, 1.4M edges) with live activity particles

Samyama Graph Simulation

Click for full demo (1:56) — Dashboard, Cypher Queries, and Graph Simulation


2. samyama-graph Module Architecture

The OSS engine is organized into 7 core modules, 3 workspace crates, and 3 SDK packages.

graph TB
    subgraph "SDK Layer"
        PYSDK["sdk/python<br/>samyama (PyO3)"]
        MCP["sdk/python<br/>samyama_mcp"]
        TSSDK["sdk/typescript<br/>samyama-sdk"]
    end

    subgraph "Crates"
        SDK["crates/samyama-sdk<br/>EmbeddedClient + RemoteClient"]
        ALGO["crates/samyama-graph-algorithms<br/>PageRank, WCC, SCC, BFS, etc."]
        OPT["crates/samyama-optimization<br/>Rao-family + classical metaheuristics"]
    end

    subgraph CLI
        CLIRS["cli/<br/>query, status, shell"]
    end

    subgraph "Core Engine (src/)"
        QUERY["query/<br/>parser (Pest) + planner + executor"]
        GRAPH["graph/<br/>store, node, edge, property, catalog"]
        PROTO["protocol/<br/>RESP server + HTTP API"]
        PERSIST["persistence/<br/>RocksDB, WAL, tenant"]
        RAFT["raft/<br/>openraft consensus"]
        NLQ["nlq/<br/>text-to-Cypher (multi-provider)"]
        AGENT["agent/<br/>GAK runtime + tools"]
        VECTOR["vector/<br/>HNSW index"]
        SHARD["sharding/<br/>tenant-level routing"]
    end

    %% SDK dependencies
    PYSDK --> SDK
    MCP --> PYSDK
    TSSDK -->|"HTTP fetch"| PROTO
    CLIRS --> SDK

    %% Crate dependencies
    SDK --> QUERY
    SDK --> GRAPH
    SDK --> PERSIST
    SDK --> ALGO
    SDK --> OPT
    SDK --> NLQ
    SDK --> AGENT
    SDK --> VECTOR

    %% Core module dependencies
    QUERY --> GRAPH
    PROTO --> QUERY
    PROTO --> GRAPH
    PERSIST --> GRAPH
    RAFT --> PERSIST
    NLQ --> QUERY
    AGENT --> NLQ
    VECTOR --> GRAPH
    SHARD --> PERSIST
    ALGO --> GRAPH

    style QUERY fill:#4a9eff,stroke:#333,color:#fff
    style GRAPH fill:#51cf66,stroke:#333,color:#fff
    style PROTO fill:#ffd43b,stroke:#333
    style SDK fill:#ff6b6b,stroke:#333,color:#fff
    style MCP fill:#b197fc,stroke:#333,color:#fff
    style PYSDK fill:#b197fc,stroke:#333,color:#fff

Module Responsibilities

ModuleKey TypesEntry Points
graph/GraphStore, Node, Edge, PropertyValue, GraphCatalogIn-memory storage, O(1) lookups, sorted adjacency lists
query/QueryExecutor, MutQueryExecutor, PhysicalOperatorPest parser → AST → logical plan → physical plan → Volcano iterator
protocol/RespServer, HttpServer, CommandHandlerRESP on :6379, HTTP on :8080
persistence/StorageEngine, WAL, TenantManagerRocksDB column families, per-tenant isolation
raft/RaftNode, GraphStateMachine, ClusterManageropenraft-based leader election + log replication
nlq/NLQPipeline, NLQClient, LLMProvidertext → schema-aware prompt → LLM → Cypher extraction
agent/AgentRuntime, Tool trait, AgentConfigGAK: query gap → enrichment prompt → LLM → Cypher → ingest
vector/HnswIndex, VectorSearchHNSW with cosine/L2/inner-product, bincode persistence
crates/samyama-sdkSamyamaClient, EmbeddedClient, RemoteClientAsync trait with extension traits (AlgorithmClient, VectorClient)
crates/samyama-graph-algorithmsGraphView (CSR), PageRank, WCC, SCC, BFS, DijkstraBuild CSR projection → run algorithm → return results
crates/samyama-optimizationSolver trait, GA, PSO, SA, ACO, etc.15 solvers with or.solve() Cypher procedure
sdk/python/samyamaSamyamaClient (PyO3).embedded() / .connect(url) factory methods
sdk/python/samyama_mcpSamyamaMCPServer, generators, schema discoveryAuto-generate MCP tools from graph schema
sdk/typescriptSamyamaClient classPure TS with fetch, .connectHttp() factory

3. Enterprise Feature Layering (OSS → SGE)

graph TB
    subgraph OSS ["samyama-graph (OSS — Apache 2.0)"]
        QE["Query Engine<br/>~90% OpenCypher"]
        PS["Persistence<br/>RocksDB + WAL"]
        MT["Multi-Tenancy"]
        VS["Vector Search<br/>HNSW"]
        GA["Graph Algorithms<br/>PageRank, WCC, BFS..."]
        NQ["NLQ<br/>text-to-Cypher"]
        HV["HTTP Visualizer"]
        RF["Raft Consensus<br/>(basic)"]
        MO["Metaheuristic<br/>Optimization"]
        RDF["RDF / SPARQL<br/>(infrastructure)"]
    end

    subgraph SGE ["samyama-graph-enterprise (Proprietary)"]
        MON["Prometheus /metrics"]
        HC["Health Checks"]
        BK["Backup & Restore<br/>(PITR)"]
        AU["Audit Trail"]
        SQ["Slow Query Log"]
        ADM["ADMIN.* Commands"]
        ERF["Enhanced Raft<br/>(HTTP transport)"]
        GPU["GPU Acceleration<br/>(wgpu shaders)"]
        LIC["JET Licensing<br/>(Ed25519 signed)"]
    end

    SGE -->|"inherits all of"| OSS

    GPU -->|"accelerates"| GA
    GPU -->|"accelerates"| VS
    MON -->|"observes"| QE
    BK -->|"snapshots"| PS
    AU -->|"logs"| QE
    LIC -->|"gates"| SGE

    style OSS fill:#e8f5e9,stroke:#2e7d32
    style SGE fill:#fce4ec,stroke:#c62828

For the full feature-by-feature comparison between Community and Enterprise editions, see the Enterprise Edition Overview.


4. Knowledge Graph Projects

All KG projects share the same stack: Python SDK → samyama-mcp-serve → custom config.

graph TB
    subgraph Engine ["Samyama Engine"]
        SG["samyama-graph<br/>(Rust)"]
        PYSDK["samyama<br/>(Python SDK / PyO3)"]
        MCPSERVE["samyama_mcp<br/>(MCP serve)"]
    end

    subgraph KGs ["Knowledge Graph Projects"]
        subgraph CKG ["cricket-kg"]
            CETL["etl/loader.py<br/>(Cricsheet JSON)"]
            CMCP["mcp_server/<br/>config.yaml (12 custom)"]
            CTEST["tests/<br/>25 MCP tests"]
        end

        subgraph CTKG ["clinicaltrials-kg"]
            CTETL["etl/loader.py<br/>(API or AACT flat files)"]
            CTMCP["mcp_server/<br/>16 tools (hand-written)"]
            CTAACT["etl/aact_loader.py<br/>(500K+ studies)"]
        end

        subgraph AOKG ["assetops-kg"]
            AOETL["etl/loader.py"]
            AOMCP["mcp_server/<br/>9 tools"]
        end
    end

    SG --> PYSDK
    PYSDK --> MCPSERVE
    MCPSERVE --> CMCP
    MCPSERVE -.->|"SK-14: migrate"| CTMCP
    MCPSERVE -.->|"SK-15: migrate"| AOMCP
    PYSDK --> CETL
    PYSDK --> CTETL
    PYSDK --> CTAACT
    PYSDK --> AOETL

    style SG fill:#4a9eff,stroke:#333,color:#fff
    style MCPSERVE fill:#b197fc,stroke:#333,color:#fff
    style CKG fill:#d0f0c0,stroke:#2e7d32
    style CTKG fill:#ffe0b2,stroke:#e65100
    style AOKG fill:#e1bee7,stroke:#6a1b9a

KG Schema Summary

KGNode LabelsEdge TypesData SourceData Volume
cricket-kg6 (Player, Match, Team, Venue, Tournament, Season)12Cricsheet JSON~100-500 matches
clinicaltrials-kg15 (ClinicalTrial, Condition, Intervention, Sponsor, Site, …)25ClinicalTrials.gov API or AACT flat files~500K+ studies
assetops-kg8 (Asset, Component, FailureMode, MaintenanceRecord, …)11Industrial IoT dataDomain-specific

5. Feature Dependency Graph (Backlog)

The complete feature dependency chain across all backlog items. Green = done, blue = in progress, white = planned.

graph TB
    subgraph "Query Engine (Done ✅)"
        QE01["QE-01<br/>Parameterized $param"]
        QE02["QE-02<br/>PROFILE stats"]
        QE03["QE-03<br/>shortestPath()"]
        QE07["QE-07<br/>CALL procedures"]
    end

    subgraph "Cypher Completeness (Done ✅)"
        CY01["CY-01<br/>collect(DISTINCT)"]
        CY02["CY-02<br/>datetime args"]
        CY04["CY-04<br/>Named paths"]
        CY05["CY-05<br/>Path functions"]
    end

    subgraph "Planner / Optimizer (Done ✅)"
        QP01["QP-01 Predicate pushdown"]
        QP02["QP-02 Cost-based"]
        QP05["QP-05 Plan cache"]
        QP11["QP-11 Graph-native enum"]
        QP12["QP-12 Triple stats"]
        QP13["QP-13 ExpandInto"]
        QP14["QP-14 Direction reversal"]
        QP15["QP-15 Logical plan IR"]
    end

    subgraph "Planner (Planned)"
        QP06["QP-06<br/>Histogram stats"]
        QP09["QP-09<br/>Operator fusion"]
        QP10["QP-10<br/>Adaptive exec"]
    end

    subgraph "Indexes (Done ✅)"
        IX01["IX-01..06<br/>DROP/SHOW/Composite/Unique"]
    end

    subgraph "Indexes (Planned)"
        IX07["IX-07<br/>Full-text index"]
        IX08["IX-08<br/>OR union scans"]
    end

    subgraph "Performance (Done ✅)"
        PF01["PF-01 CSR"]
        PF04["PF-04 Late materialization"]
        PF06["PF-06 AST cache"]
    end

    subgraph "Performance (Planned)"
        PF07["PF-07<br/>MVCC"]
        PF09["PF-09<br/>WCO joins"]
        PF10["PF-10<br/>Parallel exec"]
    end

    subgraph "Data Structures (Done ✅)"
        DS01["DS-01 Triple stats"]
        DS02["DS-02 Sorted adjacency"]
    end

    subgraph "Data Structures (Planned)"
        DS03["DS-03<br/>Type-partitioned adj"]
    end

    subgraph "SDK / MCP (Done ✅)"
        SK01["SK-01..06<br/>Rust/Python/TS SDK + CLI"]
        SK09["SK-09 npm publish"]
        SK10["SK-10 EXPLAIN/PROFILE"]
        SK11["SK-11 Schema/Stats"]
        SK12["SK-12<br/>samyama-mcp-serve"]
        SK13["SK-13<br/>cricket-kg MCP"]
    end

    subgraph "SDK (Planned)"
        SK14["SK-14<br/>clinicaltrials MCP"]
        SK15["SK-15<br/>assetops MCP"]
    end

    subgraph "HA (Done ✅)"
        HA01["HA-01 Raft"]
        HA02["HA-02 Sharding"]
        HA03["HA-03 Vector persist"]
    end

    subgraph "HA (Planned)"
        HA04["HA-04<br/>Temporal queries"]
        HA05["HA-05<br/>Graph sharding"]
        HA06["HA-06<br/>Distributed exec"]
    end

    subgraph "AI (Done ✅)"
        AI01["AI-01 GAK runtime"]
        AI02["AI-02 NLQ"]
        AI03["AI-03 Auto-embed"]
    end

    subgraph "AI / JIT KG (Planned)"
        AI07["AI-07<br/>Enterprise connectors"]
        AI08["AI-08<br/>Demand-driven agent"]
        AI09["AI-09<br/>Text-to-SQL bridge"]
        AI10["AI-10<br/>JIT KG demo"]
    end

    subgraph "GPU (Done ✅)"
        GP01["GP-01..10<br/>PageRank, CDLP, LCC,<br/>PCA, triangles, vectors,<br/>aggregates, sort"]
    end

    subgraph "Benchmarks (Done ✅)"
        BM01["BM-01..03<br/>Graphalytics, SNB, FinBench"]
    end

    subgraph "Benchmarks (Planned)"
        BM04["BM-04<br/>SF10 scale"]
        BM05["BM-05<br/>SNB BI tuning"]
        BM07["BM-07<br/>Comparative bench"]
    end

    subgraph "Visualizer (Done ✅)"
        VZ01["VZ-01..05<br/>Plan DAG, PROFILE,<br/>Stats, Console, Features"]
        VZ07["VZ-07..10<br/>Schema, CSV/JSON Import, E2E"]
    end

    subgraph "KG Projects"
        KG01["KG-01<br/>AACT full loader<br/>(in progress)"]
    end

    %% Dependencies
    CY01 & CY02 & QE03 & CY04 --> BM05
    CY04 --> CY05
    PF06 --> QP05
    QP01 & QP02 --> BM04
    PF07 --> HA04
    DS02 --> PF09
    HA05 --> HA06
    QE01 --> QP11
    QP12 --> QP11
    DS02 --> QP13
    QP14 --> QP11
    QP15 --> QP11
    SK09 --> VZ01
    SK10 --> VZ01
    SK11 --> VZ07
    QE07 --> VZ07
    SK12 --> SK13
    SK12 --> SK14
    SK12 --> SK15

    %% JIT KG chain
    AI01 --> AI07
    AI02 --> AI07
    SK12 --> AI07
    AI02 --> AI09
    AI07 --> AI08
    AI09 --> AI08
    AI08 --> AI10

    %% KG-01
    IX01 --> KG01

    %% Benchmark deps
    BM07 -.-> BM05

    style QE01 fill:#51cf66,stroke:#333,color:#fff
    style QE02 fill:#51cf66,stroke:#333,color:#fff
    style QE03 fill:#51cf66,stroke:#333,color:#fff
    style QE07 fill:#51cf66,stroke:#333,color:#fff
    style CY01 fill:#51cf66,stroke:#333,color:#fff
    style CY02 fill:#51cf66,stroke:#333,color:#fff
    style CY04 fill:#51cf66,stroke:#333,color:#fff
    style CY05 fill:#51cf66,stroke:#333,color:#fff
    style QP01 fill:#51cf66,stroke:#333,color:#fff
    style QP02 fill:#51cf66,stroke:#333,color:#fff
    style QP05 fill:#51cf66,stroke:#333,color:#fff
    style QP11 fill:#51cf66,stroke:#333,color:#fff
    style QP12 fill:#51cf66,stroke:#333,color:#fff
    style QP13 fill:#51cf66,stroke:#333,color:#fff
    style QP14 fill:#51cf66,stroke:#333,color:#fff
    style QP15 fill:#51cf66,stroke:#333,color:#fff
    style IX01 fill:#51cf66,stroke:#333,color:#fff
    style PF01 fill:#51cf66,stroke:#333,color:#fff
    style PF04 fill:#51cf66,stroke:#333,color:#fff
    style PF06 fill:#51cf66,stroke:#333,color:#fff
    style DS01 fill:#51cf66,stroke:#333,color:#fff
    style DS02 fill:#51cf66,stroke:#333,color:#fff
    style SK01 fill:#51cf66,stroke:#333,color:#fff
    style SK09 fill:#51cf66,stroke:#333,color:#fff
    style SK10 fill:#51cf66,stroke:#333,color:#fff
    style SK11 fill:#51cf66,stroke:#333,color:#fff
    style SK12 fill:#51cf66,stroke:#333,color:#fff
    style SK13 fill:#51cf66,stroke:#333,color:#fff
    style HA01 fill:#51cf66,stroke:#333,color:#fff
    style HA02 fill:#51cf66,stroke:#333,color:#fff
    style HA03 fill:#51cf66,stroke:#333,color:#fff
    style AI01 fill:#51cf66,stroke:#333,color:#fff
    style AI02 fill:#51cf66,stroke:#333,color:#fff
    style AI03 fill:#51cf66,stroke:#333,color:#fff
    style GP01 fill:#51cf66,stroke:#333,color:#fff
    style BM01 fill:#51cf66,stroke:#333,color:#fff
    style VZ01 fill:#51cf66,stroke:#333,color:#fff
    style VZ07 fill:#51cf66,stroke:#333,color:#fff
    style KG01 fill:#4a9eff,stroke:#333,color:#fff
    style AI07 fill:#fff,stroke:#333
    style AI08 fill:#fff,stroke:#333
    style AI09 fill:#fff,stroke:#333
    style AI10 fill:#fff,stroke:#333

6. Data Flow: Query → Enrichment → Response

This diagram shows the runtime data flow for a JIT KG query, incorporating the planned AI-07..AI-10 features.

sequenceDiagram
    participant U as User / Agent
    participant MCP as MCP Server
    participant NLQ as NLQ Pipeline
    participant QE as Query Engine
    participant GS as GraphStore
    participant AG as GAK Agent
    participant SRC as Enterprise Source<br/>(OneDrive / OLTP)

    U->>MCP: Natural language question
    MCP->>NLQ: text_to_cypher(question, schema)
    NLQ->>QE: MATCH (n:Person)-[:AUTHORED]->(d:Document)...
    QE->>GS: Execute query
    GS-->>QE: 0 results (gap detected)
    QE-->>MCP: Empty result set

    Note over MCP,AG: AI-08: Demand-driven enrichment triggers

    MCP->>AG: process_trigger(gap_context)
    AG->>SRC: AI-07: Pull from OneDrive (documents)
    SRC-->>AG: Document metadata + content
    AG->>NLQ: Extract entities (LLM)
    NLQ-->>AG: Cypher: CREATE (p:Person)..., CREATE (d:Document)...
    AG->>QE: Execute enrichment Cypher
    QE->>GS: MERGE nodes + edges

    AG->>SRC: AI-09: text-to-SQL (OLTP database)
    SRC-->>AG: Relational rows
    AG->>NLQ: Transform to graph entities (LLM)
    NLQ-->>AG: Cypher: CREATE (proj:Project)...
    AG->>QE: Execute enrichment Cypher
    QE->>GS: MERGE nodes + edges

    Note over MCP,GS: Graph enriched — re-execute original query

    MCP->>QE: Re-execute original Cypher
    QE->>GS: Execute query
    GS-->>QE: Results (populated)
    QE-->>MCP: Result set
    MCP-->>U: Answer with graph context

7. Deployment Architecture

graph TB
    subgraph "Samyama Server"
        SGE_BIN["samyama-graph<br/>(release binary)"]
        ROCKS["RocksDB<br/>(persistent storage)"]
        SI_DIST["samyama-insight<br/>(static dist/)"]
    end

    subgraph "Developer Workflow"
        SG_DEV["samyama-graph<br/>(cargo build)"]
        PY_DEV["Python SDK<br/>(maturin develop)"]
        KG_DEV["KG projects<br/>(python -m etl.loader)"]
    end

    subgraph "External Services"
        LLM["LLM Provider<br/>(OpenAI / Claude / Ollama)"]
    end

    SGE_BIN -->|":6379 RESP"| ROCKS
    SGE_BIN -->|":8080 HTTP"| SI_DIST
    SG_DEV -->|"sync via PR"| SGE_BIN
    SG_DEV --> PY_DEV --> KG_DEV
    SGE_BIN -->|"NLQ / GAK"| LLM

    style SGE_BIN fill:#ff6b6b,stroke:#333,color:#fff
    style SG_DEV fill:#4a9eff,stroke:#333,color:#fff

8. Version Sync Points

All packages must stay version-aligned. These are the 13 files that must be updated together on a version bump (Step 0.5 in the workflow):

graph LR
    V["Version<br/>v1.0.0"]

    V --> CT["Cargo.toml<br/>(root)"]
    V --> CLI["cli/Cargo.toml"]
    V --> SDKRS["crates/samyama-sdk/<br/>Cargo.toml"]
    V --> OPTC["crates/samyama-optimization/<br/>Cargo.toml"]
    V --> ALGOC["crates/samyama-graph-algorithms/<br/>Cargo.toml"]
    V --> PYC["sdk/python/Cargo.toml"]
    V --> PYP["sdk/python/pyproject.toml"]
    V --> TSP["sdk/typescript/package.json"]
    V --> TSL["sdk/typescript/package-lock.json"]
    V --> API["api/openapi.yaml"]
    V --> LIB["src/lib.rs<br/>(test_version)"]
    V --> CMD["CLAUDE.md"]

    style V fill:#ffd43b,stroke:#333

9. Technology Stack

LayerTechnologyPurpose
LanguageRust (2021 edition)Core engine, persistence, protocol
ParserPest (PEG)OpenCypher grammar → AST
StorageRocksDBPersistent key-value with column families
ConsensusopenraftRaft leader election + log replication
Vector IndexCustom HNSWApproximate nearest neighbor search
GPUwgpu + WGSL shadersGPU-accelerated algorithms (enterprise)
Python SDKPyO3 0.22 + maturinRust → Python FFI binding
MCP FrameworkFastMCP v2Model Context Protocol stdio server
TypeScript SDKPure TS + fetchHTTP client for browser/Node.js
FrontendReact + Vite + shadcn/uiInteractive dashboard (samyama-insight)
E2E TestingPlaywrightBrowser-based end-to-end tests
BenchmarksCriterionRust micro-benchmarks (10 suites)
CI/CDGitHub ActionsAutomated builds, tests, sync
LicensingEd25519 (JET tokens)Cryptographic feature gating
LLM IntegrationOpenAI, Claude, Gemini, OllamaNLQ + Agentic enrichment

The Future of Graph DBs

The rest of this book describes what Samyama is today: a single-server graph database with MVCC isolation, OpenCypher and SPARQL frontends, GPU-accelerated analytics, vector search, and a 500/500-pass mega-benchmark across 11 federated knowledge graphs. This chapter is about where it goes next — frontier directions that build on that foundation.

1. Time-Travel Queries (Temporal Graphs)

Data is not static; it flows. Current graph databases only show the current state.

We plan to expose our internal MVCC versions to the user. Goal: Allow queries like:

MATCH (p:Person)-[:KNOWS]->(f:Person)
WHERE p.name = 'Alice'
AT TIME '2023-01-01' -- Query the graph as it looked last year
RETURN f.name

This is invaluable for auditing, debugging, and historical analysis.

2. Graph-Level Sharding

Currently, we shard by Tenant. This is perfect for SaaS but limits the size of a single graph to one machine’s capacity (vertical scaling).

The Challenge: Partitioning a single graph across multiple machines is the “Holy Grail” of graph databases. It introduces the “Min-Cut” problem (minimizing edges that cross machines) to reduce network latency.

The Plan: We are investigating METIS and streaming partitioning algorithms to intelligently distribute nodes based on community structure, ensuring that “friends stay together” on the same physical server.

3. Distributed Query Execution (Scatter-Gather)

To complement Graph-Level Sharding, the query engine must evolve from a single-node vectorized iterator to a distributed execution framework.

  • Query Coordinator: Will partition the physical plan into sub-plans.
  • Workers: Execute local traversals.
  • Shuffle/Exchange Operators: Pass intermediate RecordBatch streams across the network using Arrow Flight RPC.

4. PROFILE (Runtime Statistics)

While EXPLAIN shows the plan, PROFILE will show the reality—executing the query and collecting actual row counts and operator-level timing. This will complement cost-based optimization with empirical feedback.

5. Native Graph Neural Networks (GNNs)

While we currently support powerful vector search (HNSW) and metaheuristic optimization, the next step in “predictive power” is natively training and serving Graph Neural Networks directly within the database.

  • Goal: Run CALL algo.gnn.predict_link('Person', 'KNOWS') without exporting data to Python and PyTorch Geometric.

Full Backlog

The items above are highlights. The complete prioritized backlog with ~100 items across 13 categories is maintained in samyama-cloud/docs/BACKLOG.md. Key backlog IDs referenced in this chapter:

TopicBacklog IDs
Temporal queriesHA-04
Graph-level shardingHA-05
Distributed query executionHA-06
PROFILE runtime statsQE-02
GNN inferenceAI-04, AI-05
Query planner improvementsQP-01 through QP-10
Cypher completeness gapsCY-01 through CY-10

Conclusion

Samyama started as a question: “Can we do better?” The answer, we believe, is “Yes.”

By fusing the transactional integrity of RocksDB, the safety of Rust, the massive parallelism of GPU compute shaders, and the semantic power of AI, we are building a database engine for the next decade of intelligent applications.

Thank you for exploring the architecture of Samyama with us.

Frequently Asked Questions

This FAQ covers common questions about Samyama’s architecture, usage, and capabilities. Use your browser’s search (Ctrl+F / Cmd+F) or the mdBook search bar to quickly find answers.


Getting Started

How do I install and run Samyama?

# Clone and build
git clone https://github.com/samyama-ai/samyama-graph.git
cd samyama-graph
cargo build --release

# Start the server (RESP on :6379, HTTP on :8080)
cargo run --release

# Run a demo
cargo run --example banking_demo

What protocols does Samyama support? Is it Postgres wire protocol?

No, Samyama does not use the Postgres wire protocol. It exposes two protocols:

  • RESP (Redis Protocol) on port 6379 — use any Redis client (redis-cli, Jedis, ioredis, etc.)
  • HTTP API on port 8080 — RESTful endpoints for queries and status

We chose RESP over Postgres wire protocol because: (1) RESP is simpler and faster (binary protocol, minimal framing overhead), (2) it enables drop-in compatibility with the RedisGraph ecosystem (which was sunset by Redis Ltd), and (3) graph queries are fundamentally different from SQL — we didn’t want to shoehorn Cypher into a SQL-shaped protocol.

Example using redis-cli:

redis-cli GRAPH.QUERY default "CREATE (n:Person {name: 'Alice', age: 30})"
redis-cli GRAPH.QUERY default "MATCH (n:Person) RETURN n.name, n.age"

Example using HTTP:

curl -s -X POST http://localhost:8080/api/query \
  -d '{"query": "MATCH (n) RETURN count(n)", "graph": "default"}'

curl -s http://localhost:8080/api/status | python3 -m json.tool

See the SDKs, CLI & API chapter.

What query language does Samyama use?

Samyama supports OpenCypher with ~90% coverage. Supported clauses: MATCH, OPTIONAL MATCH, CREATE, DELETE, SET, REMOVE, MERGE, WITH, UNWIND, UNION, RETURN DISTINCT, ORDER BY, SKIP, LIMIT, EXPLAIN, EXISTS subqueries.

Example — create a small social graph and query it:

CREATE (a:Person {name: 'Alice', age: 30})-[:KNOWS]->(b:Person {name: 'Bob', age: 25})
CREATE (b)-[:KNOWS]->(c:Person {name: 'Charlie', age: 35})

MATCH (p:Person)-[:KNOWS]->(friend)
WHERE p.age > 28
RETURN p.name, friend.name

See the Query Engine chapter.

What are the minimum system requirements?

Samyama runs on any system with a Rust 1.83+ toolchain:

  • CPU: Any x86_64 or ARM64 (M-series Macs fully supported)
  • RAM: 512MB minimum; 4GB+ recommended for production
  • Disk: Depends on data size; RocksDB with LZ4 compression is space-efficient
  • GPU (Enterprise only): Any Metal, Vulkan, or DX12-compatible GPU

What is the difference between Community and Enterprise?

Community (OSS)Enterprise
LicenseApache 2.0Commercial (JET token)
Core Engine✅ Full✅ Full
Multi-TenancySingle namespace (default)Tenant CRUD API, quotas, isolation
MonitoringLogging onlyPrometheus, health checks, audit trail
BackupWAL onlyFull/incremental backup, PITR
HABasic RaftHTTP/2 transport, snapshot streaming
GPU✅ (wgpu: Metal, Vulkan, DX12)

See the Enterprise Edition chapter for full details.


Query Engine

What Cypher features are NOT yet supported?

Remaining gaps: list slicing ([1..3]) and pattern comprehensions. The Future Roadmap tracks planned additions.

Added in v0.6.0: Named paths (p = (a)-[]->(b)), CASE expressions, collect(DISTINCT x), datetime({year: 2026, month: 3}) constructor, parameterized queries ($param), and PROFILE.

-- Named paths (v0.6.0):
MATCH p = (a:Person)-[:KNOWS]->(b:Person) RETURN p, length(p)

-- CASE expressions (v0.6.0):
MATCH (n:Person) RETURN n.name, CASE WHEN n.age > 30 THEN 'senior' ELSE 'junior' END AS category

-- collect(DISTINCT x) (v0.6.0):
MATCH (n:Person)-[:LIVES_IN]->(c:City) RETURN collect(DISTINCT c.name) AS cities

-- Parameterized queries (v0.6.0):
MATCH (n:Person {age: $age}) RETURN n

How do I check if my query is using an index?

Use EXPLAIN before your query:

EXPLAIN MATCH (n:Person {name: 'Alice'}) RETURN n

If you see IndexScanOperator in the output, the index is being used. If you see NodeScanOperator, the query is doing a full label scan — consider creating an index:

-- Before: full scan (slow on large graphs)
EXPLAIN MATCH (n:Person) WHERE n.name = 'Alice' RETURN n
-- Output: NodeScanOperator(Person) → FilterOperator(n.name = 'Alice')

-- Create the index:
CREATE INDEX ON :Person(name)

-- After: index scan (fast O(log n))
EXPLAIN MATCH (n:Person) WHERE n.name = 'Alice' RETURN n
-- Output: IndexScanOperator(Person.name = 'Alice')

See the Query Optimization chapter.

Can I use EXPLAIN to see estimated costs?

Yes. EXPLAIN returns the operator tree with estimated row counts and graph statistics (label counts, edge type counts, property selectivity):

EXPLAIN MATCH (a:Person)-[:KNOWS]->(b:Person)
WHERE a.age > 25
RETURN a.name, b.name

Output includes:

ProjectOperator [a.name, b.name]
  └── FilterOperator [a.age > 25]
        └── ExpandOperator [KNOWS]
              └── NodeScanOperator [Person]
--- Statistics ---
  Person: 10,000 nodes
  KNOWS: 45,000 edges
  avg_out_degree: 4.5

PROFILE (with actual execution timing and row counts per operator) is supported since v0.6.0:

PROFILE MATCH (a:Person)-[:KNOWS]->(b:Person)
WHERE a.age > 25
RETURN a.name, b.name

How many physical operators does the engine have?

33 operators covering scan, traversal, filter, join, aggregation, sort, write, index, constraint, and specialized operations. See the operator table.

Does Samyama support transactions?

Samyama provides per-query atomicity via RocksDB WriteBatch + WAL. Each write query (CREATE, DELETE, SET, MERGE) executes as an atomic unit — either all changes commit or none do.

-- This entire query is atomic — both nodes and the edge are created together:
CREATE (a:Account {id: 'A1', balance: 1000})-[:TRANSFER {amount: 500}]->(b:Account {id: 'A2', balance: 2000})

Interactive BEGIN...COMMIT transactions (spanning multiple queries) are on the roadmap. See the ACID Guarantees section.


Indexes & Data Access

What types of indexes does Samyama support?

Samyama provides four index types:

Index TypeData StructurePurposeCreated By
Property IndexBTreeMap<PropertyValue, HashSet<NodeId>>Fast property lookups and range scansCREATE INDEX
Label IndexHashMap<Label, HashSet<NodeId>>Fast label-based node retrievalAutomatic (built-in)
Edge Type IndexHashMap<EdgeType, HashSet<EdgeId>>Fast edge type lookupsAutomatic (built-in)
Vector IndexHNSW (Hierarchical Navigable Small World)Approximate nearest neighbor searchCREATE VECTOR INDEX

How do property indexes work?

Property indexes use a B-tree (BTreeMap) that maps property values to sets of node IDs. This gives O(log n) lookups for both exact matches and range queries.

Creating a property index:

CREATE INDEX ON :Person(name)
CREATE INDEX ON :Person(age)
CREATE INDEX ON :Transaction(amount)

How it’s used — the planner automatically selects an index scan when a WHERE predicate matches an indexed property:

-- Exact match → index lookup, returns matching NodeIds directly
MATCH (n:Person) WHERE n.name = 'Alice' RETURN n

-- Range query → B-tree range scan
MATCH (n:Person) WHERE n.age > 25 RETURN n.name, n.age

-- Supported comparison operators: =, >, >=, <, <=
MATCH (t:Transaction) WHERE t.amount >= 10000 RETURN t

Performance characteristics:

OperationComplexity
Exact match (=)O(log n)
Range query (>, >=, <, <=)O(log n + k) where k = results
Insert (on node create/update)O(log n)
Remove (on node delete/update)O(log n)

Composite indexes (v0.6.0): Multi-property indexes are supported — CREATE INDEX ON :Person(firstName, lastName) creates a composite index used when both properties appear in a WHERE clause.

How do the built-in label and edge type indexes work?

These are automatic indexes maintained internally — you don’t create or manage them.

Label index — maps each label to all nodes with that label:

-- Uses label_index internally to find all Person nodes in O(1)
MATCH (n:Person) RETURN n

-- Statistics show label cardinality:
EXPLAIN MATCH (n:Person) RETURN n
-- Output: NodeScanOperator [Person] (est. 10,000 rows)

Edge type index — maps each edge type to all edges of that type:

-- Uses edge_type_index to find all KNOWS edges
MATCH ()-[r:KNOWS]->() RETURN count(r)

Both indexes use HashMap<Key, HashSet<Id>> for O(1) lookup by label/type and O(m) iteration over all matching entities.

How do vector indexes work?

Vector indexes use HNSW (Hierarchical Navigable Small World) for approximate nearest neighbor search, powered by the hnsw_rs crate.

Creating a vector index:

CREATE VECTOR INDEX embedding_idx
FOR (d:Document) ON (d.embedding)
OPTIONS {dimensions: 768, similarity: 'cosine'}

Supported distance metrics:

MetricBest ForFormula
cosineText embeddings, normalized vectors1.0 - cos(a, b)
l2Spatial data, raw feature vectorssqrt(sum((a_i - b_i)^2))
dot_productPre-normalized embeddings1.0 - dot(a, b)

Querying:

-- Find the 5 documents most similar to a query vector
CALL db.index.vector.queryNodes('Document', 'embedding', [0.12, -0.34, ...], 5)
YIELD node, score
RETURN node.title, score

HNSW parameters (compile-time defaults):

  • max_elements: 100,000
  • M: 16 connections per layer
  • ef_construction: 200
  • ef_search: 2 × k (set at query time)

Via the Rust SDK:

#![allow(unused)]
fn main() {
client.create_vector_index("Document", "embedding", 768, DistanceMetric::Cosine).await?;
client.add_vector("Document", "embedding", node_id, &embedding_vec).await?;
let results = client.vector_search("Document", "embedding", &query_vec, 5).await?;
}

Are composite (multi-property) indexes supported?

Yes, since v0.6.0. Composite indexes cover multiple properties on the same label:

CREATE INDEX ON :Person(firstName, lastName)

-- The planner uses the composite index when both properties appear in WHERE:
MATCH (n:Person) WHERE n.firstName = 'Alice' AND n.lastName = 'Smith' RETURN n
-- Plan: IndexScanOperator(Person.firstName='Alice', Person.lastName='Smith')

Single-property indexes are also supported. When a WHERE clause has multiple indexed predicates with AND, the planner uses AND-chain index selection (v0.6.0) to pick the most selective index.

Are unique constraints supported?

Yes, since v0.6.0. You can enforce property uniqueness within a label:

CREATE CONSTRAINT ON (n:Person) ASSERT n.email IS UNIQUE

Attempting to create a node with a duplicate value on a unique-constrained property will return an error. Use SHOW CONSTRAINTS to list active constraints.

Is DROP INDEX supported?

Yes, since v0.6.0. You can drop indexes via Cypher:

DROP INDEX ON :Person(name)

Can I list all indexes?

Yes, since v0.6.0. Use SHOW INDEXES and SHOW CONSTRAINTS:

SHOW INDEXES
-- Returns: label, property, index type for all active indexes

SHOW CONSTRAINTS
-- Returns: label, property, constraint type for all active constraints

Query Planner & Optimizer

What cost model does the query planner use?

Since v0.6.1, Samyama has a graph-native cost-based planner (ADR-015) with a multiplicative cardinality model. The planner uses two tiers of statistics:

  • GraphCatalog (incremental) — triple-level stats per (source_label, edge_type, target_label) pattern, maintained on every edge create/delete
  • GraphStatistics (batch) — label counts, edge type counts, per-property selectivity (sampled from first 1,000 nodes per label)

The cost model in cost_model.rs assigns estimated cardinalities to each operator:

OperatorCost Formula
LabelScanlabel_count (from catalog)
IndexLookupFixed 10.0 (highly selective)
Expand (Forward)input_cost × avg_out_degree
Expand (Reverse)input_cost × avg_in_degree
ExpandIntoinput_cost × edge_existence_probability
Filterinput_cost × 0.5 (default selectivity)
Joinleft_cost + right_cost
CartesianProductleft_cost × right_cost

The planner pipeline:

  1. Plan enumeration: For each node in the MATCH pattern, build a candidate plan via BFS (plan_enumerator.rs), choosing optimal traversal direction at each step
  2. Logical optimization: Apply predicate pushdown and ExpandInto insertion (logical_optimizer.rs)
  3. Cost estimation: Score each candidate using the multiplicative cost model (cost_model.rs)
  4. Plan selection: Sort candidates by cost, pick the cheapest (up to 64 candidates evaluated)
  5. Physical translation: Convert the logical plan to executable operators (physical_planner.rs)
  6. Index selection: If a property index exists for a WHERE predicate, use IndexScanOperator; for AND-chains, select the most selective index
  7. Plan caching: Plans cached with generation-based invalidation tied to catalog changes

Example — the planner selects different starting points based on catalog stats:

-- 1,000 Person nodes, 10 Company nodes, each Person works at 1 Company
EXPLAIN MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN p.name, c.name

-- Candidate 1 (start from Person): LabelScan(1000) × Expand(1.0) = 1000
-- Candidate 2 (start from Company): LabelScan(10) × ReverseExpand(100.0) = 1000
-- Planner evaluates BOTH, picks cheapest

Example — index selection:

-- Without index: full label scan
EXPLAIN MATCH (n:Person) WHERE n.name = 'Alice' RETURN n
-- Plan: NodeScanOperator(Person) → FilterOperator(name = 'Alice') → ProjectOperator

-- With index: index scan
CREATE INDEX ON :Person(name)
EXPLAIN MATCH (n:Person) WHERE n.name = 'Alice' RETURN n
-- Plan: IndexScanOperator(Person.name = 'Alice') → ProjectOperator

See the Query Optimization chapter.

How are individual operator costs estimated?

Since v0.6.1, the graph-native planner assigns a multiplicative cardinality estimate to every operator in a candidate plan via cost_model::estimate_plan_cost(). The cost model is recursive — each operator’s cost depends on its input’s estimated cardinality:

Example: MATCH (p:Person)-[:KNOWS]->(q:Person) WHERE q.age > 30 RETURN q

Plan (start from p):
  LabelScan(Person)                     cost = 1,000        (label count)
  → Expand(:KNOWS, Forward)             cost = 1,000 × 5.0 = 5,000  (avg_out_degree)
  → Filter(age > 30)                    cost = 5,000 × 0.5 = 2,500  (default selectivity)
  Total plan cost: 2,500

Plan (start from q):
  LabelScan(Person)                     cost = 1,000
  → Filter(age > 30)                    cost = 1,000 × 0.5 = 500    (filter pushed down!)
  → Expand(:KNOWS, Reverse)             cost = 500 × 5.0 = 2,500
  Total plan cost: 2,500

The planner compares all candidate plans and selects the lowest-cost one. EXPLAIN shows the chosen plan with operator descriptions; PLAN_DIAGNOSTICS (accessible in EXPLAIN output) shows how many candidates were evaluated and their costs.

Current limitations:

  • Filter selectivity is hardcoded at 0.5 (no property-level histograms yet)
  • Sort/Aggregate operators are always appended after the chosen scan+expand plan
  • Property-level estimate_equality_selectivity exists in GraphStatistics but is not yet wired into the graph-native cost model

What cardinality estimation techniques are used?

Two tiers of estimation methods:

GraphCatalog (triple-level, used by graph-native planner):

MethodWhat It ReturnsComplexity
estimate_label_scan(label)Exact node count for a labelO(1)
estimate_expand_out(src_label, edge_type)Average outgoing degree (sum across target labels)O(k)
estimate_expand_in(tgt_label, edge_type)Average incoming degree (sum across source labels)O(k)
estimate_edge_existence(src, et, tgt)Probability a random (src, tgt) pair has an edgeO(1)

GraphStatistics (batch, used for EXPLAIN display and legacy planner):

MethodWhat It ReturnsComplexity
estimate_label_scan(label)Exact node count for a labelO(1)
estimate_expand(edge_type)Total edge count for a typeO(1)
estimate_equality_selectivity(label, prop)1.0 / distinct_count for the propertyO(1)

Example — GraphCatalog triple-level estimation:

Graph: 1,000 Persons, 10 Companies, 1,000 WORKS_AT edges (each person → 1 company)

Catalog TripleStats for (:Person, :WORKS_AT, :Company):
  count = 1,000, avg_out_degree = 1.0, avg_in_degree = 100.0

Plan A (start Person):  1,000 × 1.0 = 1,000 cost
Plan B (start Company): 10 × 100.0 = 1,000 cost  (same total, different shape)

Example — property selectivity:

10,000 Person nodes, 'name' has 8,000 distinct values:
estimate_equality_selectivity("Person", "name") → 1/8,000 = 0.000125
Estimated rows for WHERE name = 'Alice' → 10,000 × 0.000125 ≈ 1.25

How are statistics collected and maintained?

Samyama maintains statistics at two levels:

GraphCatalog (incremental, always up-to-date):

The GraphCatalog tracks per-triple-pattern statistics (source_label, edge_type, target_label) and is updated incrementally on every graph mutation:

  • on_label_added(label) / on_label_removed(label) — updates label counts
  • on_edge_created(src, src_labels, et, tgt, tgt_labels) — updates triple stats for all label combinations
  • on_edge_deleted(...) — mirrors edge creation

For each triple pattern, the catalog tracks:

  • count — total edges matching this pattern
  • avg_out_degree — count / distinct_sources
  • avg_in_degree — count / distinct_targets
  • distinct_sources / distinct_targets — unique endpoints
  • max_out_degree — peak degree for worst-case estimation

A generation counter increments on every change, enabling plan cache invalidation.

GraphStatistics (batch, computed on demand):

Computed via GraphStore::compute_statistics():

  1. Iterates all labels in label_index and counts nodes per label
  2. Iterates all edge types in edge_type_index and counts edges per type
  3. Samples the first 1,000 nodes per label to compute per-property stats:
    • null_fraction — fraction of sampled nodes missing the property
    • distinct_count — number of distinct values observed
    • selectivity1.0 / distinct_count (uniform distribution assumption)
  4. Computes avg_out_degree across all nodes

GraphStatistics are recomputed on each EXPLAIN call. Adding histogram-based distributions and wiring property selectivity into the graph-native cost model is on the roadmap.

How does the planner handle cardinality estimation errors?

Since v0.6.0, statistics drive cost-based plan selection (join order, index choice). This means cardinality estimation errors can now cause suboptimal plans — for example, choosing a less selective index or the wrong join order.

-- If the planner estimates 100 rows but there are actually 1,000,000:
MATCH (a:Person)-[:KNOWS]->(b:Person)
WHERE a.city = 'Mumbai'
RETURN a.name, b.name

-- The CBO might build the hash table on the wrong side
-- or choose an index that isn't actually the most selective

Mitigations: use EXPLAIN to verify estimates, and ensure statistics are fresh (they are recomputed on each EXPLAIN call). In mature optimizers, cardinality estimation errors can cause severe performance problems. Tools like Picasso visualize these errors as cardinality diagrams, mapping estimation accuracy across the selectivity space to expose where the optimizer’s statistics are most inaccurate.

What about multi-column correlations and compound predicates?

Not yet handled. The current selectivity model assumes independence between properties — selectivity(A AND B) = selectivity(A) × selectivity(B). This is the standard simplifying assumption but can be wildly wrong when properties are correlated.

Example:

MATCH (n:Person) WHERE n.city = 'Mumbai' AND n.country = 'India' RETURN n
-- Independence assumption: selectivity = (1/500 cities) × (1/200 countries) = 1/100,000
-- Reality: everyone in Mumbai is in India, so selectivity = 1/500
-- The estimate is off by 200x!

Future work includes:

  • Multi-column statistics (joint distinct counts or dependency graphs)
  • Histogram-based estimation (equi-width or equi-depth histograms per property)
  • Sketch-based estimation (HyperLogLog for distinct counts, Count-Min Sketch for frequency estimation)

Does Samyama support parameterized or templatized queries?

Yes, since v0.6.0. Use $param syntax with parameter bindings:

-- Parameterized query:
MATCH (n:Person {age: $age}) RETURN n
-- Pass parameters via the SDK or RESP protocol

-- Literal values also work:
MATCH (n:Person {age: 30}) RETURN n

Parameterized queries enable plan cache reuse across different parameter values, reducing parsing and planning overhead. Prepared statements (PREPARE/EXECUTE) are on the roadmap.

How do parameterized queries affect plan stability?

In optimizers that support parameterized queries, a key concern is plan stability — whether the same query template produces different plans for different parameter values. This is the phenomenon visualized by tools like Picasso as plan diagrams: color-coded maps showing how the optimal plan changes as selectivity varies.

Example of plan instability in a hypothetical future CBO:

-- Template: MATCH (n:Person) WHERE n.age > $threshold RETURN n
-- With $threshold = 99 (selectivity 1%):  IndexScan is optimal
-- With $threshold = 10 (selectivity 90%): LabelScan is optimal
-- The optimizer must pick the right plan for each value

Since v0.6.0, parameterized queries are supported and plans are cached. The plan cache uses query string hashing to avoid re-parsing and re-planning for repeated queries. This means the “plan sniffing” concern is relevant — a cached plan may not be optimal for all parameter values. Currently Samyama uses a simple cache with statistics-based invalidation. Adaptive re-planning (when estimated vs. actual cardinalities diverge) is on the roadmap.

What join algorithms does Samyama use?

Three join strategies are available:

OperatorAlgorithmWhen Used
JoinOperatorHash JoinMATCH clauses share a variable
LeftOuterJoinOperatorLeft Outer Hash JoinOPTIONAL MATCH
CartesianProductOperatorCross ProductNo shared variables

Example — hash join on a shared variable b:

-- Two patterns sharing variable 'b' → HashJoin
MATCH (a:Person)-[:WORKS_AT]->(b:Company)
MATCH (b)<-[:INVESTED_IN]-(c:Fund)
RETURN a.name, b.name, c.name
-- Plan: HashJoin on 'b'
--   Left:  NodeScan(Person) → Expand(WORKS_AT)
--   Right: NodeScan(Fund) → Expand(INVESTED_IN)

Example — cross product with no shared variable:

-- No shared variable → CartesianProduct (expensive!)
MATCH (a:Person), (b:Product)
RETURN a.name, b.name
-- Plan: CartesianProduct (|Person| × |Product| rows)

Example — left outer join for optional patterns:

-- OPTIONAL MATCH → LeftOuterHashJoin (NULLs for non-matches)
MATCH (p:Person)
OPTIONAL MATCH (p)-[:HAS_ADDRESS]->(a:Address)
RETURN p.name, a.city
-- Persons without addresses appear with a.city = NULL

The hash join materializes the left side into a HashMap<Value, Vec<Record>> and probes it for each right-side record.

How is join order determined?

Since v0.6.0, the planner performs join reordering based on cardinality estimates — it places the smaller (more selective) side as the build side of the hash join, regardless of the order in the query text.

-- Both versions now produce the same optimal plan:
MATCH (a:Person), (b:Company) WHERE a.worksAt = b.name RETURN a, b
MATCH (b:Company), (a:Person) WHERE a.worksAt = b.name RETURN a, b
-- Planner puts Company (1K nodes) as build side, Person (1M) as probe side

Not yet implemented: Bushy join trees (the planner always produces left-deep trees) or adaptive joins that switch strategy mid-execution.

Are there additional join strategies on the roadmap?

Yes. Future join strategies under consideration:

AlgorithmBest ForComplexity
Nested-Loop JoinSmall right side, or when index exists on join keyO(n × m) worst case
Merge JoinBoth sides already sorted on join keyO(n + m)
Index Nested-Loop JoinRight side has index on join keyO(n × log m)
Adaptive JoinSwitches strategy based on runtime cardinalitiesVariable

What scan and traversal operators are available?

Samyama has 42 physical operators in total. The key scan and traversal operators:

OperatorAccess MethodWhen Chosen
NodeScanOperatorFull label scan via label_indexDefault — no index matches the WHERE predicate
IndexScanOperatorB-tree range scan on property indexIndex exists on (label, property) and WHERE has a matching =, >, >=, <, or <= predicate
VectorSearchOperatorHNSW approximate nearest neighborCALL db.index.vector.queryNodes(...)
ExpandOperatorAdjacency list traversal (outgoing or incoming)Graph-native planner chooses direction based on catalog stats
ExpandIntoOperatorBinary search edge existence check O(log d)Both endpoints already bound (triangle/clique patterns)
NodeByIdOperatorDirect node lookup from pre-computed setInternal use (subquery results)
ShortestPathOperatorBFS shortest path with predicatesshortestPath() function in MATCH

Example showing the scan selection logic:

-- No index on :Person(age) → NodeScanOperator + FilterOperator
MATCH (n:Person) WHERE n.age > 30 RETURN n
-- Plan: NodeScan(Person) → Filter(age > 30) → Project
-- Scans ALL Person nodes, filters in memory

-- After: CREATE INDEX ON :Person(age)
MATCH (n:Person) WHERE n.age > 30 RETURN n
-- Plan: IndexScan(Person.age > 30) → Project
-- Scans ONLY nodes with age > 30 via B-tree range query

Can multiple indexes be used for a single query (index intersection)?

Since v0.6.0, the planner uses AND-chain index selection to pick the most selective index when a WHERE clause has multiple indexed predicates:

CREATE INDEX ON :Person(age)
CREATE INDEX ON :Person(city)

MATCH (n:Person) WHERE n.age > 30 AND n.city = 'Mumbai' RETURN n
-- Planner picks the more selective index (e.g., city = 'Mumbai' if fewer matches)
-- and applies the other predicate as a post-scan filter

Full index intersection (scanning both indexes independently and intersecting the result sets) is on the roadmap for further optimization.

Are there other scan limitations I should know about?

Yes:

  • Only the start node of each MATCH path is considered for index scans — intermediate or end nodes always use label scan + filter:
    -- Index on :Person(name) is used for 'a' (start node):
    MATCH (a:Person {name: 'Alice'})-[:KNOWS]->(b:Person {name: 'Bob'}) RETURN b
    -- Plan: IndexScan(a) → Expand(KNOWS) → Filter(b.name = 'Bob')
    -- Note: b.name = 'Bob' is filtered in memory, not via index
    
  • OR predicates do not trigger index union scans:
    MATCH (n:Person) WHERE n.age = 30 OR n.age = 40 RETURN n
    -- Falls back to full label scan + filter (even if age is indexed)
    
  • String predicates (CONTAINS, STARTS WITH, ENDS WITH) do not use indexes

To verify which scan your query uses, always prefix with EXPLAIN.

How does the query planner choose between possible plans?

The graph-native planner follows this pipeline:

  1. Parse the Cypher AST (cached for repeated queries)
  2. Extract a PatternGraph from the MATCH clause — nodes, edges, labels, directions
  3. Enumerate candidate plans: for each pattern node as starting point, BFS through the pattern graph building a logical plan tree. At each edge, choose_direction() compares estimate_expand_out vs estimate_expand_in to pick the cheaper traversal direction
  4. Optimize each candidate: predicate pushdown (move Filter below Expand when safe) and ExpandInto insertion (when both endpoints already bound)
  5. Score each candidate via estimate_plan_cost() using GraphCatalog triple-level stats
  6. Select the cheapest plan
  7. Translate to physical operators via logical_to_physical() (direction reversal: Logical Reverse → Physical Incoming)
  8. Cache the plan with generation-based invalidation
MATCH (a:Person)-[:KNOWS]->(b:Person)
WHERE a.name = 'Alice'
RETURN b.name
ORDER BY b.name
LIMIT 10
-- Plan: IndexScan(Person.name='Alice') → Expand(KNOWS) → Project(b.name) → Sort(b.name) → Limit(10)

EXPLAIN shows diagnostics including candidates evaluated and chosen plan cost. The planner reorders joins automatically — query text order does not affect plan quality.

What is the graph-native planner and how does it differ from the legacy planner?

Since v0.6.1, Samyama has a graph-native cost-based optimizer (ADR-015) that follows the same fundamental approach as mature systems like PostgreSQL:

  1. Enumerate candidate plans — one per starting node in the MATCH pattern, with BFS traversal through the pattern graph
  2. Estimate the cost of each plan using the multiplicative cardinality model and GraphCatalog triple-level statistics
  3. Optimize each candidate with predicate pushdown and ExpandInto insertion
  4. Compare all candidates and select the lowest-cost plan (up to 64 evaluated)

Key differences from the legacy planner:

AspectLegacy PlannerGraph-Native Planner
Starting pointAlways leftmost node in ASTEvaluates ALL pattern nodes
DirectionAlways follows AST directionChooses cheapest direction per edge
ExpandIntoNot availableO(log d) edge existence check
Cost modelHeuristic (no numeric costs)Multiplicative cardinality estimation
Plan candidates1 (single greedy plan)Up to 64 per query
StatisticsBatch (GraphStatistics)Incremental (GraphCatalog)
Predicate pushdownBasicCost-aware, below Expand nodes

Example — the graph-native planner considers multiple plans for a 3-way join:

MATCH (a:Person)-[:KNOWS]->(b:Person)-[:WORKS_AT]->(c:Company)
WHERE a.age > 25 AND c.size > 1000
RETURN a.name, c.name

-- Plan A (start a): LabelScan(Person) → Filter(age>25) → Expand(KNOWS) → Expand(WORKS_AT) → Filter(size>1000)
-- Plan B (start c): LabelScan(Company) → Filter(size>1000) → ReverseExpand(WORKS_AT) → ReverseExpand(KNOWS) → Filter(age>25)
-- Plan C (start b): LabelScan(Person) → Expand(KNOWS, Reverse) → Expand(WORKS_AT) → Filter(age>25, size>1000)
-- Planner estimates cost of each via catalog stats, picks cheapest

The ExpandInto operator is a key graph-native optimization. When both endpoints of an edge are already bound, instead of scanning all neighbors (O(degree)), it checks edge existence via binary search on sorted adjacency lists (O(log degree)):

-- Triangle pattern: a→b, b→c, a→c
MATCH (a:Person)-[:KNOWS]->(b:Person)-[:KNOWS]->(c:Person), (a)-[:KNOWS]->(c)
-- Plan: LabelScan(a) → Expand(a→b) → Expand(b→c) → ExpandInto(a→c)
-- ExpandInto checks if edge exists between already-bound a and c

Picasso visualization (available in samyama-insight) helps analyze CBO behavior by generating plan diagrams — color-coded maps showing which plan the optimizer selects at each point in the selectivity/parameter space. These visualizations reveal:

  • Plan switches: Where the optimizer changes its preferred plan
  • Cost cliffs: Sudden spikes in estimated cost at plan boundaries
  • Nervous regions: Areas where small selectivity changes cause frequent plan switches
  • Robust plans: Plans that perform well across a wide range of selectivities

The graph-native planner is enabled via PlannerConfig { graph_native: true } and falls back gracefully to the legacy planner for unsupported patterns (e.g., variable-length paths).

What are “plan cliffs” and does Samyama have them?

A plan cliff occurs when a small change in data distribution causes the optimizer to switch to a dramatically different (and often worse) plan.

Example in a hypothetical CBO:

Selectivity of WHERE age > $threshold:
  threshold=95 → IndexScan  (fast, 5% of data)   → 2ms
  threshold=94 → IndexScan  (fast, 6% of data)   → 2.4ms
  threshold=93 → LabelScan! (slow, full table)    → 200ms  ← CLIFF!

The optimizer switches from index scan to full scan at a threshold, causing a 100x latency spike. Picasso visualizes these as sudden color changes in plan diagrams or sharp spikes in 3D cost surface plots.

Since v0.6.1, Samyama’s graph-native planner evaluates multiple candidate plans per query. Plan cliffs are possible (e.g., switching starting point or direction as data distribution shifts). samyama-insight’s Picasso tool visualizes these by sweeping parameter or pattern space and coloring cells by chosen plan, revealing plan switches and cost cliffs.

Can I evaluate alternative plans for the same query (Foreign Plan Costing)?

Yes, partially. The graph-native planner stores PlanDiagnostics for each query, accessible via EXPLAIN:

EXPLAIN MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN p, c

Planner diagnostics:
  Candidates evaluated: 2
  Chosen plan cost: 1000.0
  Alternatives:
    Plan starting from p: cost 1000.0 ← selected
    Plan starting from c: cost 1000.0

samyama-insight’s Picasso page extends this further — sweeping parameter ranges and showing which plan wins at each point in the selectivity space. Full FPC-style “force a specific plan and measure sub-optimality” is on the roadmap.

Can I visualize and compare execution plans (Plan Diffing)?

EXPLAIN outputs a textual operator tree, which can be compared manually between different queries:

-- Query A:
EXPLAIN MATCH (n:Person) WHERE n.name = 'Alice' RETURN n
-- Output: IndexScanOperator(Person.name = 'Alice') → ProjectOperator

-- Query B:
EXPLAIN MATCH (n:Person) WHERE n.age > 25 RETURN n
-- Output: NodeScanOperator(Person) → FilterOperator(age > 25) → ProjectOperator

-- Manual diff: Query A uses IndexScan, Query B uses NodeScan + Filter
-- → Create an index on :Person(age) to improve Query B

There is no built-in plan diffing tool that automatically highlights differences between two plans. Plan diffing, plan diagram generation, and graphical plan visualization are on the roadmap.

Is there plan caching or AST caching?

Yes, since v0.6.0. Samyama caches both parsed ASTs and execution plans, keyed by query string hash. Repeated queries skip parsing and planning entirely:

-- First execution: parse + plan + execute
MATCH (n:Person) WHERE n.name = 'Alice' RETURN n    -- cold: ~40ms

-- Subsequent executions: cache hit, execute only
MATCH (n:Person) WHERE n.name = 'Alice' RETURN n    -- warm: ~2ms (cache hit)

The plan cache significantly reduces warm-query latency. LDBC benchmarks show high cache hit rates (e.g., 63 hits vs 21 misses on the SNB Interactive workload).

Prepared statements (PREPARE/EXECUTE syntax) are on the roadmap for explicit cache management.

What is predicate pushdown, and does Samyama do it?

Predicate pushdown moves filter conditions as close to the data source as possible — filtering early reduces the number of records flowing through the rest of the plan.

Since v0.6.0, Samyama performs full predicate pushdown across paths and MATCH clauses:

  • Index pushdown: When a WHERE predicate matches an indexed property, the IndexScanOperator applies the filter during the scan itself
  • Label filtering: NodeScanOperator only scans nodes with the specified label, not all nodes
  • Cross-scope pushdown (v0.6.0): WHERE predicates are scoped across paths and MATCH clauses, filtering as early as possible
-- Index pushdown (index on :Person(name)):
MATCH (n:Person) WHERE n.name = 'Alice' RETURN n
-- Plan: IndexScan(name='Alice')  ← filter is INSIDE the scan operator

-- Cross-scope pushdown (v0.6.0):
MATCH (a:Person)-[:KNOWS]->(b:Person)
WHERE b.age > 30
RETURN a.name, b.name
-- Plan: NodeScan(Person) → Expand(KNOWS) → Filter(b.age > 30) [pushed to earliest point]

Not yet implemented:

  • Predicates on aggregation results (HAVING-style) are not pushed below the aggregation
  • Edge predicates are not pushed into the ExpandOperator

Can I force a specific execution plan or provide optimizer hints?

Not yet. Samyama does not currently support:

  • USING INDEX directives (Neo4j-style)
  • USING SCAN to force a label scan
  • USING JOIN ON to force a specific join variable
  • Query hints or optimizer directives of any kind

The only way to influence plan selection today is:

-- 1. Create indexes so the planner automatically uses them:
CREATE INDEX ON :Person(name)
CREATE INDEX ON :Person(age)

-- 2. Reorder MATCH clauses (put most selective first):
-- Slow (scans all 1M persons first):
MATCH (a:Person), (b:Department {name: 'Engineering'}) ...
-- Fast (scans 1 department first):
MATCH (b:Department {name: 'Engineering'}), (a:Person) ...

-- 3. Use EXPLAIN to verify the plan:
EXPLAIN MATCH (n:Person) WHERE n.name = 'Alice' RETURN n

Optimizer hints and plan forcing are planned for a future release.

What is the query optimizer roadmap?

The optimizer roadmap, roughly in priority order:

FeatureImpactStatus
AST cachingEliminate re-parsing (~22ms savings)Done (v0.6.0)
Plan memoizationEliminate re-planning (~18ms savings)Done (v0.6.0)
Parameterized queries ($param)Enable plan reuse across parameter valuesDone (v0.6.0)
PROFILE (runtime statistics)Actual rows, timing per operatorDone (v0.6.0)
DROP INDEX / SHOW INDEXESIndex lifecycle managementDone (v0.6.0)
Composite indexesMulti-property indexesDone (v0.6.0)
AND-chain index selectionUse best index for multi-predicate WHEREDone (v0.6.0)
Predicate pushdown across scopesReduce intermediate result sizesDone (v0.6.0)
Cost-based plan selectionCompare alternative plans by estimated costDone (v0.6.0)
Join reorderingPick optimal join order based on cardinalitiesDone (v0.6.0)
Early LIMIT propagationPush LIMIT down to reduce workDone (v0.6.0)
Index intersectionCombine multiple index scansPlanned
USING INDEX / USING SCAN hintsUser-controlled plan forcingPlanned
Histogram-based statisticsBetter selectivity estimates for skewed dataPlanned
Adaptive query executionRe-plan mid-execution if estimates are wrongResearch

How many physical operators does Samyama have?

42 physical operators organized into these categories:

CategoryOperatorsCount
Scan & TraverseNodeScanOperator, ExpandOperator, ExpandIntoOperator, IndexScanOperator, VectorSearchOperator, NodeByIdOperator, ShortestPathOperator7
RelationalFilterOperator, ProjectOperator, JoinOperator, LeftOuterJoinOperator, CartesianProductOperator5
AggregationAggregateOperator, UnwindOperator, ForeachOperator3
Sort & LimitSortOperator, LimitOperator, SkipOperator, WithBarrierOperator4
WriteCreateNodeOperator, CreateEdgeOperator, CreateNodesAndEdgesOperator, MatchCreateEdgeOperator, MatchMergeEdgeOperator, DeleteOperator, SetPropertyOperator, RemovePropertyOperator, MergeOperator9
Schema/DDLCreateIndexOperator, CreateVectorIndexOperator, CompositeCreateIndexOperator, CreateConstraintOperator, DropIndexOperator, ShowIndexesOperator, ShowConstraintsOperator, ShowLabelsOperator, ShowRelationshipTypesOperator, ShowPropertyKeysOperator, SchemaVisualizationOperator11
SpecialSingleRowOperator, AlgorithmOperator2
NavigationShortestPathOperator1

All operators implement the Volcano iterator model (lazy, pull-based) with late materialization (Value::NodeRef instead of full node clones).

How many index types does Samyama have?

6 distinct index types:

IndexStorageUse CaseComplexity
PropertyIndexB-Tree (BTreeMap<PropertyValue, HashSet<NodeId>>)Point lookups and range scans on (label, property)O(log n)
VectorIndexHNSW (Hierarchical Navigable Small World)Approximate nearest neighbor searchO(log n)
LabelIndexHashMap<Label, HashSet<NodeId>>Fast node lookup by labelO(1)
EdgeTypeIndexHashMap<EdgeType, HashSet<EdgeId>>Fast edge lookup by typeO(1)
SortedAdjacencyListsVec-of-Vec + FrozenAdjacency (CSR)Neighbor traversal, edge_between() binary searchO(log d)
ColumnStoreColumnar property storageVectorized property reads for late materializationO(1)

Additionally:

  • Composite indexes create individual PropertyIndex entries per property in the list
  • Unique constraints are enforced via PropertyIndex with uniqueness validation on insert
  • GraphCatalog maintains triple-level statistics (not an index, but used for cost-based planning)

Graph Algorithms

What algorithms are available?

13 algorithms in the samyama-graph-algorithms crate:

CategoryAlgorithms
CentralityPageRank, Local Clustering Coefficient (directed + undirected)
CommunityWCC, SCC, CDLP, Triangle Counting
PathfindingBFS, Dijkstra, BFS All Shortest Paths
Network FlowEdmonds-Karp (Max Flow), Prim’s MST
StatisticalPCA (Randomized SVD + Power Iteration)

How do I run PageRank?

Via Cypher:

CALL algo.pagerank({label: 'Person', edge_type: 'KNOWS', damping: 0.85, iterations: 20})
YIELD node, score

Via SDK (Rust):

#![allow(unused)]
fn main() {
use samyama_sdk::AlgorithmClient;

let config = PageRankConfig { damping: 0.85, iterations: 20, tolerance: 1e-6 };
let scores = client.page_rank(config, "Person", "KNOWS").await?;
for (node_id, score) in &scores {
    println!("Node {}: {:.4}", node_id, score);
}
}

How do I find shortest paths?

Using Dijkstra for weighted shortest paths:

CALL algo.dijkstra({
  source_label: 'City', source_property: 'name', source_value: 'Mumbai',
  target_label: 'City', target_property: 'name', target_value: 'Delhi',
  edge_type: 'ROAD', weight_property: 'distance'
})
YIELD path, cost

Using BFS for unweighted shortest paths:

CALL algo.bfs({
  source_label: 'Person', source_property: 'name', source_value: 'Alice',
  edge_type: 'KNOWS'
})
YIELD node, depth

What is the CSR format and why is it used?

Compressed Sparse Row (CSR) is a cache-efficient array-based representation of a graph. Algorithms project from GraphStore into CSR for OLAP workloads because sequential memory access patterns allow CPU prefetching with ~100% accuracy.

Example — a graph with 4 nodes and 5 edges in CSR:

Adjacency:  0→1, 0→2, 1→2, 2→3, 3→0

out_offsets:  [0, 2, 3, 4, 5]   ← node i's edges start at out_offsets[i]
out_targets:  [1, 2, 2, 3, 0]   ← target node IDs, packed contiguously
weights:      [1.0, 1.0, ...]   ← optional edge weights

To iterate node 0's neighbors: out_targets[0..2] = [1, 2]
To iterate node 1's neighbors: out_targets[2..3] = [2]

This layout is ~10x faster than HashMap<NodeId, Vec<NodeId>> for iterative algorithms because it eliminates pointer chasing and hash lookups. See the Analytical Power chapter.

Does PCA support auto-selection of the solver?

Yes. PcaSolver::Auto selects Randomized SVD when n > 500 and k < 0.8 * min(n, d), otherwise falls back to Power Iteration.

Example via Cypher:

CALL algo.pca({
  label: 'Document',
  properties: ['feature1', 'feature2', 'feature3', 'feature4'],
  components: 2,
  solver: 'auto'
})
YIELD node, components

Via Rust SDK:

#![allow(unused)]
fn main() {
let config = PcaConfig { components: 2, solver: PcaSolver::Auto };
let results = client.pca(config, "Document", &["feature1", "feature2", "feature3"]).await?;
}

Vector Search & AI

What distance metrics are supported?

Three metrics: Cosine, L2 (Euclidean), and Dot Product.

Example — choosing the right metric:

-- Cosine: best for text embeddings (direction matters, not magnitude)
CREATE VECTOR INDEX FOR (d:Document) ON (d.embedding) OPTIONS {dimensions: 768, similarity: 'cosine'}

-- L2: best for spatial data (absolute distance matters)
CREATE VECTOR INDEX FOR (p:Point) ON (p.coords) OPTIONS {dimensions: 3, similarity: 'l2'}

-- Dot Product: best for pre-normalized embeddings
CREATE VECTOR INDEX FOR (i:Item) ON (i.features) OPTIONS {dimensions: 128, similarity: 'dot_product'}

What is Graph RAG?

Graph RAG combines vector search with graph traversal in a single query. Instead of retrieving vectors and filtering in the application layer, Samyama applies graph filters inside the execution engine.

Example — find documents similar to a query, but only from a specific author’s department:

MATCH (a:Author {name: 'Alice'})-[:WORKS_IN]->(dept:Department)
MATCH (d:Document)-[:AUTHORED_BY]->(colleague)-[:WORKS_IN]->(dept)
CALL db.index.vector.queryNodes('Document', 'embedding', $query_vector, 10)
YIELD node, score
WHERE node = d
RETURN d.title, score, colleague.name
ORDER BY score DESC

This prevents the “filter-out-all-results” problem where a pure vector search returns documents from irrelevant departments. See AI & Vector Search.

How do I generate embeddings? Why is Mock the default?

Samyama indexes and searches vectors but does not bundle an embedding model. The default Mock provider generates random vectors — this is deliberate to keep the binary small (~30MB savings), avoid mandatory model downloads, and let you choose the embedding model that fits your domain.

For real embeddings, choose based on your stack:

StackProviderSetup
Pythonsentence-transformerspip install sentence-transformers — best model selection, easiest path
Rustort crate (ONNX Runtime)Export model to ONNX, load with ort::Session — fastest, no Python
Any languageOpenAI APIHTTP call to /v1/embeddings — simplest, pay-per-use
Any language (local)Ollamaollama pull nomic-embed-text — free, private, runs anywhere

Python example with sentence-transformers:

from samyama import SamyamaClient
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("all-MiniLM-L6-v2")  # 384-dim
client = SamyamaClient.embedded()
client.create_vector_index("Document", "embedding", 384, "cosine")

embedding = model.encode("Graph databases unify structure and search").tolist()
client.add_vector("Document", "embedding", node_id, embedding)

See AI & Vector Search — Embedding Providers for complete examples across all providers.

What is Agentic Enrichment (GAK)?

Generation-Augmented Knowledge (GAK) is the inverse of RAG. Instead of using the database to help an LLM, the database uses an LLM to help build itself.

Example flow:

1. Event:    New node created: (:Company {name: 'Acme Corp'})
2. Trigger:  AgentRuntime detects missing properties (industry, revenue, CEO)
3. LLM Call: "What industry is Acme Corp in? Who is the CEO?"
4. Result:   SET n.industry = 'Manufacturing', n.revenue = 5000000
             CREATE (n)-[:LED_BY]->(:Person {name: 'Jane Smith', role: 'CEO'})
5. Safety:   Schema validation + destructive query rejection before commit

See Agentic Enrichment.

What LLM providers are supported for NLQ?

The NLQClient supports: OpenAI, Google Gemini, Ollama (local), Anthropic (Claude API), Claude Code, and Azure OpenAI. A Mock provider is also available for testing.

Example — natural language to Cypher:

#![allow(unused)]
fn main() {
let pipeline = NLQPipeline::new(NLQConfig {
    enabled: true,
    provider: LLMProvider::OpenAI,
    model: "gpt-4o".to_string(),
    api_key: Some(env::var("OPENAI_API_KEY")?),
    api_base_url: None,
    system_prompt: None,
})?;

let cypher = pipeline.text_to_cypher(
    "Who are Alice's friends that work at Google?",
    &schema_summary
).await?;
// Returns: MATCH (a:Person {name: 'Alice'})-[:KNOWS]->(f:Person)-[:WORKS_AT]->(c:Company {name: 'Google'}) RETURN f.name
}

Supported providers: LLMProvider::OpenAI, Ollama, Gemini, Anthropic, ClaudeCode, AzureOpenAI, Mock (for testing).

The pipeline uses a whitelist safety check — only queries starting with MATCH, RETURN, UNWIND, CALL, or WITH are allowed through, preventing accidental mutations from LLM-generated Cypher.


Optimization

How many solvers are available?

22 metaheuristic solvers in the samyama-optimization crate:

  • Metaphor-less: Jaya, QOJAYA, Rao (1-3), TLBO, ITLBO, GOTLBO
  • Swarm/Evolutionary: PSO, DE, GA, GWO, ABC, BAT, Cuckoo, Firefly, FPA
  • Physics-based: GSA, SA, HS, BMR, BWR
  • Multi-objective: NSGA-II, MOTLBO

How do I run an optimization solver?

Via Cypher:

-- Single-objective: minimize supply chain cost
CALL algo.or.solve({
  solver: 'jaya',
  dimensions: 5,
  bounds: [[0, 100], [0, 100], [0, 100], [0, 100], [0, 100]],
  objective: 'minimize',
  fitness_function: 'supply_chain_cost',
  iterations: 1000,
  population: 50
})
YIELD solution, fitness

-- Multi-objective: Pareto-optimal trade-offs
CALL algo.or.solve({
  solver: 'nsga2',
  dimensions: 3,
  bounds: [[0, 1], [0, 1], [0, 1]],
  objectives: ['minimize_cost', 'maximize_quality'],
  population: 100,
  generations: 200
})
YIELD pareto_front

Are the optimization solvers open-source or enterprise-only?

All 22 solvers are in the open-source samyama-optimization crate. Enterprise adds GPU-accelerated constraint evaluation for large-scale problems.

How do I choose the right solver?

ScenarioRecommended SolverWhy
Simple optimization, no tuningJayaParameter-free, good baseline
Constraints with penalty functionsPSO or GWOGood constraint handling
Multiple conflicting objectivesNSGA-IIConstrained Dominance Principle, Pareto front
High-dimensional search spaceDEGood for 10+ dimensions
Need global optimum, avoid local minimaSA (Simulated Annealing)Probabilistic escape from local minima
Teaching/learning-inspiredTLBONo algorithm-specific parameters

Performance & Scaling

What are the latest benchmark numbers?

On Mac Mini M4 (16GB RAM), v0.6.0:

BenchmarkCPUGPU
Node Ingestion255K/s412K/s
Edge Ingestion4.2M/s5.2M/s
Cypher OLTP (1M nodes)115K QPS
PageRank (1M nodes)92ms11ms (8.2x)
Vector Search (10K, 128d)15K QPS

When should I use GPU acceleration?

GPU acceleration is beneficial for graphs with > 100,000 nodes. Below this threshold, CPU-GPU memory transfer overhead dominates.

Example — PageRank speedup at different scales:

10K nodes:   CPU 0.6ms vs GPU 9.3ms  → GPU is SLOWER (0.06x)
100K nodes:  CPU 8.2ms vs GPU 3.1ms  → GPU wins (2.6x faster)
1M nodes:    CPU 92ms  vs GPU 11ms   → GPU wins big (8.2x faster)

For PCA specifically, the threshold is 50,000 nodes and > 32 dimensions.

Has Samyama been validated against industry benchmarks?

Yes. Samyama achieved 28/28 (100%) on the LDBC Graphalytics benchmark suite across 6 algorithms (BFS, PageRank, WCC, CDLP, LCC, SSSP) on both XS and S-size datasets.

# Run the validation yourself:
cargo bench --bench graphalytics_benchmark -- --all

S-size datasets include cit-Patents (3.8M vertices), datagen-7_5-fb (633K vertices, 68M edges), and wiki-Talk (2.4M vertices). See Performance & Benchmarks.

What is the bottleneck in query execution?

At 1M nodes, the bottleneck is the language frontend (parsing: 54%, planning: 44%), not execution (2%):

Component          Time      % of total
─────────────────────────────────────────
Parse (Pest)       ~22ms     54%
Plan (AST→Ops)     ~18ms     44%
Execute (iterate)  <1ms       2%  ← actual graph work is sub-millisecond!

As of v0.6.0, a plan cache memoizes compiled execution plans for repeated queries, eliminating the parsing and planning overhead on warm queries. Parameterized queries ($param) further improve cache hit rates by separating query structure from literal values.

Where do the Neo4j and Memgraph comparison numbers come from?

Table 10 in the arxiv paper (2603.08036) compares Samyama against Neo4j 5.x and Memgraph 2.x. Here are the sources for each competitor number:

1-Hop Query Latency — Memgraph ~1.1 ms, Neo4j ~28 ms: From Memgraph’s official benchmark (Expansion 1 query: Memgraph 1.09 ms, Neo4j 27.96 ms).

Node Ingestion — Neo4j ~26K/s, Memgraph ~295K/s: From Memgraph’s write speed analysis — Neo4j took 3.8s to create 100K nodes (~26K/s); Memgraph took ~400ms for 100K nodes (~250K/s).

Memory (1M nodes) — Neo4j ~1,200 MB, Memgraph ~600 MB: Neo4j’s JVM heap sizing recommendations (heap + page cache overhead for graph workloads); Memgraph’s C++ in-memory architecture characteristics.

GC Pauses — Neo4j 10-100 ms, Samyama/Memgraph 0 ms: Neo4j’s GC tuning documentation describes old-generation garbage collection pauses; Samyama (Rust) and Memgraph (C++) have no garbage collector.

Additional resources:

Note: The memory numbers (~1,200 MB for Neo4j, ~600 MB for Memgraph at 1M nodes) are estimates based on architecture characteristics rather than a single published benchmark at exactly 1M nodes. The ingestion and latency numbers come from Memgraph’s published benchmarks, which were conducted on their hardware and configuration. Samyama numbers are measured on Mac Mini M4 (16 GB RAM). As stated in the paper: “Direct comparison is approximate due to different hardware, datasets, and query optimization levels.”


Architecture Deep Dive

Is Samyama ACID-compliant or eventually consistent?

Samyama provides local ACID guarantees for single-node deployments:

  • Atomicity: Each write query (CREATE, DELETE, SET, MERGE) executes as an atomic WriteBatch via RocksDB. Either all changes commit or none do.
  • Consistency: Unique constraints (when defined) are enforced before commit. Schema integrity is maintained across labels, edges, and properties.
  • Isolation: The in-memory GraphStore uses a RwLock — multiple concurrent readers with exclusive writer access. Queries see a consistent snapshot.
  • Durability: The Write-Ahead Log (WAL) persists every mutation before acknowledgement. On crash recovery, uncommitted WAL entries are replayed.

In a Raft cluster (Enterprise), writes go through consensus — a write is acknowledged only after a majority of nodes have persisted the log entry. This provides strong consistency (linearizable writes) at the cost of write latency. There is no “eventually consistent” mode.

Interactive multi-statement transactions (BEGIN...COMMIT) are on the roadmap. Today, each Cypher statement is an implicit transaction.

Is Samyama multi-master? How does Raft synchronization work?

No. Samyama uses single-leader Raft consensus (via the openraft crate):

  • One leader accepts all write requests and replicates them to followers.
  • Followers can serve read queries (read replicas) for horizontal read scaling.
  • If the leader fails, a new leader is automatically elected (typically within 1–2 seconds).

This is not a multi-master architecture. Multi-master would require conflict resolution (CRDTs, last-write-wins, etc.), which adds complexity and weakens consistency guarantees. Single-leader Raft gives us strong consistency without conflict resolution overhead.

Client Write ──► Leader ──► Follower 1 (ack)
                       └──► Follower 2 (ack)
                       └──► majority acked → commit → respond to client

Does Samyama use the RocksDB C/C++ library or a Rust port?

Samyama uses rust-rocksdb, which is a Rust binding to the original C++ RocksDB library from Meta (Facebook). It is NOT a Rust rewrite — it links against the actual C++ RocksDB via FFI (Foreign Function Interface). This means:

  • We get the battle-tested, production-proven RocksDB storage engine (used by Meta, CockroachDB, TiKV, etc.)
  • The Rust binding provides safe, idiomatic Rust APIs over the C++ core
  • Performance is identical to native RocksDB — no overhead from the binding layer

RocksDB handles compaction, compression (LZ4/Zstd), bloom filters, and sorted string tables (SSTs). Samyama uses RocksDB column families for multi-tenancy isolation.

How does concurrency work?

Samyama uses a readers-writer lock (tokio::sync::RwLock) at the GraphStore level:

  • Reads (MATCH queries): Multiple readers can execute concurrently. Each reader acquires a shared read lock.
  • Writes (CREATE, DELETE, SET, MERGE): A writer acquires an exclusive lock. No reads or other writes proceed while a write is in progress.
  • RESP server: The Tokio async runtime handles thousands of concurrent connections. Read queries are processed concurrently; write queries are serialized.

This model is simple and correct. For read-heavy workloads (typical for graph databases), it provides excellent throughput since reads never block each other. Write throughput is limited to one writer at a time, but individual writes are fast (sub-millisecond for most mutations).

Future work includes finer-grained concurrency (per-partition or MVCC-based), but the current model handles production workloads well because graph queries spend most time in traversal (reading), not mutation.

Are you using SIMD for graph traversal?

Not currently in explicit SIMD intrinsics, but we benefit from auto-vectorization by the LLVM backend (Rust compiles via LLVM). The --release build enables -O3 optimizations which include:

  • Auto-vectorized array operations in adjacency list scanning
  • SIMD-friendly memory layouts in the CSR (Compressed Sparse Row) representation used by graph algorithms
  • Cache-line-aligned data structures for traversal hot paths

For GPU acceleration (Enterprise), we use WGSL compute shaders via wgpu — this is massively parallel computation (thousands of GPU threads), which is a different paradigm from CPU SIMD. GPU shaders handle PageRank, CDLP, LCC, Triangle Counting, and PCA on large graphs (>100K nodes).

Explicit CPU SIMD intrinsics (e.g., for batch property filtering or distance calculations) are on the roadmap but not yet implemented.

How does multi-tenancy work internally? Is there database-level isolation?

Yes, tenants get storage-level isolation via RocksDB Column Families:

  • Each tenant gets its own Column Family in a single RocksDB instance. Column families are logically separate key-value namespaces — they have independent memtables, SST files, and compaction schedules.
  • One tenant’s heavy writes or compaction do not affect other tenants’ read/write performance.
  • Per-tenant quotas are enforced: max_nodes, max_edges, max_memory_bytes, max_storage_bytes, max_connections, and max_query_time_ms.
┌──────────── Single RocksDB Instance ────────────┐
│  ┌─────────────┐  ┌─────────────┐  ┌──────────┐ │
│  │  CF: acme   │  │ CF: globex  │  │ CF: ...  │ │
│  │  memtable   │  │  memtable   │  │          │ │
│  │  SST files  │  │  SST files  │  │          │ │
│  │  WAL        │  │  WAL        │  │          │ │
│  └─────────────┘  └─────────────┘  └──────────┘ │
└─────────────────────────────────────────────────┘

We chose a single RocksDB instance with column families over multiple RocksDB instances because:

  1. Lower resource overhead: One set of background threads, one WAL, shared block cache
  2. Simpler operations: One database to back up, monitor, and recover
  3. Proven at scale: TiKV (TiDB’s storage engine) uses the same column-family-per-region approach

If you need stronger isolation (separate processes, separate machines), the Raft cluster topology allows deploying dedicated nodes per tenant.

How does embedding work? Is it a .so file or a Rust library?

Both options are available:

  1. Rust library (primary): Add samyama-sdk as a Cargo dependency. The EmbeddedClient runs the full engine in-process — no server, no network, no serialization overhead.

    [dependencies]
    samyama-sdk = "0.6"
    
    #![allow(unused)]
    fn main() {
    let client = EmbeddedClient::new();
    client.query("default", "CREATE (n:Person {name: 'Alice'})").await?;
    }
  2. Python binding (PyO3): The Python SDK compiles to a native .so / .dylib shared library via PyO3. Install with pip install samyama (or maturin develop from source). No Rust toolchain needed at runtime.

    from samyama import SamyamaClient
    client = SamyamaClient.embedded()
    result = client.query("default", "MATCH (n) RETURN count(n)")
    
  3. C FFI (planned): A C-compatible shared library (.so / .dll) for embedding from any language with FFI support (Go, Java, C#, etc.) is on the roadmap.

For production services, most users run Samyama as a standalone server (RESP on :6379, HTTP on :8080) and connect via the Rust, Python, or TypeScript SDK using the RemoteClient.


Distributed Deployment & High Availability

Does Samyama support replication?

Yes. Samyama implements Raft consensus (via the openraft Rust crate) for distributed replication. All write operations (CREATE, SET, DELETE, MERGE) are replicated to followers before being committed.

How it works:

  1. Client sends a write to the Raft leader
  2. Leader appends to its local log (uncommitted)
  3. Leader sends AppendEntries to followers in parallel
  4. Once a quorum (majority) acknowledges, the entry is committed
  5. Leader applies to the graph store and returns success
  6. Followers apply in the next heartbeat cycle

Configuration: 500ms heartbeat, 1.5–3s election timeout, log compaction after 5000 entries.

How does a node failure get handled?

ScenarioBehaviorDowntime
Follower fails (1 of 3)Quorum still holds (2/2), writes continueNone
Leader failsElection triggered, new leader elected150–300ms
Network partitionMajority partition continues; minority rejects writesAuto-heals on reconnection

Recovery: When a failed node comes back online, it receives heartbeats from the current leader, requests missing log entries, catches up, and rejoins the cluster. No manual intervention needed.

Data safety: A Raft entry is committed only after replication to a majority. Even if the leader crashes immediately after committing, at least one other node has the data.

How does tenant persistence and restore work?

Each tenant’s data is persisted to RocksDB using column families (one per tenant). The write path is:

  1. Write-Ahead Log (WAL) — sequential log for durability
  2. RocksDB — indexed storage with tenant-prefixed keys
  3. In-memory graph — the live GraphStore

On restart, PersistenceManager::recover(tenant) scans all nodes and edges from RocksDB and rebuilds the in-memory adjacency lists.

Snapshots (.sgsnap) provide an additional backup mechanism:

  • Export: POST /api/snapshot/export → gzip-compressed JSON-lines file
  • Import: POST /api/snapshot/import → ID remapping allows importing into non-empty stores
  • Use cases: disaster recovery, tenant migration, version-controlled deployments

How does this work in a distributed deployment?

In a Raft cluster:

  • All nodes hold a full copy of every tenant’s data (full replication, not partitioned)
  • The leader processes writes and replicates via Raft log entries
  • Followers can serve read queries (if configured for read replicas)
  • Snapshot and WAL are per-node; Raft log is the source of truth for consistency

Tenant-level sharding is implemented: a routing layer maps each tenant to a specific Raft cluster. Different tenants can be served by different clusters, providing logical isolation.

Tenant A → Raft Cluster 1 (nodes 1, 2, 3)
Tenant B → Raft Cluster 2 (nodes 4, 5, 6)
Tenant C → Raft Cluster 1 (same cluster as A)

What if a tenant needs 1 billion nodes? Isn’t sharding necessary?

Yes. Today, Samyama’s graph store is in-memory, so a single graph is limited by available RAM on one node. Practical limits:

NodesEdgesApprox. RAM
100K1M~500 MB
1M10M~5 GB
8M28M~33 GB
100M500M~150 GB
1B5B~1.5 TB

For 1 billion nodes, you would need either a very large machine (1.5+ TB RAM) or graph-level sharding — partitioning a single graph across multiple nodes.

Current status: Graph-level sharding is designed but not yet implemented (ADR-009). The approach uses graph-aware partitioning (METIS min-cut algorithm) to minimize cross-partition edges, with scatter-gather distributed query execution via Arrow Flight RPC.

Why not yet? It’s a research-level problem with very high complexity. The current Raft replication handles the majority of production use cases. Graph-level sharding will be implemented when customer demand justifies the engineering investment.

Workaround today: For very large graphs, use a machine with sufficient RAM (e.g., AWS r6i.24xlarge with 768 GB, or x2idn.32xlarge with 2 TB). The in-memory architecture means queries are extremely fast on these machines.

ClusterQuorumFault ToleranceWrite Latency
1 node1None~1.2ms
3 nodes21 failure~2.8ms
5 nodes32 failures~3.5ms

Recommendation: 3 nodes for most deployments (balances availability and latency). 5 nodes for critical workloads requiring tolerance of 2 simultaneous failures.


Enterprise & Operations

How does licensing work?

Enterprise uses JET (JSON Enablement Token)—an Ed25519-signed token containing org, edition, features, expiry, and machine fingerprint. 30-day grace period after expiry.

# Check license status:
redis-cli ADMIN.LICENSE

# Set license file:
SAMYAMA_LICENSE_FILE=/path/to/samyama.license cargo run --release --features gpu

See Enterprise Edition.

How do I create a backup?

# Full snapshot
redis-cli ADMIN.BACKUP CREATE

# List all backups
redis-cli ADMIN.BACKUP LIST

# Verify integrity of backup #5
redis-cli ADMIN.BACKUP VERIFY 5

# Restore from backup
redis-cli ADMIN.BACKUP RESTORE 5

What is Point-in-Time Recovery (PITR)?

PITR replays archived WAL entries against a snapshot to restore the database to an exact moment.

Example scenario:

10:30:00  Backup snapshot taken
10:30:04  Normal writes happening
10:30:05  Accidental: DELETE (n:Customer) WHERE n.region = 'APAC'   ← oops!
10:30:06  More writes

# Restore to 10:30:04 (before the accidental delete):
redis-cli ADMIN.PITR RESTORE "2026-03-04T10:30:04.000000"
# All APAC customers are back, writes after 10:30:04 are lost

How does multi-tenancy work?

Each tenant gets a dedicated RocksDB Column Family with per-tenant resource quotas (memory, storage, query time). Compaction is independent per tenant—one tenant’s write-heavy workload won’t affect others.

Example — querying within a specific tenant:

# Create a graph in tenant "acme"
redis-cli GRAPH.QUERY acme "CREATE (n:User {name: 'Alice'})"

# Query within that tenant (isolated from other tenants)
redis-cli GRAPH.QUERY acme "MATCH (n:User) RETURN n.name"

# Different tenant, different data
redis-cli GRAPH.QUERY globex "MATCH (n:User) RETURN n.name"  -- returns different results

See Observability & Multi-tenancy.


RDF & SPARQL

What RDF serialization formats are supported?

FormatReadWriteExample
Turtle (.ttl)@prefix ex: <http://example.org/> . ex:Alice a ex:Person .
N-Triples (.nt)<http://example.org/Alice> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Person> .
RDF/XML (.rdf)<rdf:Description rdf:about="http://example.org/Alice">
JSON-LD (.jsonld){"@id": "http://example.org/Alice", "@type": "Person"}

Is SPARQL fully implemented?

SPARQL parser infrastructure is in place (via the spargebra crate), but query execution is not yet operational. The focus is on the OpenCypher engine.

Example of what will be supported:

PREFIX ex: <http://example.org/>
SELECT ?name ?age
WHERE {
  ?person a ex:Person .
  ?person ex:name ?name .
  ?person ex:age ?age .
  FILTER (?age > 25)
}
ORDER BY ?name

See RDF & SPARQL.

Can I use RDF and property graph data together?

A mapping framework (MappingConfig) is defined for converting between RDF triples and property graph nodes/edges. Automatic bidirectional conversion is on the roadmap.

Example of the conceptual mapping:

RDF Triple:  <ex:Alice>  <ex:knows>  <ex:Bob>
                  ↕              ↕           ↕
Property Graph:  (:Person {uri: 'ex:Alice'}) -[:knows]-> (:Person {uri: 'ex:Bob'})

SDKs & Integration

Which SDKs are available?

SDKLanguageTransportInstall
samyama-sdkRustEmbedded + HTTPcargo add samyama-sdk
samyamaPythonEmbedded + HTTP (PyO3)pip install samyama
samyama-sdkTypeScriptHTTP onlynpm install samyama-sdk
samyama-cliCLIHTTPcargo install samyama-cli

Can I embed Samyama in my application without running a server?

Yes. The Rust SDK’s EmbeddedClient runs the full engine in-process with zero network overhead:

#![allow(unused)]
fn main() {
use samyama_sdk::{EmbeddedClient, SamyamaClient};

let client = EmbeddedClient::new();

// Write data
client.query("default", "CREATE (n:Person {name: 'Alice', age: 30})").await?;
client.query("default", "CREATE (n:Person {name: 'Bob', age: 25})").await?;

// Query data
let result = client.query("default", "MATCH (n:Person) WHERE n.age > 28 RETURN n.name").await?;
println!("{:?}", result.rows);  // [["Alice"]]
}

How do I use the CLI?

# Single query
samyama-cli query "MATCH (n:Person) RETURN n.name, n.age" --format table

# Output:
# +-------+-----+
# | n.name| n.age|
# +-------+-----+
# | Alice |  30  |
# | Bob   |  25  |
# +-------+-----+

# Interactive REPL
samyama-cli shell
samyama> MATCH (n) RETURN count(n)
samyama> CREATE (n:City {name: 'Mumbai', population: 20000000})

# Server status
samyama-cli status --format json

# Health check
samyama-cli ping

Does the Python SDK support algorithms directly?

Yes (v0.6.0+). The Python SDK provides direct method-level algorithm access in embedded mode, in addition to Cypher CALL algo.* queries:

from samyama import SamyamaClient

# Embedded mode (no server required)
client = SamyamaClient.embedded()

# Create data
client.query("default", "CREATE (a:Person {name: 'Alice'})-[:KNOWS]->(b:Person {name: 'Bob'})")

# Direct algorithm methods (embedded mode only)
scores = client.page_rank("Person", "KNOWS", damping=0.85, iterations=20)
components = client.wcc("Person", "KNOWS")
distances = client.bfs("Person", "KNOWS", start_node_id=0)
shortest = client.dijkstra("Person", "KNOWS", source_id=0, target_id=1, weight_property="weight")

# Also available: scc(), pca(), triangle_count()

# Or via Cypher (works in both embedded and remote mode)
result = client.query("default", """
    CALL algo.pagerank({label: 'Person', edge_type: 'KNOWS', iterations: 20})
    YIELD node, score
""")

How do I use the TypeScript SDK?

import { SamyamaClient } from 'samyama-sdk';

const client = SamyamaClient.connectHttp('http://localhost:8080');

// Query
const result = await client.query('default', 'MATCH (n:Person) RETURN n.name');
console.log(result.rows);

// Create data
await client.query('default', `
  CREATE (a:Person {name: 'Alice'})-[:KNOWS]->(b:Person {name: 'Bob'})
`);

Project & Commercial

What is Samyama’s motivation and long-term vision?

Samyama was born from the observation that existing graph databases force users to choose between performance (C++/Rust in-memory engines), features (Cypher, vector search, NLQ, graph algorithms), and operational simplicity (easy deployment, Redis protocol compatibility). We believe a modern graph database should deliver all three.

The name “Samyama” comes from Sanskrit — it means “integration” or “bringing together.” The database integrates property graphs, vector search, natural language queries, graph algorithms, and constrained optimization into a single engine.

Long-term, Samyama aims to be the converged graph + AI database — where graph structure, vector embeddings, and LLM-powered queries work together natively, not as bolted-on features.

How do you plan to maintain this over 6–8 years?

Three pillars:

  1. Rust as a foundation: Rust’s memory safety, zero-cost abstractions, and absence of garbage collection give us a codebase that is inherently more maintainable than C++ (no memory bugs) and more performant than JVM-based alternatives (no GC pauses). The compiler catches entire classes of bugs at compile time.

  2. Open-core model: The Community Edition (Apache 2.0) ensures the core engine always has community scrutiny and contributions. Enterprise features (monitoring, backup, GPU, audit) are layered on top — they don’t fork the core. This means maintenance effort focuses on one engine, not two.

  3. Revenue-funded engineering: The Enterprise tier funds dedicated engineering. We’re not dependent on VC funding cycles. The pricing model (data-scale tiers, not per-seat) ensures revenue grows with customer success.

We also invest heavily in automated quality: 250+ unit tests, 10 benchmark suites, LDBC Graphalytics validation (100% pass rate), and LDBC SNB Interactive/BI benchmarks run on every release.

What features are Enterprise-only vs. open source?

The core principle: Enterprise gates operations, not functionality. The full query engine, all algorithms, vector search, NLQ, persistence, and multi-tenancy are in the open-source Community Edition. Enterprise adds:

Enterprise-Only FeatureWhy Enterprise
GPU acceleration (wgpu shaders)Hardware-specific, driver dependencies
Prometheus metrics / health checksProduction monitoring
Backup & restore (full/incremental/PITR)Data protection SLA
Audit loggingCompliance (SOC2, GDPR)
Enhanced Raft (HTTP/2 transport, snapshot streaming)Production HA
ADMIN commands (CONFIG, STATS, TENANTS)Operational control

How is the Enterprise edition priced?

Samyama uses a data-scale + cluster-size pricing model — not per-seat, not per-CPU, not per-query. Pricing is transparent and published:

TierPriceData LimitClusterSupport
CommunityFreeUnlimited1 nodeGitHub community
Pro$499/mo ($4,990/yr)10M nodesUp to 3 nodesEmail, 48h SLA
Enterprise$2,499/mo ($24,990/yr)100M nodesUnlimited24/7, 4h Sev1 SLA
Dedicated CloudContact salesUnlimitedUnlimitedNamed TAM, 1h Sev1 SLA

Annual commitment saves 17%. Multi-year (3-year) saves 30%.

We deliberately avoid per-CPU/per-core licensing — customers shouldn’t worry about hardware choices. Price scales with the value delivered (data size, operational maturity), not with infrastructure decisions.

Do you provide support? What does it look like?

TierSupport LevelResponse Time
CommunityGitHub Issues, community forumsBest-effort
ProEmail support48h for general, 24h for Sev1
Enterprise24/7 support, phone escalation4h for Sev1, 8h for Sev2
DedicatedNamed Technical Account Manager1h for Sev1, custom SLA

Add-ons available: dedicated support engineer (+$2,000/mo), premium SLA upgrade (+$500/mo), custom integration/consulting ($250/hr).

Is the pricing recurring or one-time? Per-CPU?

Recurring — monthly or annual subscription. Annual prepay saves 17%.

We explicitly avoid per-CPU/per-core licensing. The pricing model is based on data scale (node count) and cluster size (number of HA nodes). Customers can run on any hardware without license implications — whether it’s a 4-core laptop or a 128-core server.

Do you offer OEM licensing?

Yes. For partners who embed Samyama within their own product or manage it on behalf of their clients, we offer OEM / Embedded licensing with:

  • White-label deployment: No Samyama branding visible to end customers
  • Volume-based pricing: Per-deployment or per-end-customer pricing rather than per-instance
  • Redistribution rights: Bundle Samyama binaries within your product installer
  • Dedicated integration support: Engineering assistance for embedding and customization

OEM licensing is structured as a custom annual agreement. Contact sales for terms that match your deployment model (SaaS platform, managed service, on-prem appliance, etc.).

BiomedQA Benchmark FAQ

Why does GPT-4o standalone (75%) outperform text-to-Cypher (0%)?

These are fundamentally different tasks, not the same task with different accuracy.

GPT-4o Standalone (75%) — No Database at All

This is not generating queries. GPT-4o answers from its training data memory:

Question: "What genes does Metformin target?"
GPT-4o: "Metformin primarily targets AMPK (AMP-activated protein kinase),
         and also interacts with PPARG, OCT1/SLC22A1..."

It gets 75% because GPT-4o has strong pharmacology knowledge baked in from medical literature. It knows what Metformin does. We evaluate by checking if the answer text contains the expected values (e.g., does “PPARG” appear in the response).

Where it fails (25%): Questions requiring precise identifiers (“What’s the DrugBank ID of Tamoxifen?”), exact counts (“How many side effects does Warfarin have?”), and shared-target queries that need database-level precision.

Text-to-Cypher (0%) — Generates Queries, All Fail Silently

We did provide schema + 3 few-shot examples in the system prompt:

System prompt:
  "You are a Cypher query expert. Given a graph database schema and a question,
   generate ONLY the Cypher query..."

  SCHEMA: 19 node labels, 12 edge types, property names...

  3 FEW-SHOT EXAMPLES

GPT-4o generates syntactically valid Cypher that looks correct but returns empty results:

Example 1: Hallucinated property filter

Question: "What are the approved indications for Metformin?"

GPT-4o generates:
  MATCH (d:Drug {name: 'Metformin'})-[:HAS_INDICATION {method: 'approved'}]->(i:Indication)
  RETURN i.name

Problem: The edge HAS_INDICATION has no {method: 'approved'} property in our
actual data — GPT-4o hallucinated that filter. Query runs successfully but
returns EMPTY result set.

Example 2: Subtle schema mismatch

Question: "Which proteins participate in the Apoptosis pathway?"

GPT-4o generates:
  MATCH (p:Protein)-[:PARTICIPATES_IN]->(pw:Pathway {name: 'Apoptosis'})
  RETURN p.uniprot_id

Problem: Query looks perfect but returns empty because of how the
snapshot import remapped node IDs — the property pattern matching has
subtle mismatches with the actual graph structure.

Error Breakdown

The 0% is NOT syntax errors — it’s the insidious “plausible but wrong” failure mode:

Error CategoryCountExample
Schema mismatch (empty result)33 (82%)Hallucinated property filters, wrong property names
Incorrect multi-MATCH pattern6 (15%)Comma-separated MATCH that engine handles differently
Non-existent filter constraint1 (3%){method: 'approved'} doesn’t exist

Why 3 Examples Weren’t Enough

The schema has 19 node labels and 12 edge types across 3 federated KGs. Three examples can’t cover:

  • Which properties exist on which edges (HAS_INDICATION has method but not value 'approved')
  • How multi-MATCH patterns resolve across snapshot-imported nodes
  • The exact casing and property names (gene_name vs name vs uniprot_id)

With more examples or fine-tuning, text-to-Cypher would likely reach 30–50%. But MCP tools would still dominate because templates eliminate the entire class of schema-mismatch errors.

The Key Insight

Standalone GPT-4o (75%):  LLM answers from MEMORY — no query, no database
                          Good for general knowledge, bad for precision

Text-to-Cypher (0%):      LLM generates QUERIES — syntactically valid but
                          semantically wrong. Silent failures. Dangerous.

MCP Tools (98%):           LLM SELECTS pre-authored tools — deterministic,
                          auditable, no schema hallucination possible

The paradox is intentional: knowing the answer (75%) beats generating the query (0%). This is exactly why the “inverted-LLM” pattern works — don’t ask the LLM to write code, ask it to pick from a menu.


Could text-to-Cypher improve with better prompting?

Yes. The Remote Planet demo achieved 100% NLQ accuracy (12/12) with Ollama qwen2.5-coder:14b by:

  1. Including full schema with edge directions in the system prompt (not just labels)
  2. Adding property type annotations (String, Float, Boolean) and value casing rules (e.g., severity="critical" lowercase, Region.name="Scotland" title-case)
  3. Adding 3 few-shot examples covering edge counting, variable-length paths, and aggregation
  4. Iterating the system prompt through 4 versions (42% → 67% → 75% → 100%)

However, that was on a single KG with 10 node labels. The BiomedQA benchmark spans 3 federated KGs with 19 labels — the schema complexity is much higher, making text-to-Cypher fundamentally harder.

Why not combine both? (MCP tools + text-to-Cypher fallback)

This is planned (see backlog item AI-11). The architecture:

  1. LLM first tries to match a domain-specific MCP tool (98% accuracy)
  2. If no tool matches → fall back to Samyama Enterprise’s NLQ endpoint
  3. NLQ pipeline has direct schema access, safety validation, and its own LLM call
  4. Expected hybrid accuracy: ~98% for known patterns + ~50% for long-tail questions

See MCP Tool Catalog — Architecture for sequence diagrams.


Benchmark Details

BiomedQA benchmark: 40 pharmacology questions across 7 categories over 3 federated KGs (7.9M nodes).

ApproachAccuracyAvg LatencyAvg TokensHow It Works
GPT-4o standalone30/40 (75%)2,474ms213Answers from training data memory
Text-to-Cypher0/40 (0%)986ms548Generates Cypher, executes against graph
MCP tools39/40 (98%)651ms0Selects pre-authored tool, deterministic execution

Hardware: AWS g4dn.4xlarge (16 vCPU AMD EPYC, 62GB RAM, NVIDIA A10G) Graph: Pathways (119K nodes) + Drug Interactions (245K nodes) + Clinical Trials (7.7M nodes) Verified: 3 independent fresh-load runs, all producing 39/40 (98%)

Glossary

Key terms and concepts used throughout this book, organized alphabetically.


Adjacency List
A graph representation where each node stores a list of its outgoing and incoming edge IDs. Used in GraphStore for fast neighbor lookups. O(1) access to a node’s neighbors.
AGE (Autonomous Graph Evolution)
AI agents that build knowledge graphs from unstructured data — entity extraction + relationship detection. Supports customer-defined regex patterns (deterministic, confidence=1.0) and/or LLM-based extraction (additive, schema-constrained). Per-tenant configurable. Tagline: “Paste any text, get a knowledge graph.” See also GAK (which enriches existing graphs rather than building them). Enterprise feature.
Agentic Enrichment
See GAK.
Arena Allocation
A memory management pattern where objects are allocated in contiguous blocks rather than scattered heap allocations. Samyama uses a versioned arena (Vec<Vec<T>>) for nodes and edges, giving cache-friendly sequential memory access.
AST (Abstract Syntax Tree)
The intermediate tree representation produced by the Pest parser after parsing a Cypher query string. Transformed by the QueryPlanner into a physical execution plan.
Bincode
A Rust-specific binary serialization format used for RocksDB value encoding. Faster than JSON or Protobuf for Rust-to-Rust communication. Used to serialize StoredNode and StoredEdge structs.
CAP Theorem
States that a distributed system can provide only two of three guarantees: Consistency, Availability, Partition Tolerance. Samyama chooses CP (Consistency + Partition Tolerance) via Raft.
CDLP (Community Detection via Label Propagation)
A graph algorithm where each node adopts the most frequent label among its neighbors. Converges to natural community boundaries. LDBC Graphalytics standard.
Column Family
A RocksDB feature that logically partitions data. Samyama uses column families for tenant isolation (separate compaction, backup, and key namespaces per tenant).
ColumnStore
Samyama’s columnar property storage. Stores all values of a given property (e.g., all “ages”) in a contiguous array, enabling cache-efficient analytical queries and late materialization.
Cost-Based Optimizer (CBO)
The query planning component that uses GraphStatistics (label counts, edge counts, property selectivity) to choose between execution strategies (e.g., IndexScan vs. NodeScan).
CSR (Compressed Sparse Row)
A compact, read-only graph representation using three arrays (out_offsets, out_targets, weights). Used for OLAP algorithm execution because sequential memory access enables CPU prefetching.
Cypher
A declarative graph query language originally created by Neo4j. Samyama supports ~90% of the OpenCypher specification.
EdgeId
A u64 integer serving as a direct index into the edge storage arena. Like NodeId, this gives O(1) access without hashing.
Embedded Mode
Running the Samyama engine in-process (no server) via EmbeddedClient. Zero network overhead, full access to algorithms, vector search, and persistence APIs.
EXPLAIN
A Cypher prefix that returns the physical execution plan without executing the query. Shows operator tree, estimated row counts, and graph statistics.
GAK (Generation-Augmented Knowledge)
Samyama’s paradigm where the database uses LLMs to autonomously discover and create missing data, inverting the traditional RAG pattern. The database actively builds its own knowledge graph.
GraphStatistics
Runtime statistics maintained by GraphStore: label counts, edge type counts, average degree, and property stats (null fraction, distinct count, selectivity). Used by the cost-based optimizer.
GraphStore
The core in-memory storage structure. Contains versioned arenas for nodes/edges, adjacency lists, column stores, vector indices, and property indices.
GraphView
The CSR representation of a projected subgraph, used as input to all algorithms in samyama-graph-algorithms. Immutable once built, enabling zero-lock parallel processing.
HNSW (Hierarchical Navigable Small World)
An approximate nearest neighbor search algorithm for vector indexing. Provides logarithmic search complexity with high recall. Implemented via the hnsw_rs crate.
JET (JSON Enablement Token)
The Enterprise license format: base64(header).base64(payload).base64(signature) with Ed25519 signing. Contains org, features, expiry, and machine fingerprint.
Label
A string tag on a node that categorizes it (e.g., Person, Account). Nodes can have multiple labels. Labels are indexed for fast scanning.
Late Materialization
An optimization where scan operators produce Value::NodeRef(id) references instead of full node clones. Properties are resolved on-demand only at the ProjectOperator, reducing memory bandwidth by 4-5x.
LDBC Graphalytics
The industry-standard benchmark suite for graph analytics correctness and performance. Samyama passes 28/28 tests across 6 algorithms on XS and S-size datasets.
LSM-Tree (Log-Structured Merge-Tree)
The storage engine architecture used by RocksDB. Converts random writes into sequential appends, optimizing for write-heavy workloads like graph databases.
MCP (Model Context Protocol)
Anthropic’s open standard for connecting LLMs to external tools and data sources. Samyama exposes graph queries as MCP tools, enabling LLM agents to query the knowledge graph via pre-authored Cypher templates. Achieves 98% accuracy on BiomedQA benchmark vs. 0% for text-to-Cypher. See sdk/python/samyama_mcp/.
Mechanical Sympathy
Designing software to align with hardware characteristics (CPU caches, memory access patterns, SIMD lanes). A core design principle throughout Samyama.
Metaheuristic
A nature-inspired optimization algorithm that searches for “good enough” solutions in complex spaces. Samyama implements 22 metaheuristics (Jaya, PSO, DE, GWO, NSGA-II, etc.).
MVCC (Multi-Version Concurrency Control)
A concurrency technique where readers see a consistent snapshot while writers create new versions. Samyama implements MVCC via version chains in the node/edge arenas.
NodeId
A u64 integer serving as a direct index into the versioned node arena (Vec<Vec<Node>>). This eliminates hash lookups, giving O(1) access with cache-friendly contiguous memory.
NodeRef
A lightweight Value::NodeRef(NodeId) used in late materialization. Carries only the ID, not the full node data. Properties are resolved lazily via resolve_property().
NLQ (Natural Language Query)
The pipeline that converts natural language questions to Cypher queries using LLMs. Supports OpenAI, Gemini, Ollama, and Claude providers.
NSGA-II (Non-dominated Sorting Genetic Algorithm II)
A multi-objective optimization algorithm that finds Pareto-optimal solutions. Used with the Constrained Dominance Principle for feasible-first selection.
OpenCypher
The open standard for the Cypher query language, maintained by the openCypher project. Samyama implements ~90% of the specification.
Pareto Front
The set of solutions where no objective can be improved without worsening another. NSGA-II and MOTLBO return Pareto fronts for multi-objective optimization.
PCA (Principal Component Analysis)
A dimensionality reduction technique that projects high-dimensional data onto principal components. Samyama implements Randomized SVD (Halko et al.) and Power Iteration solvers.
PEG (Parsing Expression Grammar)
A formal grammar type that uses ordered choice (tries alternatives left-to-right). Samyama’s Cypher parser uses the Pest PEG library.
PhysicalOperator
The trait implemented by all 35 execution operators. Each operator processes RecordBatches in a pull-based Volcano model.
PITR (Point-in-Time Recovery)
Enterprise feature that restores the database to an exact timestamp by replaying WAL entries against a snapshot.
PROFILE
A planned Cypher prefix (not yet implemented) that will execute the query and return actual row counts and timing per operator, complementing EXPLAIN.
PropertyValue
The union type for node/edge properties: String, Integer, Float, Boolean, DateTime, Array, Map, or Null.
Raft
A consensus algorithm for distributed systems. Ensures all nodes agree on the log order. Samyama uses the openraft crate for leader election, log replication, and quorum commits.
Rayon
A Rust parallel computing library used for data-parallel algorithm execution. Enables zero-overhead parallel iteration over CSR arrays.
RDF (Resource Description Framework)
A W3C standard for representing knowledge as subject-predicate-object triples. Samyama supports RDF with SPO/POS/OSP indexing and Turtle/N-Triples/RDF-XML serialization.
RecordBatch
The internal data structure passed between operators in the Volcano model. Contains columns of Values and supports batch processing of 1,024 records at a time.
RESP (Redis Serialization Protocol)
The wire protocol used by Redis clients. Samyama implements RESP3 for backward compatibility with the Redis ecosystem.
RocksDB
An embedded key-value store based on LSM-Trees, originally forked from LevelDB by Facebook. Samyama uses it for persistent storage with Column Families for multi-tenancy.
Selectivity
The fraction of rows that satisfy a filter predicate. Low selectivity (e.g., 0.01 = 1%) means the filter is highly selective, favoring index scans.
Snapshot Isolation
A concurrency level where each query sees a consistent point-in-time view of the database, regardless of concurrent writes. Achieved via MVCC version chains.
SPARQL
The W3C standard query language for RDF data. Parser infrastructure is in place via spargebra; query execution is in development.
Volcano Model
A query execution model where operators form a tree and data flows bottom-up via next_batch() calls. Each operator pulls from its children on demand (lazy evaluation).
WAL (Write-Ahead Log)
A sequential log where all mutations are written before being applied to the main storage. Ensures durability: if the process crashes, uncommitted changes can be replayed.
wgpu
The Rust implementation of the WebGPU API. Used in Samyama Enterprise for GPU-accelerated graph algorithms via WGSL compute shaders targeting Metal, Vulkan, and DX12.
WGSL (WebGPU Shading Language)
The shader language for WebGPU compute kernels. Samyama Enterprise uses WGSL shaders for PageRank, CDLP, LCC, Triangle Counting, PCA, and vector distance operations.

Publication Tracker

Public-facing record of Samyama-related research publications. Manuscript sources, reviewer feedback, and submission timelines live in the private samyama-research repository.

Papers

#TitleVenuePublic linkStatus
1Samyama: Unified Graph-Vector Databasearxiv preprint → VLDB 2027arxiv:2603.08036Preprint published; v3 in preparation incorporating v1.0.0 + hero-run results (187.5M nodes / 1.29B edges / 99% pass, 2026-04-30)
3Knowledge Graphs for Industrial Asset OperationsNeurIPS 2026 E&DIn preparation
4Open Biomedical Knowledge Graphs at Scalearxiv preprint → VLDB / ICDE 2027arxiv:2603.15080Preprint published; v2 ready (Drug Interactions KG, BiomedQA 98%)
5aFederated Biomedical KGs (Demo)GRADES-NDA @ SIGMOD 2026Submitted
5bFederated Biomedical KGs (In-Use)ISWC 2026 In-Use TrackSubmitted
6MCP Tools vs Text-to-CypheraiDM @ SIGMOD 2026Submitted
7Billion-Edge KG Federation on Commodity Hardwarearxiv preprint → VLDB 2027In preparation
8Graph-Grounded Optimization: Rao-Family Metaheuristics, Classical OR, and SLM-Driven Formulation over Knowledge Graphsarxiv preprintarxiv:2605.12204Preprint published 2026-05-15
VLDB 2027 Systems PaperVLDB 2027 Industry TrackIn preparation (extends Paper 1)

Benchmarks referenced in papers

BenchmarkPapersResultsHardware
LDBC SNB Interactive (21/21)1, VLDBAll pass, SF1Mac Mini M4
LDBC Graphalytics (28/28)1, VLDBAll pass, XS–SMac Mini M4
LDBC FinBench (40/40)1, VLDBAll passMac Mini M4
AssetOpsBench (139 scenarios)3, 6MCP 99% · T2C 83% · GPT-4 65%Mac Mini M4
BiomedQA (40 questions)4, 5, 6MCP 98% · T2C 85% · GPT-4o 75%AWS g4dn.4xlarge
Biomedical 100-query (74M nodes, 1B edges)7, VLDB96 / 100 passAWS r6a.8xlarge
Public Health 40-query (305K nodes)740 / 40 passMacBook Pro
Cricket 100-query (37K nodes)187 / 100Mac Mini M4
Mega Benchmark (138M nodes, 1.22B edges, 11 KGs)5b, 7, VLDB500 / 500 passAWS r7i.16xlarge
Hero Run (187.5M nodes, 1.29B edges, 1000 queries)7, VLDB99% pass (~$1.85)AWS r7i-class spot (2026-04-30)
Paper 8 demo suite (7 problems, 19.7K–7.78M nodes)8BMWR 4/7, Rao-1 2/7 wins; OR-tools 2–3× on linear/MILPLaptop / single-node

Research Paper: Samyama Overview

We have published a comprehensive research paper detailing the architecture, design decisions, and performance evaluation of Samyama Graph.

Title: Samyama: A Unified Graph-Vector Database with In-Database Optimization, Agentic Enrichment, and Hardware Acceleration

Authors: Madhulatha Mandarapu (madhulatha@samyama.ai), Sandeep Kunkunuru (sandeep@samyama.ai)

arxiv:2603.08036 · samyama-graph on GitHub

Keywords: Graph Databases, Vector Search, Distributed Systems, Metaheuristic Optimization, Rust, GPU Acceleration, Agentic AI, RDF, LDBC.


Abstract

Modern data architectures are fragmented across graph databases, vector stores, analytics engines, and optimization solvers, resulting in complex ETL pipelines and synchronization overhead. We present Samyama, a high-performance graph-vector database written in Rust that unifies these workloads into a single engine. Samyama combines a RocksDB-backed persistent store with a versioned-arena MVCC model, a vectorized query executor with 35 physical operators, a cost-based query planner with plan enumeration and predicate pushdown, a dedicated CSR-based analytics engine, and native RDF/SPARQL support. The system integrates 22 metaheuristic optimization solvers directly into its query language, implements HNSW vector indexing with Graph RAG capabilities, and introduces “Agentic Enrichment” for autonomous graph expansion via LLMs. A comprehensive SDK ecosystem (Rust, Python, TypeScript) and CLI provide multiple access patterns.

The Samyama Enterprise Edition adds GPU acceleration via wgpu (Metal, Vulkan, DX12), production-grade observability, point-in-time recovery, and hardened high availability with HTTP/2 Raft transport.

Our evaluation on commodity hardware (Mac Mini M4, 16GB RAM) demonstrates:

  • Ingestion: 255K nodes/s (CPU), 412K nodes/s (GPU-accelerated), 4.2M–5.2M edges/s
  • OLTP throughput: 115K Cypher queries/sec at 1M nodes
  • Late materialization: 4.0–4.7x latency reduction on multi-hop traversals
  • GPU PageRank: 8.2x speedup at 1M nodes
  • LDBC Graphalytics: 28/28 tests passed (100% validation)

Paper Structure (10 Sections)

1. Introduction

Motivates the need for a unified graph-vector-optimization engine. Identifies 8 key contributions: unified engine, late materialization, in-database optimization, agentic enrichment (GAK), GPU acceleration, SDK ecosystem, RDF interoperability, and 100% LDBC Graphalytics validation.

2. System Architecture

Covers four subsystems:

  • Storage Engine: RocksDB with LSM-tree, LZ4/Zstd compression, Column Families for multi-tenant isolation. NodeId/EdgeId as direct u64 arena indices for O(1) access.
  • Memory Management & MVCC: Versioned-arena (Vec<Vec<T>>) for Snapshot Isolation without read locks. ACID guarantees via WriteBatch + WAL + Raft quorum.
  • Query & Execution Engine: ~90% OpenCypher via PEG parser (pest). Hybrid Volcano-Vectorized model with 35 physical operators and batch size 1,024. Cost-based optimizer using GraphStatistics. Late materialization via Value::NodeRef(id).
  • RDF & SPARQL: Native RDF via oxrdf with SPO/POS/OSP triple indices, Turtle/N-Triples/RDF-XML serialization, and spargebra SPARQL parser.

3. High-Performance Analytics

  • CSR Projection: GraphView with out_offsets/out_targets/weights arrays for cache-efficient traversal with near-perfect CPU prefetch accuracy.
  • Algorithm Library: 14 algorithms across centrality (PageRank, LCC), community (WCC, SCC, CDLP, Triangle Counting), pathfinding (BFS, Dijkstra), network flow (Edmonds-Karp, Prim’s MST), and statistical (PCA with Randomized SVD + Power Iteration).

4. In-Database Optimization

22 metaheuristic solvers accessible via CALL algo.or.solve(...) Cypher procedures. Covers metaphor-less (Jaya, QOJAYA, Rao 1-3, TLBO, ITLBO, GOTLBO), swarm/evolutionary (PSO, DE, GA, GWO, ABC, BAT, Cuckoo, Firefly, FPA), physics-based (GSA, SA, HS, BMR, BWR), and multi-objective (NSGA-II, MOTLBO) families. All solvers use Rayon for parallel fitness evaluation.

5. AI & Agentic Enrichment

  • Vector Search: HNSW indexing via hnsw_rs with Cosine, L2, Dot Product metrics. VectorSearchOperator enables Graph RAG.
  • GAK (Generation-Augmented Knowledge): AgentRuntime with tool-calling agents for autonomous graph expansion. Safety validation includes schema checking and destructive query rejection.
  • NLQ Pipeline: Natural language to Cypher via OpenAI, Gemini, Ollama, or Claude providers.

6. SDK Ecosystem

Multi-language SDKs: Rust (SamyamaClient trait with EmbeddedClient/RemoteClient, AlgorithmClient/VectorClient extension traits), Python (PyO3), TypeScript (HTTP), CLI (query/status/ping/shell), and OpenAPI.

7. Enterprise Edition

  • GPU Acceleration: wgpu compute shaders (Metal/Vulkan/DX12) for PageRank, CDLP, LCC, Triangle Counting, PCA. GPU PCA uses 5 specialized WGSL shaders with tiled covariance.
  • Observability: 200+ Prometheus metrics, health probes, audit trail, slow query log.
  • Backup & PITR: Full + incremental snapshots with microsecond-precision restore.
  • Hardened HA: HTTP/2 Raft transport with TLS, snapshot streaming, cluster metrics.
  • License Hardening: Ed25519 JET tokens with machine fingerprint binding and revocation lists.

8. Performance Evaluation

Comprehensive benchmarks on Mac Mini M4 (16GB RAM):

BenchmarkResult
Node Ingestion (CPU / GPU)255K / 412K ops/s
Edge Ingestion (CPU / GPU)4.2M / 5.2M ops/s
Cypher OLTP (1M nodes)115,320 QPS at 0.008ms
Late Materialization4.0x (1-hop), 4.7x (2-hop)
GPU PageRank (1M nodes)8.2x speedup (11.2 ms)
Vector Search (10K, 128d)15,872 QPS
LDBC Graphalytics28/28 (100%)

GPU crossover: ~100K nodes for general algorithms, ~50K for PCA.

Compares against Neo4j (JVM GC pauses), FalkorDB (no vector/optimization), Kuzudb (analytical-only), and DuckDB (relational, no native graph). Samyama differentiates by unifying OLTP, OLAP, vector, and optimization in one memory-safe binary.

10. Conclusion

Samyama bridges transactional integrity and analytical intelligence. 100% LDBC validation confirms algorithmic correctness. The SDK ecosystem lowers adoption barriers across Rust, Python, and TypeScript.


Visualizations

The paper includes several illustrations detailing the system’s design:

1. Unified Engine Architecture

A high-level view of how the RESP protocol interacts with the Cypher parser, which in turn orchestrates the Vectorized Executor across the HNSW (Vector) and RocksDB (Graph) indices. Samyama Architecture

2. The Optimization Frontier

A Pareto front chart illustrating how the NSGA-II solver identifies optimal trade-offs in multi-objective resource allocation directly on the graph. Pareto Front

3. JIT Knowledge Graph Expansion

A sequence diagram showing the Agentic Enrichment loop: an event trigger initiates an LLM search which automatically creates new nodes and edges, “healing” the graph’s missing knowledge. Agentic Loop


Implemented Research

For a comprehensive list of the specific academic algorithms, models, and architectures implemented directly within the Samyama codebase, see the Index of Implemented Papers.


Manuscript sources, reviewer feedback, and reproduction artifacts live in the private samyama-research repository under papers/paper1-samyama-systems/. The summary above reflects the arxiv preprint as published; the v3 update with billion-edge federation results is in preparation.

Research Paper: Open Biomedical Knowledge Graphs at Scale

We have published a research paper on constructing, federating, and querying biomedical knowledge graphs with Samyama.

Title: Open Biomedical Knowledge Graphs at Scale: Construction, Federation, and AI Agent Access with Samyama Graph Database

Authors: Madhulatha Mandarapu (madhulatha@samyama.ai), Sandeep Kunkunuru (sandeep@samyama.ai)

arxiv:2603.15080 · Pathways KG · Clinical Trials KG

Keywords: Knowledge Graphs, Biomedical Data Integration, Graph Databases, Cross-KG Federation, Model Context Protocol, Clinical Trials, Biological Pathways, OpenCypher.


Abstract

Biomedical knowledge is fragmented across siloed databases — Reactome for pathways, STRING for protein interactions, Gene Ontology for functional annotations, ClinicalTrials.gov for study registries, and dozens more. We present two open-source biomedical knowledge graphs — Pathways KG (118,686 nodes, 834,785 edges from 5 sources) and Clinical Trials KG (7,711,965 nodes, 27,069,085 edges from 5 sources) — built on Samyama, a high-performance graph database written in Rust.

Our contributions are threefold:

  1. Reproducible KG construction — ETL pipelines for two large-scale KGs using a common pattern: download, parse, deduplicate, batch-load via Cypher, and export as portable .sgsnap snapshots.

  2. Cross-KG federation — loading both snapshots into a single graph tenant enables property-based joins across datasets, answering questions like “Which biological pathways are disrupted by drugs currently in Phase 3 trials for breast cancer?”

  3. Schema-driven MCP server generation — each KG automatically exposes typed tools for LLM agents via the Model Context Protocol, enabling natural-language access without manual tool authoring.

The combined federated graph (7.83M nodes, 27.9M edges) loads in under 3 minutes on commodity hardware.


Key Results

MetricPathways KGClinical Trials KGCombined
Nodes118,6867,711,9657,830,651
Edges834,78527,069,08527,903,870
Labels51520
Edge types92534
Data sources5510
Snapshot size9 MB711 MB720 MB
Import time< 5 s~90 s~95 s

Cross-KG Federation Query Patterns

PatternTraversalLatency
Drug → PathwayTrial → Drug → Protein → Pathway2.5 s
Drug → GO ProcessTrial → Drug → Protein → GOTerm1.8 s
Drug → PPI NetworkDrug → Protein target → INTERACTS_WITH1.2 s
Disease → PathwayGene → Disease + Gene → Protein → Pathway1.8 s
Adverse Event → PathwayTrial → AE → Drug → Protein → Pathway3.2 s

Manuscript sources, reviewer feedback, and reproduction artifacts live in the private samyama-research repository under papers/paper4-biomedical-kg/.

Paper 7: Scaling Knowledge Graph Federation to One Billion Edges on Commodity Hardware

Target: arxiv preprint → seeds VLDB 2027 submission

Status: In preparation

Authors: Madhulatha Mandarapu, Sandeep Kunkunuru

Motivation

No existing open-source graph database has demonstrated billion-edge knowledge graph federation with cross-domain queries on commodity hardware at sub-$5 cost. This paper presents the engineering and data architecture that makes it possible, and evaluates it with 140 benchmark queries across 8 knowledge graphs spanning molecular biology to population health.

Key Claims

  1. 74.3 million nodes and 1.07 billion edges loaded from 4 biomedical KGs (PubMed, Clinical Trials, Pathways, Drug Interactions) in 3 hours 46 minutes on a single r6a.8xlarge AWS spot instance for $2.50 total cost
  2. 96 of 100 cross-KG queries return data on the biomedical trifecta, with latencies from 1.3s to 19.4s
  3. 305K public health nodes across 3 additional KGs (Surveillance, Health Determinants, Health Systems) with 40/40 queries passing in under 500ms each
  4. 6-KG federation from molecular biology to population health in a single Cypher query, bridged by shared properties (Country.iso_code, Drug.drugbank_id, Gene.gene_name)

Outline (10 pages)

1. Introduction (1.5 pages)

  • The fragmentation problem: biomedical + public health data spread across silos
  • Why graph databases for cross-domain federation
  • Contribution summary: scale (1B edges), cost ($2.50), breadth (6 KGs, 8 open data sources)

2. Architecture (2 pages)

  • Hybrid CSR adjacency (frozen segments + write buffer)
  • Two-phase bulk loading: node stubs (777 B/node) + edge stubs (52 B/edge)
  • Mid-phase compaction (every 50M edges)
  • Memory optimization: sparse ColumnStore, edge arena removal
  • Key insight: 13.6x memory reduction via stubs enables 1B edges on 256GB

3. Knowledge Graph Catalog (1.5 pages)

KGSourceNodesEdgesLoader
PubMed/MEDLINENLM66.2M1.04BRust (pipe-delimited)
Clinical TrialsAACT7.8M27MRust (JSON)
PathwaysReactome + STRING + GO119K835KRust (TSV/JSON)
Drug InteractionsDrugBank + 4 sources245K388KRust (TSV/CSV)
SurveillanceWHO GHO217K241KRust (JSON)
Health DeterminantsWorld Bank WDI + WHO286K286KRust (JSON/CSV)
Health SystemsWHO SPAR + NHWA20K19KRust (JSON/CSV)
Cricket (baseline)Cricsheet37K1.4MRust (JSON)

4. Federation Architecture (1.5 pages)

  • Bridge properties: iso_code (countries), drugbank_id (drugs), gene_name (genes), uniprot_id (proteins)
  • No ETL between KGs — federation via property-value matching in Cypher MATCH clauses
  • Example: molecular pathway → drug → clinical trial → disease surveillance → country vulnerability

5. Benchmark Design (1 page)

  • 100 biomedical queries: 35 PubMed, 20 Clinical Trials, 15 Pathways, 15 Drug Interactions, 15 cross-KG
  • 40 public health queries: 20 Health Determinants, 10 Health Systems, 10 cross-KG
  • Query categories: point lookup, 1-hop traversal, aggregation, cross-indicator, cross-KG federation

6. Evaluation (2 pages)

6.1 Scale (biomedical trifecta)

  • Load time: 3h46m on r6a.8xlarge (32 vCPU, 256GB), $2.50 spot
  • 96/100 queries pass, 3 empty (data gaps), 1 timeout (cartesian explosion)
  • Latency: 1.3s – 19.4s per query

6.2 Federation (public health)

  • 40/40 queries pass
  • Point lookups: 1-4ms, single-hop: 2-25ms, aggregations: 10-134ms, cross-KG: 66-478ms
  • Import time: 1.6s (286K nodes) + 0.1s (20K nodes) from .sgsnap

6.3 Cost comparison

  • Samyama: $2.50 (spot) / $200-480/mo (persistent)
  • Neo4j Aura: $2,000+/mo for comparable scale
  • AWS Neptune: $1,500+/mo
  • TigerGraph: $5,000+/mo

7. Discussion & Limitations (0.5 pages)

  • 4 failing queries: PM10 (missing grant data), PM28 (timeout), CT18 (missing edge type), DI05 (data gap)
  • Snapshot export limitation for edge-stub-loaded graphs — resolved in v1.0.0 (edges arena fully removed, DS-07c only)
  • Single-node architecture — distributed federation is future work
  • No MVCC yet — read-snapshot isolation in progress
  • LDBC benchmarking council, Neo4j GDS, TigerGraph GSQL, Kuzu, Memgraph
  • Microsoft GraphRAG, knowledge graph construction (OpenIE, DeepDive)
  • Biomedical KGs: Bio2RDF, Hetionet, PrimeKG

9. Conclusion

  • First open-source demonstration of billion-edge cross-domain KG federation
  • Reproducible: all data open, all loaders open-source, all queries published
  • 8 KGs, 8.6M+ nodes, 30M+ edges in registry, all on S3

Data Availability

All data, loaders, snapshots, queries, and results are open:

  • Snapshots: s3://samyama-data/snapshots/ + GitHub releases
  • Benchmark queries: samyama-cloud/book/src/data/benchmark/
  • Loaders: in the OSS engine repo under examples/
  • Registry: Supabase kg_registry table

Manuscript sources, reviewer feedback, and reproduction artifacts live in the private samyama-research repository under papers/paper7-billion-edge/. The broader 11-KG mega-benchmark (138M nodes, 1.22B edges, 500/500 pass) — which extends this paper’s biomedical-trifecta scope — is documented in the Mega Benchmark chapter and Paper 5b: ISWC 2026 In-Use.

Research Paper: Graph-Grounded Optimization

Title: Graph-Grounded Optimization: Rao-Family Metaheuristics, Classical OR, and SLM-Driven Formulation over Knowledge Graphs

Authors: Madhulatha Mandarapu (madhulatha@samyama.ai), Sandeep Kunkunuru (sandeep@samyama.ai)

arxiv:2605.12204 · Published 2026-05-15

Keywords: Knowledge Graphs, Optimization, Rao-Family Metaheuristics, OR-Tools, Small Language Models, Cypher, Property Graph Databases.


Abstract

What if optimization problems were sourced from a knowledge graph instead of a paragraph of English? We introduce graph-grounded optimization: a paradigm where the objective, decision variables, and constraints of an optimization problem are sourced from a property knowledge graph via Cypher queries, rather than from a natural-language description.

We evaluate seven real-world problems — drug repurposing, clinical-trial site selection, supply-chain rerouting, healthcare allocation, grid dispatch, antimicrobial-resistance stewardship, and wildfire evacuation — over public knowledge graphs ranging from 19.7K to 7.78M nodes, all expressed as Cypher against Samyama. We benchmark five Rao-family metaheuristics (BMWR, Jaya, SAMP-Jaya, EHR-Jaya, Rao-1) against Google OR-tools (CP-SAT, GLOP) and SLM baselines (Phi-4, GPT-4.1, o3, gpt-5.5, OptiMind-SFT) in schema-aware and blind settings.


Key Findings

  • No single Rao variant dominates across problems. BMWR wins 4/7; Rao-1 wins 2/7. Variant choice is problem-dependent.
  • Classical OR is still the right tool for linear/MILP-shaped problems, beating metaheuristics by 2–3× in solution quality where structure permits.
  • Zero-shot SLMs collapse on real formulations. Phi-4: 0/7 exact. GPT-4.1: 2/7. The failures are schema-alignment failures, not reasoning failures — a model that never sees the KG cannot formulate against it.
  • Graph-grounding surfaces data-quality issues that text-based formulation quietly hides.

Architecture: Two Invocation Paths

The same samyama-optimization crate is used in two distinct invocation patterns:

  1. In-database stored procedure — production path. Cypher CALL algo.or.solve({...}) dispatches into the executor (see samyama-graph/src/query/executor/operator.rs and ADR-026), which constructs a Problem from a Cypher-projected table and runs the chosen solver.
  2. Standalone Rust harness — paper-8 benchmarks. Each problem (p1…p7) is an independent Rust binary that links the same crate directly, loads a .sgsnap snapshot, builds the Problem in-process, and runs the solver per seed. This is the path used for the published benchmark numbers.

Both paths exercise the same solver code; the harness path adds per-seed reproducibility and avoids the protocol round-trip overhead that would dominate small-N benchmarks.

Solver Inventory (crates/samyama-optimization)

Single-objective: JayaSolver, RaoSolver (with RaoVariant), TLBOSolver, FireflySolver, CuckooSolver, GWOSolver, GASolver, SASolver, BatSolver, ABCSolver, GSASolver, HSSolver, FPASolver. Multi-objective: NSGA2Solver, MOTLBOSolver, plus the BMWR / MO-BMR / MO-BWR / MO-BMWR / SAMP-Jaya / SAPHR / EHR-Jaya / QO-Rao extensions covered in ADR-026.

Why It Matters for Samyama

Graph-grounded optimization is the prescriptive endgame of BI: descriptive dashboards say what happened, predictive models say what’s likely, but the actual decision — what should we do about it — is an optimization problem. By making that step a first-class CALL algo.or.solve operation over the same graph that holds the entities and relationships, Samyama removes the export/import seam that normally separates analytics from optimization.

Artifacts

  • Paper: arxiv:2605.12204
  • Optimization crate: samyama-graph/crates/samyama-optimization/
  • ADR-026: Rao-Family Optimization Crate (docs/ADR/ADR-026-rao-optimization-crate.md)
  • Paper-8 standalone harnesses: samyama-research/papers/paper8-graph-grounded-optimization/06-aws-cycles/p{1..7}/src/main.rs
  • SLM baseline harness: samyama-research/papers/paper8-graph-grounded-optimization/05-baselines/slm/optimind/

Paper 5a: Federated Biomedical Knowledge Graphs — GRADES-NDA @ SIGMOD 2026

Title: [Demo] Federated Biomedical Knowledge Graphs: Graph-Native Storage, Planning, and AI-Agent Integration

Venue: GRADES-NDA Workshop at SIGMOD 2026, Bengaluru, India (June 5, 2026)

Status: Submitted

Authors: Madhulatha Mandarapu, Sandeep Kunkunuru

Summary

Demo paper showing three federated biomedical knowledge graphs (Pathways, Clinical Trials, Drug Interactions) queryable through a single Cypher interface. Demonstrates graph-native query planning, cross-KG federation via shared property bridges, and MCP tool integration for AI-agent access.

The full In-Use track companion paper covering the 11-KG federated mega-benchmark is Paper 5b.

Key Results

  • 3 KGs federated: 7.9M nodes, 28M edges
  • BiomedQA: MCP 98% · Text-to-Cypher 85% · GPT-4o standalone 75%
  • Graph-native planner: cost-based selection across multiple candidate plans per query

Manuscript sources, reviewer feedback, and reproduction artifacts live in the private samyama-research repository under papers/paper5-grades-nda/.

Paper 5b: Federated Biomedical Knowledge Graphs — ISWC 2026 In-Use Track

Title: Federated Biomedical Knowledge Graphs at Scale: A Single-Server, Single-Query Substrate for AI Agents

Venue: International Semantic Web Conference (ISWC) 2026, In-Use Track

Status: Submitted

Authors: Madhulatha Mandarapu, Sandeep Kunkunuru

Summary

Companion to the GRADES-NDA demo: a full In-Use track paper documenting the production deployment of 11 federated biomedical and public-health knowledge graphs on a single Samyama Graph server, queryable through a single OpenCypher interface and exposed to AI agents via MCP tools.

The paper covers the engineering choices that make federation tractable on commodity hardware — graph-native query planning, columnar property storage with late materialization, adjacency-aware aggregation for degree-bounded queries, and MVCC for concurrent reader/writer workloads — and reports the 500/500-pass result on the federated benchmark.

Key Results

  • 11 KGs federated: ~138M nodes, 1.22B edges, single server (r7i.16xlarge spot)
  • 500-query mega-benchmark: 500 / 500 pass (468 full-pass + 32 corpus-gap data-dependent, 0 errors)
  • Total benchmark runtime: 78 minutes (load + query)
  • BiomedQA via MCP tools: 98% accuracy

Files

Manuscript sources, build scripts, and reproduction artifacts (B3 baselines, LDBC calibration logs) live in the private samyama-research repository under papers/paper5-iswc-inuse/.

Paper 6: MCP Tools vs Text-to-Cypher — aiDM @ SIGMOD 2026

Title: Domain-Specific MCP Tools vs. Generic Text-to-Cypher: How Graph Databases Become the Data Layer for AI Agents

Venue: aiDM Workshop at SIGMOD 2026, Bengaluru, India (May 31, 2026)

Status: Submitted

Authors: Madhulatha Mandarapu, Sandeep Kunkunuru

Summary

Empirical comparison of three approaches for LLM access to knowledge graphs:

  1. Domain-specific MCP tools with Cypher templates
  2. Generic text-to-Cypher via schema-aware prompting
  3. Raw LLM with no graph access

Evaluated on two benchmarks across biomedical and industrial domains.

Key Results

ApproachAssetOpsBench (139)BiomedQA (40)
MCP Tools99%98%
Text-to-Cypher (NLQ)83%85%
GPT-4 / 4o standalone65%75%

The “inverted LLM” thesis: structured data + deterministic tools outperforms unstructured LLM reasoning on domain-specific factual questions.


Manuscript sources, reviewer feedback, and reproduction artifacts live in the private samyama-research repository under papers/paper6-aidm/.

Research Paper: Knowledge Graphs for Industrial Operations

We have published a research paper evaluating knowledge graphs as the data layer for LLM-based industrial asset operations, building on the AssetOpsBench benchmark.

Title: Knowledge Graphs as the Missing Data Layer for LLM-Based Industrial Asset Operations

Authors: Madhulatha Mandarapu (madhulatha@samyama.ai), Sandeep Kunkunuru (sandeep@samyama.ai)

GitHub (assetops-kg) · IBM AssetOpsBench

Keywords: Knowledge Graphs, Large Language Models, Industrial Asset Operations, Benchmark, OpenCypher, Vector Search, Graph Algorithms.


Abstract

LLM-based agents for industrial asset operations show promise but achieve limited accuracy when reasoning over flat document stores. The AssetOpsBench benchmark establishes that GPT-4 agents achieve 65% success on 139 industrial maintenance scenarios backed by CouchDB, YAML, and CSV data sources. AssetOpsBench evaluates LLM agent autonomy; we ask a complementary question: how much does the data model behind the tools affect agent performance?

Building on the same benchmark data and scenarios, we introduce a knowledge graph layer (781 nodes, 955 edges, 16 relationship types) and evaluate three architectures of increasing LLM involvement:

ArchitectureLLM RolePass RateAvg Latency
Deterministic + graphNone (pre-coded)99% (137/139)63 ms
LLM + graph via NLQGenerates Cypher83% (115/139)5,874 ms
Baseline (tool-augmented LLM)Does everything~65% (91/139)not reported

Our key finding is inverted LLM usage: instead of asking the LLM to reason over raw data (a broad, error-prone task), we ask it to generate structured queries from a typed schema — a narrow problem that plays to LLM strengths. The graph then executes deterministically.


Thesis

For structured operational domains, the data model is the primary bottleneck. A knowledge graph with typed relationships enables both deterministic queries (for known patterns) and LLM-assisted queries (for novel questions), while document stores place the full data-reasoning burden on the LLM — a task where LLMs consistently struggle.


Three Architectures

Baseline: Tool-Augmented LLM (65%)

User question
  → LLM parses intent → LLM selects tool → Tool queries document store
    → LLM interprets raw results → LLM synthesizes answer

The LLM handles intent parsing, tool selection, argument crafting, data interpretation, and answer synthesis. GPT-4 achieves 65%. Failures cluster around counting, cross-document correlation, and relationship traversal — data operations rather than reasoning failures.

NLQ: LLM Generates Queries (83%)

User question
  → LLM generates Cypher (given schema)
    → Graph executes deterministically
      → LLM synthesizes answer from structured results

We invert the LLM’s role: instead of broad data reasoning, ask it to generate a Cypher query from a typed schema. This is code generation — a task LLMs excel at. The graph handles traversal, counting, and algorithms deterministically.

Deterministic: No LLM (99%)

User question
  → Keyword routing → Cypher query → Structured response

Pre-coded handlers for known patterns. A software engineering solution — demonstrates the ceiling with the right data model. 63ms average latency, zero token cost.


The Inverted LLM Pattern

The key insight: schema-aware query generation outperforms free-form data reasoning for any structured domain.

  • Architecture A asks: “LLM, answer this question from this data” (broad, error-prone)
  • Architecture B asks: “LLM, given this schema, write a Cypher query” (narrow, plays to strengths)

The same LLM, given a sharper problem scoped to its strengths, produces dramatically better results. Code generation is an LLM strength; data traversal, counting, and relationship reasoning are graph strengths. Each system does what it’s good at.


Knowledge Graph Schema

781 nodes, 955 edges, 11 labels, 16 edge types

Built from the AssetOpsBench data sources via an 8-step ETL pipeline:

Site ─[CONTAINS_LOCATION]→ Location ─[CONTAINS_EQUIPMENT]→ Equipment ─[HAS_SENSOR]→ Sensor
                                                              │
                                           DEPENDS_ON / SHARES_SYSTEM_WITH
                                                              │
FailureMode ─[MONITORS]→ Equipment ─[EXPERIENCED]→ FailureMode
WorkOrder ─[FOR_EQUIPMENT]→ Equipment
WorkOrder ─[ADDRESSES]→ FailureMode
Anomaly ─[TRIGGERED]→ WorkOrder
Event ─[FOR_EQUIPMENT]→ Equipment

Key additions over the baseline document model:

  • Equipment dependencies: DEPENDS_ON and SHARES_SYSTEM_WITH edges enable cascade analysis
  • Failure mode embeddings: 384-dim Sentence-BERT vectors in HNSW index enable similarity search
  • Unified event timeline: 6,256 events with ISO timestamps enable temporal queries

AssetOpsBench 139 Scenarios — Per-Type Results

TypeCountDeterministicNLQ (GPT-4o)Baseline (GPT-4)
IoT2020/20 (100%)17/20 (85%)
FMSR4040/40 (100%)37/40 (93%)
TSFM2323/23 (100%)21/23 (91%)
Multi2020/20 (100%)8/20 (40%)
WO3634/36 (94%)32/36 (89%)
Total139137/139 (99%)115/139 (83%)~91/139 (65%)

NLQ Multi stays at 40% because 12/20 scenarios require TSFM pipeline execution (forecasting, anomaly detection) that cannot be expressed as Cypher queries — a structural limitation.


Custom 40 Scenarios — Graph-Native Capabilities

40 new scenarios extending the benchmark with graph-native capabilities:

CategoryCountGPT-4o AvgSamyama AvgDelta
Failure similarity60.5010.902+0.401
Criticality analysis50.5660.938+0.372
Root cause analysis50.5800.934+0.354
Multi-hop dependency80.6180.934+0.316
Maintenance optimization50.6340.931+0.297
Cross-asset correlation60.6380.929+0.291
Temporal pattern50.6790.923+0.244

Largest gains on failure similarity (+0.401) and criticality analysis (+0.372) — exactly where graph structure and vector search provide the most value. GPT-4o’s 6 failures all require graph traversal, PageRank, or vector search that LLMs cannot perform from parametric knowledge alone.


The Full Pipeline: LLMs at the Edges, Graph in the Middle

The query layer comparison above is only part of the story. The full industrial data pipeline has three layers:

  1. Data Ingestion (software engineering): Structured data (90%+) → deterministic ETL. Unstructured data (maintenance logs, PDFs) → LLM-assisted entity extraction, resolution, classification.
  2. Data Model (architecture decision): One-time choice between flat documents and knowledge graph.
  3. Query (LLM optional): Deterministic handlers for known patterns; LLM-generated Cypher for novel questions.

LLMs appear at both edges — data preparation (unstructured → structured) and query generation (natural language → Cypher). The graph is the stable center that receives data from both deterministic and LLM-assisted ingestion, and serves both deterministic and LLM-generated queries.

In both cases, the LLM performs a generation task (structured output from unstructured input) — its strength. The graph handles data operations (storage, traversal, algorithms) — its strength. Neither component is asked to do what it’s bad at.


Scalability

DimensionArch. A (LLM + docs)Arch. B/C (graph ± LLM)
10K queries/day$300–500 (tokens)$0 (deterministic) or ~$30 (NLQ)
Real-time streamingNot supportedGraph updates + continuous queries
Multi-hop at 10K assetsLLM reasons across 10K docsBFS traversal, O(|E|)
Latency per query5–11 seconds63 ms (det.) / ~6 s (NLQ)

Honest Caveats

  1. Deterministic vs. autonomous: The 99% result compares pre-coded answers against an autonomous agent — fundamentally different tasks. The comparison illustrates the ceiling achievable with the right data model, not a claim of superior agent intelligence.
  2. Model mismatch: The baseline used GPT-4; NLQ used GPT-4o. The +18pp gap is an upper bound. Same-model comparison pending.
  3. Clean data: AssetOpsBench provides clean, structured data. Real-world messy data needs LLM-assisted preparation.
  4. Custom scenarios: Designed to extend the benchmark with graph-native capabilities, not replace the original scenarios.
  5. Complementary research questions: AssetOpsBench evaluates LLM agent autonomy. We evaluate data model impact. Both are valid; our results do not diminish the value of the original benchmark.

Conclusion

Building on AssetOpsBench, we show that introducing a knowledge graph as the data layer improves LLM-based industrial operations at every level of LLM involvement. For structured operational domains, the data model is the primary bottleneck. The inverted LLM pattern (schema-aware query generation instead of free-form data reasoning) is generalizable to any structured domain.


Implementation


Manuscript sources, reviewer feedback, and reproduction artifacts live in the private samyama-research repository under papers/paper3-industrial-kg/.

VLDB 2027 Systems Paper (In Preparation)

Target: PVLDB Vol. 20, Industry Track

Working Title: Samyama: A Unified Graph-Vector Database with Cost-Based Query Planning and Late Materialization

Status: In preparation. Extends Paper 1 (arxiv:2603.08036) with deeper evaluation and VLDB-specific focus.

Strategy

The arxiv preprint covers everything broadly. For VLDB we focus and deepen on three core database contributions:

  1. Late materialization for property graphs (NodeRef / EdgeRef) — 4× traversal speedup, 60% memory reduction
  2. Graph-native cost-based planner — triple-level statistics, plan enumeration, direction reversal, ExpandInto
  3. Hybrid CSR adjacency — frozen tier + write buffer, two-phase bulk loading, billion-edge ingestion at single-server scale

De-emphasize: GPU acceleration, agentic enrichment, optimization solvers, RDF (mention as system features, don’t evaluate deeply).

Add: LDBC SNB comparison, billion-edge evaluation, cross-KG federation at scale.

Key New Results (since arxiv v2)

ResultImpact
11-KG mega-benchmark, 138M nodes / 1.22B edges, 500/500 pass on r7i.16xlargeScale + correctness credibility
Adjacency-aware aggregation (ADR-017)Algorithmic contribution — closes degree-aggregation timeouts on PubMed-scale data
WCO TrieJoin for cyclic patternsAlgorithmic contribution
Edge-arena removal (DS-07c) — COW edges via EdgeViewEngineering contribution — substantial memory savings at 1B-edge scale
MVCC: Snapshot Isolation + Read Committed with write-write conflict detectionConcurrency story
Rayon parallel algorithms (PageRank, LCC, CDLP)Parallelism

Manuscript sources, planning notes, and formatting TODO live in the private samyama-research repository under papers/paper-vldb-2027/.

Index of Implemented Research Papers

Samyama Graph Database is built on the foundations of cutting-edge computer science research. Below is a comprehensive index of the research papers, algorithms, data structures, and standards implemented directly within the core engine and its specialized crates.


Core System Architecture

Query Execution

  • Volcano Iterator Model

    • Paper: “Volcano — An Extensible and Parallel Query Evaluation System” (Graefe, 1994)
    • Implementation: src/query/executor/operator.rs — physical operators using pull-based next_batch() with vectorized RecordBatch processing
    • Key insight: Lazy evaluation avoids materializing intermediate results; each operator pulls only what downstream needs
  • Late Materialization

    • Paper: “Column-Stores vs. Row-Stores: How Different Are They Really?” (Abadi et al., 2008)
    • Implementation: src/query/executor/operator.rs — Scan operators produce Value::NodeRef(id) instead of full node clones; properties resolved on-demand at ProjectOperator
    • Result: 4.0x improvement on 1-hop traversals, 4.7x on 2-hop traversals
  • Adjacency-Aware Aggregation (ADR-017)

    • Pattern: When the query asks for count(neighbor) over a degree-bounded match set, the engine walks per-node adjacency lists rather than scanning the full edge population
    • Implementation: AdjacencyCountAggregateOperator (planner detects the shape; executor walks adjacency)
    • Effect: Closes degree-aggregation timeouts on PubMed-scale data — what previously needed an OLAP-shaped full-edge scan now answers in seconds
  • PEG Parsing (Parsing Expression Grammars)

    • Paper: “Parsing Expression Grammars: A Recognition-Based Syntactic Foundation” (Ford, 2004)
    • Implementation: src/query/cypher.pest — Pest PEG parser for OpenCypher with atomic keyword rules for word boundary enforcement

Storage Engine

  • Log-Structured Merge Trees (LSM-Tree)

    • Paper: “The Log-Structured Merge-Tree (LSM-Tree)” (O’Neil et al., 1996)
    • Implementation: src/persistence/storage.rs — RocksDB with LZ4/Zstd compression, Column Families for multi-tenant isolation
  • Write-Ahead Logging (WAL)

    • Paper: “ARIES: A Transaction Recovery Method Supporting Fine-Granularity Locking and Partial Rollbacks” (Mohan et al., 1992)
    • Implementation: src/persistence/wal.rs — Sequential WAL with fsync for Raft log, async for state machine

Concurrency Control

  • Multi-Version Concurrency Control (MVCC)
    • Paper: “Concurrency Control in Distributed Database Systems” (Bernstein & Goodman, 1981)
    • Implementation: src/graph/store.rs — versioned node arena with per-slot version chains; copy-on-write edges via EdgeView against columnar storage (no in-memory edge arena)
    • Isolation levels: Read Committed and Snapshot Isolation, with write-write conflict detection at commit
    • Memory bound: background version GC drops node versions older than the oldest live snapshot; WAL is versioned so log replay reconstructs the right state

Distributed Consensus

  • Raft Consensus Algorithm
    • Paper: “In Search of an Understandable Consensus Algorithm” (Ongaro & Ousterhout, 2014)
    • Implementation: src/raft/ via the openraft framework — Leader election, log replication, quorum commits, CP trade-off
    • Enterprise: HTTP/2 transport, TLS encryption, snapshot streaming, cluster metrics

Serialization

  • Bincode (Binary Encoding)
    • Library: bincode crate — Compact binary serialization for StoredNode/StoredEdge structs in RocksDB
    • Benefit: Nanosecond deserialization, no field name overhead, serde integration

Vector Search & AI

  • HNSW (Hierarchical Navigable Small World)
    • Paper: “Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs” (Malkov & Yashunin, 2018)
    • Implementation: src/vector/ via the hnsw_rs crate — Cosine, L2, and Dot Product metrics; 15K+ QPS on 128-dim vectors
    • Integration: VectorSearchOperator in query pipeline enables Graph RAG (combined vector + graph traversal)

Graph Analytics (samyama-graph-algorithms)

Centrality & Importance

  • PageRank

    • Paper: “The PageRank Citation Ranking: Bringing Order to the Web” (Page, Brin, Motwani & Winograd, 1999)
    • Implementation: crates/samyama-graph-algorithms/src/pagerank.rs — Iterative power method with configurable damping factor, dangling node redistribution, convergence tolerance
    • Validation: LDBC Graphalytics 5/5 (XS + S datasets including cit-Patents 3.8M vertices)
  • Local Clustering Coefficient (LCC)

    • Paper: “Collective dynamics of ‘small-world’ networks” (Watts & Strogatz, 1998)
    • Implementation: crates/samyama-graph-algorithms/src/lcc.rs — Both directed and undirected variants; measures neighborhood connectivity
    • Validation: LDBC Graphalytics 5/5

Community Detection & Connectivity

  • Community Detection via Label Propagation (CDLP)

    • Paper: “Near linear time algorithm to detect community structures in large-scale networks” (Raghavan, Albert & Kumara, 2007)
    • Implementation: crates/samyama-graph-algorithms/src/cdlp.rs — Iterative neighbor voting with configurable max iterations
    • Validation: LDBC Graphalytics 5/5
  • Weakly Connected Components (WCC)

    • Algorithm: Union-Find with path compression and union by rank
    • Implementation: crates/samyama-graph-algorithms/src/community.rs — O(n * α(n)) near-linear time
    • Validation: LDBC Graphalytics 5/5
  • Strongly Connected Components (SCC)

    • Algorithm: Tarjan’s Algorithm (Tarjan, 1972)
    • Implementation: crates/samyama-graph-algorithms/src/community.rs — Single DFS pass with lowlink tracking
  • Triangle Counting

    • Algorithm: Node-iterator method with sorted adjacency intersection
    • Implementation: crates/samyama-graph-algorithms/src/topology.rs — Used for social cohesion analysis and network clustering metrics

Pathfinding & Network Flow

  • Breadth-First Search (BFS)

    • Algorithm: Level-synchronous BFS (Moore, 1959)
    • Implementation: crates/samyama-graph-algorithms/src/pathfinding.rs — Standard BFS + all shortest paths variant
    • Validation: LDBC Graphalytics 5/5
  • Dijkstra’s Shortest Path

    • Paper: “A note on two problems in connexion with graphs” (Dijkstra, 1959)
    • Implementation: crates/samyama-graph-algorithms/src/pathfinding.rs — Binary heap priority queue; also used for SSSP in LDBC validation
    • Validation: LDBC Graphalytics SSSP 3/3
  • Edmonds-Karp Maximum Flow

    • Paper: “Theoretical Improvements in Algorithmic Efficiency for Network Flow Problems” (Edmonds & Karp, 1972)
    • Implementation: crates/samyama-graph-algorithms/src/flow.rs — BFS-based augmenting path selection; O(VE²) complexity
  • Prim’s Minimum Spanning Tree

    • Algorithm: Prim’s Algorithm (Prim, 1957)
    • Implementation: crates/samyama-graph-algorithms/src/mst.rs — Greedy MST construction with priority queue

Statistical & Dimensionality Reduction

  • PCA — Randomized SVD

    • Paper: “Finding structure with randomness: Probabilistic algorithms for constructing approximate matrix decompositions” (Halko, Martinsson & Tropp, 2011)
    • Implementation: crates/samyama-graph-algorithms/src/pca.rs — Gaussian random projection → power iterations → QR factorization → small SVD; O(n·d·k) complexity
    • Auto-selection: PcaSolver::Auto uses Randomized SVD for n > 500 nodes
  • PCA — Power Iteration (Deflation)

    • Algorithm: Classical power iteration with Gram-Schmidt re-orthogonalization
    • Implementation: crates/samyama-graph-algorithms/src/pca.rs — Legacy solver, PcaResult includes transform() and transform_one() for projection

Metaheuristic Optimization (samyama-optimization)

The engine natively supports the Rao-family-and-friends suite of metaheuristic optimizers — all implemented in crates/samyama-optimization/src/algorithms/. Beyond the originals listed below, the suite includes the Rao-family extensions (BMWR, MO-BMR / BWR / BMWR, SAMP-Jaya, SAPHR, EHRJAYA, QO-Rao, MO-Rao+DE):

Metaphor-Less Algorithms

  • Jaya Algorithm

    • Paper: “Jaya: A simple and new optimization algorithm for solving constrained and unconstrained optimization problems” (R. Venkata Rao, 2016)
    • Key property: Parameter-free—requires no algorithm-specific tuning
  • Quasi-Oppositional Jaya (QOJAYA)

    • Paper: “Quasi-oppositional based Jaya algorithm” (derived from Rao, 2016)
    • Enhancement: Opposition-based initialization improves convergence speed
  • Rao Algorithms (Rao-1, Rao-2, Rao-3)

    • Paper: “Rao algorithms: Three metaphor-less simple algorithms for solving optimization problems” (R. Venkata Rao, 2020)
    • Key property: Three progressively complex variants; all metaphor-free
  • TLBO (Teaching-Learning-Based Optimization)

    • Paper: “Teaching–learning-based optimization: A novel method for constrained mechanical design optimization problems” (R. Venkata Rao, Savsani & Vakharia, 2011)
  • ITLBO (Improved TLBO)

    • Enhancement: Adaptive learning factor and improved selection mechanisms
  • GOTLBO (Group-Optimized TLBO)

    • Enhancement: Group-based teaching phase with oppositional learning

Swarm & Evolutionary Algorithms

  • Particle Swarm Optimization (PSO)

    • Paper: “Particle swarm optimization” (Kennedy & Eberhart, 1995)
  • Differential Evolution (DE)

    • Paper: “Differential Evolution – A Simple and Efficient Heuristic for global Optimization over Continuous Spaces” (Storn & Price, 1997)
  • Genetic Algorithm (GA)

    • Paper: “Adaptation in Natural and Artificial Systems” (Holland, 1975)
  • Grey Wolf Optimizer (GWO)

    • Paper: “Grey Wolf Optimizer” (Mirjalili, Mirjalili & Lewis, 2014)
  • Artificial Bee Colony (ABC)

    • Paper: “An Idea Based On Honey Bee Swarm for Numerical Optimization” (Karaboga, 2005)
  • Bat Algorithm

    • Paper: “A New Metaheuristic Bat-Inspired Algorithm” (Yang, 2010)
  • Cuckoo Search

    • Paper: “Cuckoo Search via Lévy Flights” (Yang & Deb, 2009)
  • Firefly Algorithm

    • Paper: “Firefly Algorithms for Multimodal Optimization” (Yang, 2009)
  • Flower Pollination Algorithm (FPA)

    • Paper: “Flower Pollination Algorithm for Global Optimization” (Yang, 2012)

Physics-Based Algorithms

  • Gravitational Search Algorithm (GSA)

    • Paper: “GSA: A Gravitational Search Algorithm” (Rashedi, Nezamabadi-pour & Saryazdi, 2009)
  • Simulated Annealing (SA)

    • Paper: “Optimization by Simulated Annealing” (Kirkpatrick, Gelatt & Vecchi, 1983)
  • Harmony Search (HS)

    • Paper: “A New Heuristic Optimization Algorithm: Harmony Search” (Geem, Kim & Loganathan, 2001)
  • BMR & BWR

    • Specialized reinforcement-based solvers for constrained search spaces

Multi-Objective Algorithms

  • NSGA-II (Non-dominated Sorting Genetic Algorithm II)

    • Paper: “A fast and elitist multiobjective genetic algorithm: NSGA-II” (Deb, Pratap, Agarwal & Meyarivan, 2002)
    • Enhancement: Constrained Dominance Principle for feasibility-first selection
  • MOTLBO (Multi-Objective TLBO)

    • Paper: Multi-objective extension of TLBO (derived from Rao et al., 2011)
    • Feature: Pareto front discovery with crowding distance for diversity preservation

RDF & Semantic Web Standards

  • RDF (Resource Description Framework)

    • Standard: W3C RDF 1.1 Concepts and Abstract Syntax (2014)
    • Implementation: src/rdf/ — Triple/Quad storage with SPO/POS/OSP indices via oxrdf crate
  • Turtle (Terse RDF Triple Language)

    • Standard: W3C RDF 1.1 Turtle (2014)
    • Implementation: src/rdf/serialization/turtle.rs via rio_turtle
  • SPARQL 1.1

    • Standard: W3C SPARQL 1.1 Query Language (2013)
    • Implementation: src/sparql/ — Parser infrastructure via spargebra; query execution in development

Hardware Acceleration (samyama-gpu)

  • Parallel Graph Algorithms on GPU

    • Implementation: 8+ WGSL compute shaders targeting WebGPU (Metal, Vulkan, DX12)
    • Algorithms: PageRank, Triangle Counting, CDLP, LCC, PCA
    • Operators: SUM aggregation (parallel reduction), ORDER BY (bitonic sort)
    • Vector: Cosine distance, inner product (batch re-ranking)
  • GPU PCA (Fused Power Iteration)

    • Implementation: Five WGSL shaders: pca_mean, pca_center, pca_covariance (tiled, 64-sample tiles), pca_power_iter, pca_power_iter_norm (fused mat-vec + parallel norm + normalize in single dispatch)
    • Threshold: MIN_GPU_PCA = 50,000 nodes, d > 32 dimensions
  • Bitonic Sort

    • Paper: “Sorting networks and their applications” (Batcher, 1968)
    • Implementation: crates/samyama-gpu/src/shaders/bitonic_sort.wgsl — GPU argsort for ORDER BY on >10K result sets

Benchmark Validation

  • LDBC Graphalytics
    • Standard: “The LDBC Graphalytics Benchmark” (Iosup et al., 2016)
    • Result: 28/28 tests passed (100%) across BFS, PageRank, WCC, CDLP, LCC, SSSP on XS and S-size datasets
    • Datasets: example-directed, example-undirected, cit-Patents (3.8M vertices), datagen-7_5-fb (633K vertices, 68M edges), wiki-Talk (2.4M vertices)