Skip to content

Commit fe5350e

Browse files
docs(demo): add live read-only demo, seed script, and Railway benchmark row
Public demo at rustyred-production-fc07.up.railway.app with a graph:read-only token; scripts/demo/seed.sh loads a small epistemic sample graph. benchmarks.md gains the measured Railway row (network-dominated PPR latency, noted).
1 parent 970c380 commit fe5350e

3 files changed

Lines changed: 102 additions & 2 deletions

File tree

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,44 @@ Under the hood: a RAM-first store with append-only-file + snapshot durability, H
1616

1717
Clicking the button deploys a single Railway service with a persistent volume, security-by-default, and a freshly generated API token. You get the same in-memory RAM-first graph database documented below — no Redis sidecar, no second service, no extra moving parts.
1818

19+
## Try it live (read-only)
20+
21+
A public RustyRed instance is already online with a small sample graph and a **read-only** token — nothing to deploy. The token carries only `graph:read`, so you can query, search, and run graph algorithms, but not mutate the data.
22+
23+
- **Base URL:** `https://rustyred-production-fc07.up.railway.app`
24+
- **MCP endpoint:** `https://rustyred-production-fc07.up.railway.app/mcp`
25+
- **Read-only token:** `rrdemo_aceb221d263a64a47a1e08b523fba4db617f02465fc8945d`
26+
27+
Point an agent at it (Claude Desktop / Cursor):
28+
29+
```json
30+
{
31+
"mcpServers": {
32+
"rustyred-demo": {
33+
"url": "https://rustyred-production-fc07.up.railway.app/mcp",
34+
"headers": { "Authorization": "Bearer rrdemo_aceb221d263a64a47a1e08b523fba4db617f02465fc8945d" }
35+
}
36+
}
37+
}
38+
```
39+
40+
Or curl it — an HNSW vector search and a PageRank over the sample graph:
41+
42+
```bash
43+
DEMO=https://rustyred-production-fc07.up.railway.app
44+
TOKEN=rrdemo_aceb221d263a64a47a1e08b523fba4db617f02465fc8945d
45+
46+
curl -s -X POST "$DEMO/v1/tenants/demo/graph/vector/search" \
47+
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
48+
-d '{"label":"Claim","property":"embedding","k":3,"query":[0.88,0.12,0.25,0.02,0.08,0,0,0]}'
49+
50+
curl -s -X POST "$DEMO/v1/tenants/demo/graph/algorithms/pagerank" \
51+
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
52+
-d '{"top_k":5}'
53+
```
54+
55+
The sample is a tiny epistemic knowledge graph about RustyRed itself, loaded by [`scripts/demo/seed.sh`](scripts/demo/seed.sh). Want your own instance with write access? Hit **Deploy on Railway** above.
56+
1957
## What Rusty Red does
2058

2159
- **Graph storage** with AOF/snapshot persistence, per-tenant isolation, single-writer serializable commits, and committed read snapshots

docs/benchmarks.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,18 @@ BASE_URL=https://<service>.up.railway.app TOKEN=<token> ./scripts/bench/run.sh
6868
| Environment | Ingest, nodes/sec | Ingest, edges/sec | PPR p50 | PPR p95 |
6969
|-------------|-------------------|-------------------|---------|---------|
7070
| Apple Silicon (Darwin arm64), release build, loopback HTTP | ~8,300 | ~4,800 | 27 ms | 42 ms |
71+
| Railway (shared instance), client over public internet | ~3,700 | ~3,000 | 248 ms | 319 ms |
7172

7273
Run: `VERSION=0.9.1 NODES=20000 PPR_TRIALS=50 ./scripts/bench/run.sh` (20,000 nodes,
7374
40,000 edges, 50 PPR trials, one warm-up discarded). Edge ingest is slower than
7475
node ingest because each edge validates both endpoints and the bulk loader
7576
commits in batches (default 500), refreshing the committed read view per batch.
7677

77-
A deployed-instance (Railway) row — same harness, with network latency folded
78-
into the PPR figure — belongs here once the public instance is live.
78+
Both rows are measured (2026-06-06). The Railway row is the **same harness run
79+
from a developer laptop against the live demo over the public internet**, so its
80+
PPR latency is dominated by client↔server round-trip time, not engine compute —
81+
the loopback row isolates the engine. A client co-located with the instance sees
82+
latency close to the loopback figure plus one network hop.
7983
<!-- BENCH_RESULTS_END -->
8084

8185
Numbers are point-in-time and machine-specific. The header of each run records

scripts/demo/seed.sh

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Seed the RustyRed public demo with a small epistemic knowledge graph about
4+
# RustyRed itself: Claim nodes carrying 8-dim embeddings, a Source, and
5+
# confidence-weighted epistemic edges (Supports / Cites). Designates the
6+
# embedding property for HNSW vector search and the text property for BM25
7+
# full-text, so the read-only demo token can exercise vector search, full-text
8+
# search, epistemic traversal, and the graph algorithms.
9+
#
10+
# Usage:
11+
# BASE_URL=https://<service>.up.railway.app TOKEN=<graph:write token> ./scripts/demo/seed.sh
12+
#
13+
# Env: BASE_URL (required), TOKEN (required, needs graph:write), TENANT (default "demo").
14+
15+
set -euo pipefail
16+
17+
BASE="${BASE_URL:?set BASE_URL}"
18+
TOKEN="${TOKEN:?set TOKEN (needs graph:write)}"
19+
TENANT="${TENANT:-demo}"
20+
base="${BASE%/}/v1/tenants/${TENANT}/graph"
21+
22+
jpost() {
23+
curl -fsS -H "Authorization: Bearer ${TOKEN}" -H "Content-Type: application/json" \
24+
-X POST "${base}/$1" -d "$2" >/dev/null
25+
}
26+
27+
echo "designating vector + full-text properties..."
28+
jpost vector/designate '{"label":"Claim","property":"embedding","dimension":8}'
29+
jpost fulltext/designate '{"label":"Claim","property":"text"}'
30+
31+
echo "loading nodes..."
32+
curl -fsS -H "Authorization: Bearer ${TOKEN}" -H "Content-Type: application/x-ndjson" \
33+
-X POST "${base}/bulk/nodes" --data-binary @- >/dev/null <<'JSONL'
34+
{"id":"claim:graph","labels":["Claim"],"properties":{"text":"RustyRed is a graph and vector database in one engine","embedding":[0.90,0.10,0.20,0.00,0.10,0.00,0.00,0.00]}}
35+
{"id":"claim:vector","labels":["Claim"],"properties":{"text":"RustyRed runs HNSW vector search over node properties","embedding":[0.80,0.20,0.30,0.10,0.00,0.00,0.00,0.00]}}
36+
{"id":"claim:epistemic","labels":["Claim"],"properties":{"text":"RustyRed models confidence-weighted epistemic edges","embedding":[0.85,0.15,0.25,0.05,0.05,0.00,0.00,0.00]}}
37+
{"id":"claim:mcp","labels":["Claim"],"properties":{"text":"RustyRed exposes a first-class MCP agent port","embedding":[0.10,0.00,0.00,0.90,0.20,0.10,0.00,0.00]}}
38+
{"id":"claim:ram","labels":["Claim"],"properties":{"text":"RustyRed is RAM-first with append-only-file durability","embedding":[0.00,0.10,0.10,0.80,0.30,0.00,0.00,0.00]}}
39+
{"id":"claim:rust","labels":["Claim"],"properties":{"text":"RustyRed is written in Rust","embedding":[0.05,0.00,0.00,0.85,0.25,0.10,0.00,0.00]}}
40+
{"id":"source:readme","labels":["Source"],"properties":{"text":"RustyRed GraphDB README","embedding":[0.40,0.10,0.10,0.40,0.10,0.00,0.00,0.00]}}
41+
JSONL
42+
43+
echo "linking epistemic edges..."
44+
edges=(
45+
'e:cite:graph|source:readme|claim:graph|CITES|cites|1.0'
46+
'e:cite:vector|source:readme|claim:vector|CITES|cites|1.0'
47+
'e:cite:mcp|source:readme|claim:mcp|CITES|cites|1.0'
48+
'e:sup:graph_vector|claim:graph|claim:vector|SUPPORTS|supports|0.95'
49+
'e:sup:graph_epi|claim:graph|claim:epistemic|SUPPORTS|supports|0.9'
50+
'e:sup:rust_ram|claim:rust|claim:ram|SUPPORTS|supports|0.9'
51+
'e:sup:mcp_graph|claim:mcp|claim:graph|SUPPORTS|supports|0.85'
52+
)
53+
for spec in "${edges[@]}"; do
54+
IFS='|' read -r id from to type epi conf <<<"${spec}"
55+
jpost edges "{\"id\":\"${id}\",\"from_id\":\"${from}\",\"to_id\":\"${to}\",\"type\":\"${type}\",\"epistemic_type\":\"${epi}\",\"confidence\":${conf}}"
56+
done
57+
58+
echo "demo seeded into tenant '${TENANT}'."

0 commit comments

Comments
 (0)