Built in Rust  ·  Cypher Query  ·  Bolt Protocol  ·  Streaming Ingestion

The graph engine built for
real-time decisions at any scale

JetGraph is a purpose-built in-memory graph engine with native Cypher query language support, Bolt protocol compatibility for Neo4j drivers, and high-throughput streaming data ingestion — delivering sub-millisecond velocity counts, relationship signals, and risk propagation across any domain.

0.05ms
Velocity lookup (O(1))
35k
Events per second (streaming)
0.05ms
Node context read
<0.5ms
Time-window aggregation

Not another general-purpose
graph database

Every design decision optimizes for one thing: answering relationship and velocity questions in real time, with deterministic latency, regardless of your domain. With Cypher, Bolt, and streaming ingestion built in.

O(1) Velocity at Query Time

Velocity windows are pre-computed as ring counters — 1min, 5min, 1hr, 24hr. No aggregation at query time. Get exact event counts for any entity in any window with a single DashMap lookup.

0.05ms · GetVelocityCount
🌊

Automatic Risk Propagation

Flag one node as high-risk and every directly connected entity instantly reflects its exposure score. No batch jobs, no manual propagation — one call and the entire neighborhood is updated in microseconds.

Propagates in microseconds
🔬

Novelty Detection Built-In

Know instantly if two entities have ever been connected before — before the event is recorded. Structural relationship tracking gives you "first-time" signals across any domain: users, devices, products, or locations.

O(1) · CompactEdge store
🦀

Rust Performance, Zero GC Pauses

Written entirely in Rust. No garbage collector means no unpredictable latency spikes under load. Memory layout is optimized: strings are dictionary-encoded, booleans are bit-packed, integers are compact.

Deterministic sub-ms latency
📡

Streaming Data Ingestion

High-throughput streaming pipeline built on bidirectional gRPC — eliminating per-event TCP round-trip overhead. Push 35,000+ events per second from a single stream with full backpressure, acknowledgement, and zero data loss.

~35k ops/sec · single stream
📊

HyperLogLog Cardinality at Scale

Count unique neighbors — "how many distinct users bought this product?", "how many hosts touched this IP?" — with HyperLogLog in O(1). No full traversal. Works at millions of connections.

0.06ms · GetNeighborCount
🔤

Cypher Query Language

Write graph queries in Cypher — the same expressive, human-readable language used by Neo4j. Create nodes, match patterns, and call built-in procedures directly via POST /cypher or the visual Cypher Editor in the admin UI.

MATCH · CREATE · CALL procedures
🔌

Bolt Protocol Support

JetGraph speaks the Bolt binary protocol on port 7687 — meaning any Neo4j-compatible driver (official or community) connects without modification. Drop in your existing driver, point it at JetGraph, and start querying.

Port 7687 · Neo4j-driver compatible

Query first. Enrich. Then insert.

JetGraph is designed around a precise three-phase pattern that gives you accurate, consistent signals every time — without reading your own writes.

Phase 01
🔍

Query Historical State

Before the event is recorded, query the graph for every signal you need. The graph reflects only committed history — giving you a clean, consistent baseline.

GetVelocityCount(entity, 1hr)
GetNeighbors(node → related)
GetNodeContext(entity)
GetNeighborCount(node)
QueryEdgeWindow(aggregate)
Phase 02
🎯

Enrich & Decide

Combine graph signals into a composite score. Apply your own weights and business logic. JetGraph supplies the primitives — your application controls the model and the outcome.

score < 0.4 → Allow / Recommend
score 0.4–0.7 → Review / Throttle
score > 0.7 → Block / Escalate
Phase 03
📝

Insert & Propagate

Record every event — including rejected or low-confidence ones. Flag nodes that breach your thresholds and propagation updates all connected entities automatically.

UpsertEdge(entity_event)
CreateEdge(new_relationship)
FlagNode(entity, if threshold)

Flag one node.
The graph learns.

When any node is flagged as high-risk or compromised, JetGraph instantly propagates its exposure score to every directly connected entity — users, IPs, products, devices — without any additional queries.

🎯

Direct risk score

The node you flag carries a direct risk score and reason — queryable in a single O(1) DashMap read from any part of your application.

🌊

Neighbor exposure

All connected nodes get their max_neighbor_risk_score and flagged_neighbor_count updated automatically.

↩️

Clean false-positive recovery

Unflag a node and exposure on all neighbors is decremented atomically. No stale scores, no manual cleanup.

Live Risk Propagation
🌐 IP · 1.2.3.4
👤 Entity · FLAGGED
🏢 Org · Linked
↕ entity_ip
↕ entity_event
↕ entity_org
🌐 IP · shared
📦 Resource
📱 Device
Flagged (direct_risk_score)
Exposed (neighbor_score++)

Numbers that matter at decision time

Measured on a single machine. Every number reflects real API calls on the critical query path.

Query Latency — Single Machine
GetNodeContextTwo DashMap lookups, O(1) 0.05 ms
GetVelocityCountPre-computed ring, O(1) 0.05 ms
GetNeighborCount (HLL)HyperLogLog estimate, O(1) 0.06 ms
GetNeighbors (1 neighbor)Hot-layer + cold CSR merge 0.5 ms
GetNeighbors (100 neighbors)Scales with degree 0.9 ms
QueryEdgeWindow (1hr, ~12 edges)Binary search + property lookup < 0.5 ms

Ingestion Throughput

BatchMutate streaming — bidirectional gRPC eliminates per-event round-trip overhead.

BatchMutate (streaming) ~35,000 ops/sec
CreateEdge (unary gRPC) ~10,000 ops/sec
Pre-computed Velocity Windows
1 minute window O(1) lookup
5 minute window O(1) lookup
1 hour window O(1) lookup
24 hour window O(1) lookup

Designed for
in-process speed

JetGraph stores everything in memory with a layout optimized for read-heavy, latency-sensitive workloads. No serialization on the critical path. No disk I/O during queries.

🗄️

Compact edge store

Edges are stored one record per unique src–dst pair with time-to-live support. No write amplification, no compaction pauses.

💾

Memory-efficient encoding

Strings are dictionary-encoded, booleans are bit-packed, timestamps stored as 64-bit epoch microseconds. The graph fits more data in less RAM.

📸

Snapshot persistence

The engine snapshots its full state to disk on a configurable interval. Recovery loads the latest snapshot — no WAL replay, fast restart.

🐳

Docker-native deployment

Single binary. Drop in a Docker Compose file. Mount a data volume for snapshots. No cluster to manage for most workloads.

API Layer
gRPC / HTTP2 — port 50051 SchemaService · GraphService · FeatureService · BatchMutate stream
REST + Cypher — port 8080 POST /cypher · Admin · tooling · quick testing
Bolt Protocol — port 7687 Neo4j-driver compatible · binary framing · streaming results
↓ async Tokio runtime
Engine Layer
Graph Engine (Rust) Concurrent writes · DashMap sharding
Feature Engine Velocity rings · HLL · Node context · Timelines
↓ lock-free reads / RwLock writes
Storage Layer
Compact Neighbor Store One record per src–dst pair · TTL eviction
Node Histograms · Activity Bitmaps HyperLogLog cardinality · per-node timelines
↓ background snapshot task
Persistence Layer
Snapshot — v4 binary format Configurable interval · fast recovery · no WAL replay

Any domain where relationships
and time matter

JetGraph's primitives — velocity, novelty, propagation, cardinality — apply wherever graph structure carries signal and latency is non-negotiable.

Fraud & Risk

Real-Time Risk Scoring

Score every event against full historical context: velocity, novelty, spend patterns, and neighbor risk exposure — all in one sub-millisecond decision path. Plug into any authorization or review flow.

velocity_1min is_new_relationship neighbor_risk_score spend_1hr
Recommendations

Personalization & Collaborative Filtering

Model user–item interactions as a live graph. Query which items a user's closest neighbors have engaged with, detect novelty ("never seen this product before"), and serve personalized signals in under a millisecond.

item_affinity_score is_new_item neighbor_purchases interaction_velocity
Network Security

Threat Detection & Lateral Movement

Map relationships between hosts, IPs, users, and services. Flag a compromised endpoint and propagation immediately exposes all connected assets. Detect lateral movement patterns before they escalate.

is_new_connection host_risk_score access_velocity neighbor_exposure
Identity & Access

Anomalous Login & Session Detection

Track the full history of which IPs, devices, and locations each identity has used. Surface anomalous sessions the instant a new device or geography appears, before any downstream action is taken.

is_new_ip is_new_device login_velocity ip_unique_accounts
Supply Chain

Entity Relationship & Anomaly Analytics

Model suppliers, components, logistics nodes, and certifications as a live graph. Detect unusual relationship patterns, compute supplier exposure when a node goes high-risk, and track velocity of supply events in any window.

supplier_risk_score shipment_velocity is_new_supplier neighbor_disruption
Knowledge Graph

Entity Resolution & Graph Enrichment

Build a live knowledge graph of entities and their relationships across heterogeneous data sources. Use HyperLogLog cardinality to detect entity clusters, and Cypher queries to traverse and enrich in real time.

entity_overlap shared_attribute_count cluster_size co_occurrence_velocity

From zero to first
graph signal in minutes

The jetgraph-client Rust crate gives you a typed, ergonomic API over gRPC. No proto files to copy, no build.rs to write.

1

Add the client crate

Add jetgraph-client to your Cargo.toml and connect in seconds.

2

Register your schema

Declare node types, edge types, velocity windows, and property schemas once at startup — for any domain.

3

Query → Enrich → Insert

Follow the three-phase pattern on every event. Collect graph signals, apply your logic, record the outcome.

🦀

Rust Client

Native crate with typed API

🐍

Python Client

Protobuf gRPC bindings

🔤

Cypher HTTP API

POST /cypher — any language

🔌

Neo4j Drivers (Bolt)

Official & community drivers

score_transaction.rs
// Phase 1: query historical state let card_id = lookup_node(&graph, "card", &tx.card_pan).await; // Velocity — O(1) pre-computed rings let tx_count_1hr = features .get_velocity_count(VelocityQuery { node: card_id, edge_type: "card_transaction".into(), window_secs: 3600, }).await?.count; // Novelty — is this a new merchant relationship? let is_new_merchant = !edge_exists( &graph, card_id, merchant_id, "card_merchant" ).await; // Fraud contagion — O(1) DashMap read let ctx = features .get_fraud_context(FraudContextQuery { node: card_id, }).await?; // Phase 2: score let mut risk: f32 = 0.0; if is_new_merchant { risk += 0.15; } if tx_count_1hr > 30 { risk += 0.25; } risk += 0.5 * ctx.max_neighbor_fraud_score; let decision = match risk { r if r > 0.7 => Decline, r if r > 0.4 => Challenge, _ => Approve, }; // Phase 3: insert — always, even if declined graph.create_edge(CreateEdgeRequest { edge_type_name: "card_transaction".into(), src: card_id, dst: merchant_id, properties: vec![prop("decision", decision)], }).await?; if decision == Decline { // Contamination propagates automatically features.flag_node(FlagRequest { node: card_id, fraud_score: 0.85, reason: "auto_decline".into(), }).await?; }

Up and running in 3 minutes

Try JetGraph locally with Docker — no build, no config required. Connect via Cypher HTTP API, Bolt protocol (port 7687), or the visual admin UI. The demo image ships with full support for all three.

01

Start the stack

Save the file below as docker-compose.yml, then run docker compose up -d. Both images are pulled automatically from Docker Hub.

docker-compose.yml
services: graphengine: image: alhascan/jetgraph-demo:latest restart: unless-stopped ports: - "8080:8080" - "7687:7687" volumes: - graphengine-data:/data environment: RUST_LOG: info ENABLE_ADMIN_RESET: "true" healthcheck: test: ["CMD", "sh", "-c", "curl -sf http://localhost:8080/health || curl -sf http://localhost:8080/api/health || exit 1"] interval: 10s timeout: 5s retries: 5 start_period: 120s segment-evaluator: image: alhascan/jetgraph-demo:latest entrypoint: ["/usr/local/bin/segment-evaluator"] restart: unless-stopped environment: RUST_LOG: info GRAPH_ENGINE_ENDPOINT: http://graphengine:50051 SEGMENT_EVALUATOR_CONFIG_DB: /data/seg-config volumes: - seg-config-data:/data/seg-config depends_on: graphengine: condition: service_healthy pattern-miner: image: alhascan/jetgraph-demo:latest entrypoint: ["/usr/local/bin/pattern-miner"] restart: unless-stopped environment: RUST_LOG: info GRAPH_ENGINE_ENDPOINT: http://graphengine:50051 PATTERN_MINER_CONFIG_DB: /data/pm-config PATTERN_MINER_ADDR: 0.0.0.0:8082 volumes: - pm-config-data:/data/pm-config depends_on: graphengine: condition: service_healthy graphengine-ui: image: alhascan/jetgraph-ui-demo:latest restart: unless-stopped ports: - "80:3000" environment: BOLT_URL: bolt://graphengine:7687 NEO4J_USER: "" NEO4J_PASSWORD: "" GRAPH_HTTP_URL: http://graphengine:8080 SEGMENT_API_URL: http://segment-evaluator:8081 PATTERN_MINER_URL: http://pattern-miner:8082 depends_on: graphengine: condition: service_healthy volumes: graphengine-data: seg-config-data: pm-config-data:
02

Verify the engine is ready

Once both containers are up, check the health endpoint. You should see a JSON response with "ready":true.

bash
# Health check curl http://localhost:8080/health # → {"status":"ok","ready":true} # Then open the admin UI in your browser open http://localhost
03

Load sample data with one click

Open the Admin UI at http://localhost, go to Schema in the left nav, and click Apply Schema & Load Sample Data. This provisions the Credit Card Fraud schema and seeds a representative dataset so every query in Analytics returns results — no manual Cypher required. Prefer to bring your own schema? Skip this step and use the manual flow in Step 05.

Admin UI flow
# 1. Open the UI open http://localhost # 2. In the left sidebar, click Schema # 3. In the "Quick Start — Credit Card Fraud Space" card, # click ⚡ Apply Schema & Load Sample Data # 4. When the green "All done" banner appears, explore in: # Graph Explorer (visual traversal) # Cypher Editor (free-form queries) # Analytics ▸ Signals / Patterns / Segmentation
04

Connect via Bolt (Neo4j drivers)

JetGraph listens on port 7687 with the Bolt binary protocol. Any Neo4j-compatible driver works out of the box — no credentials required in demo mode.

Python — neo4j driver
Node.js — neo4j driver
from neo4j import GraphDatabase driver = GraphDatabase.driver("bolt://localhost:7687", auth=("", "")) with driver.session() as session: result = session.run("MATCH (c:CARD) RETURN c.external_id AS id LIMIT 10") for record in result: print(record["id"]) driver.close() # → card-001
05

Or — register your own schema & run Cypher queries

If you skipped Step 03, declare your schema manually before writing data. Run these calls via the Cypher HTTP API — or paste them directly into the Cypher Editor in the UI.

bash — POST /cypher
# 1. Register node types (use 'string' for human-readable IDs) curl -sS -X POST http://localhost:8080/cypher \ -H 'Content-Type: application/json' \ -d '{"query":"CALL db.registerNodeType(\"CARD\", \"string\") YIELD node_type_id RETURN node_type_id","parameters":{}}' # Repeat for each type you need: MERCHANT, CUSTOMER, DEVICE, IP … curl -sS -X POST http://localhost:8080/cypher \ -H 'Content-Type: application/json' \ -d '{"query":"CALL db.registerNodeType(\"MERCHANT\", \"string\") YIELD node_type_id RETURN node_type_id","parameters":{}}' # 2. Register a relationship type curl -sS -X POST http://localhost:8080/cypher \ -H 'Content-Type: application/json' \ -d '{"query":"CALL db.registerEdgeType({name:\"TRANSACTS_AT\",from_node_type:\"CARD\",to_node_type:\"MERCHANT\"}) YIELD edge_type_id RETURN edge_type_id","parameters":{}}' # 3. Finalize schema — required before any write can succeed curl -sS -X POST http://localhost:8080/cypher \ -H 'Content-Type: application/json' \ -d '{"query":"CALL db.finalizeSchema() YIELD schema_version RETURN schema_version","parameters":{}}' # 4. Create nodes curl -sS -X POST http://localhost:8080/cypher \ -H 'Content-Type: application/json' \ -d '{"query":"CREATE (c:CARD {external_id: $id}) RETURN c.external_id AS created","parameters":{"id":"card-001"}}' # 5. Query back curl -sS -X POST http://localhost:8080/cypher \ -H 'Content-Type: application/json' \ -d '{"query":"MATCH (c:CARD {external_id: $id}) RETURN c.external_id AS id","parameters":{"id":"card-001"}}' # → {"columns":["id"],"rows":[["card-001"]]}

Explore visually in the Admin UI

Use the Cypher Editor, Schema Designer, and Graph Explorer — no CLI required.

http://localhost

Ready to add real-time graph intelligence?

Get JetGraph running in minutes with Docker. Works across any domain — fraud, recommendations, security, supply chain, and more.

$
docker compose up jetgraph