No description
  • Rust 68.3%
  • HTML 31.7%
Find a file
Kristof c3a8ebcf05
Some checks failed
lab release / release (push) Failing after 8s
Build and Test / build (push) Failing after 1m25s
fix: update admin router and template to /api path convention
Switch health endpoint from /health to /health.json, update proxy comment
and rpc_url to /api/rpc, and fix domain routing in base.html to replace
/api/rpc with /api/{domain}/rpc instead of the old /d/{domain}/rpc pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 15:51:10 +02:00
.cargo build: enable sccache and disable incremental compilation 2026-05-30 15:21:11 +02:00
.claude chore: replace Keys pane with full RedisUI browser, add perf_batch_db, misc cleanups 2026-06-06 13:54:23 +02:00
.codegraph fix: update RPC/OpenRPC paths to /api prefix and patch hero_lib locally 2026-06-14 15:19:53 +02:00
.forgejo/workflows ci: canonical lab-release (cargo check + multi-arch + hero.releaser) 2026-06-10 20:08:31 +02:00
.hero refactor: remove custom session auth from hero_db_admin, fetch theme from hero_proc 2026-05-10 23:05:32 +02:00
crates fix: update admin router and template to /api path convention 2026-06-14 15:51:10 +02:00
docs refactor: rename FORGEJO_TOKEN→FORGE_TOKEN and HERO_SOCKET_DIR→PATH_SOCKET 2026-05-26 12:35:02 +02:00
rhai_examples feat: rename hero_redis to hero_db across entire codebase 2026-04-04 11:15:44 +02:00
specs refactor: rename FORGEJO_TOKEN→FORGE_TOKEN and HERO_SOCKET_DIR→PATH_SOCKET 2026-05-26 12:35:02 +02:00
.gitignore chore: remove Cargo.lock and update gitignore 2026-06-06 08:05:00 +02:00
Cargo.toml chore: remove temporary hero_lib path patch now the fix is upstream 2026-06-14 15:38:19 +02:00
LICENSE Hero Redis: optimized Redis server on redb 2025-12-25 10:08:48 +01:00
README.md chore: replace Keys pane with full RedisUI browser, add perf_batch_db, misc cleanups 2026-06-06 13:54:23 +02:00
rust-toolchain.toml build: bump toolchain to Rust 1.96, propagate rust-version to crates, remove backup file 2026-06-01 06:34:39 +02:00

Hero Redis

A high-performance, Redis-compatible server with ChaCha20-Poly1305 encryption and secret-based authentication.

Architecture

hero_db/
├── Cargo.toml # workspace root
├── crates/
│ ├── hero_db/ # library: core Redis protocol + server implementation
│ ├── hero_db_sdk/ # library: RESP2 client + admin helpers
│ ├── hero_db_server/ # binary: daemon, OpenRPC management socket, database backend
│ ├── hero_db_admin/ # binary: Axum+HTML admin dashboard (Unix socket only)
│ └── hero_db_examples/ # example programs using the SDK

Ports & Sockets

Socket / Port Protocol Description
$PATH_SOCKET/hero_db/rpc.sock HTTP/1.1 OpenRPC JSON-RPC 2.0 management API
$PATH_SOCKET/hero_db/resp.sock RESP2 Redis wire protocol (redis-cli / SDK via Unix)
TCP 0.0.0.0:6378 RESP2 Redis wire protocol (redis-cli / SDK via TCP)
$PATH_SOCKET/hero_db/admin.sock HTTP/1.1 Admin web dashboard (via hero_router)

PATH_SOCKET defaults to ~/hero/var/sockets.

Each socket serves exactly one protocol — no multiplexing.

Features

  • Redis Protocol Compatible - Works with redis-cli and any Redis client library
  • Secret-based Auth - AUTH <secret> / SAUTH <secret> with per-user ACLs
  • Open Mode - Run without authentication (like standard Redis with no requirepass)
  • Multi-Database with ACL - Per-database Read/Write/Admin permissions per user
  • Persistent Storage - Data stored in the database engine
  • Encryption - All values encrypted with ChaCha20-Poly1305
  • Multiple Databases - Up to 1000 databases with lazy loading
  • Low Memory - ~3MB at startup, databases loaded on demand
  • Auto-cleanup - Idle databases automatically closed after 5 minutes
  • Unix Socket & TCP - Both connection methods supported
  • Vector Search - HNSW-based similarity search with the hannoy library
  • Cross-platform - Linux (x86_64, aarch64) and macOS (x86_64, aarch64)

Quick Start

Install from Binaries

Download from the Forge package registry:

mkdir -p ~/hero/bin
# Download server and admin
curl -fsSL -o ~/hero/bin/hero_db_server \
 "https://forge.ourworld.tf/api/packages/lhumina_code/generic/hero_db/dev/hero_db_server-x86_64-unknown-linux-musl"
curl -fsSL -o ~/hero/bin/hero_db_admin \
 "https://forge.ourworld.tf/api/packages/lhumina_code/generic/hero_db/dev/hero_db_admin-x86_64-unknown-linux-musl"
chmod +x ~/hero/bin/hero_db_server ~/hero/bin/hero_db_admin

Add to your PATH (if not already):

export PATH="$HOME/hero/bin:$PATH"

Supported platforms: Linux x86_64 (amd64), Linux aarch64 (arm64), macOS Apple Silicon (darwin-arm64)

Build from Source

git clone https://forge.ourworld.tf/lhumina_code/hero_db.git
cd hero_db
lab build # release build
lab service db --install # install all binaries to ~/hero/bin/

Start Server (Open Mode — No Auth)

The simplest way to run Hero Redis, just like standard Redis with no password:

hero_db_server

Connect and use immediately:

redis-cli -p 6378
> SET mykey myvalue
OK
> GET mykey
"myvalue"

In open mode, databases are auto-created on first use (SELECT 1, SELECT 2, etc.).

Start Server (With Authentication)

Pass one or more --admin-secret flags to enable authentication:

hero_db_server \
 --encryption-key "your-encryption-key" \
 --admin-secret "my-secret-password"

Then authenticate before executing commands:

redis-cli -p 6378
> AUTH my-secret-password
OK
> SET mykey myvalue
OK

SAUTH <secret> works identically to AUTH <secret>.

Start Server + UI (via lab / hero_proc)

lab service db --install # build + install all binaries
lab service db --start # register with hero_proc and start server + admin
lab service db --stop # stop all components
lab service db --status # show running status

Testing with redis-cli

Once the server is running (lab service db --start), connect via TCP:

redis-cli -p 6378

Basic smoke test:

# Connection
redis-cli -p 6378 PING
# → PONG

# String
redis-cli -p 6378 SET mykey "hello from hero_db"
redis-cli -p 6378 GET mykey
# → hello from hero_db

# Hash
redis-cli -p 6378 HSET user:1 name Alice age 30
redis-cli -p 6378 HGETALL user:1
# → name Alice age 30

# List
redis-cli -p 6378 RPUSH mylist a b c
redis-cli -p 6378 LRANGE mylist 0 -1
# → a b c

# Server info
redis-cli -p 6378 DBSIZE
redis-cli -p 6378 INFO server

Or test via the Unix socket directly (bypasses TCP, useful for local scripts):

redis-cli -s ~/hero/var/sockets/hero_db/resp.sock PING
# → PONG

Authentication

Hero Redis supports two modes:

Open Mode (No Auth)

Start without --admin-secret. Any AUTH call is accepted immediately. This is the default.

hero_db_server --data-dir ~/.hero_db

Pass --admin-secret to require authentication. Multiple secrets can be set (one per flag):

hero_db_server \
 --encryption-key "your-key" \
 --admin-secret "admin-secret-1" \
 --admin-secret "admin-secret-2"

Authenticate with:

AUTH <secret> # standard Redis AUTH (works with any Redis client)
SAUTH <secret> # hero_db extension (identical behaviour)

Create per-database users:

USER.CREATESECRET alice alice-secret-123
USER.GRANT 1 alice write

Users authenticate with their own secret:

AUTH alice-secret-123

Command Line Options

hero_db_server

Option / Env Var Default Description
HERO_DB_DATA_DIR ~/.hero_db Database directory
HERO_DB_SERVER_SOCKET $PATH_SOCKET/hero_db/rpc.sock Unix socket for JSON-RPC management
HERO_DB_PORT 6378 TCP port for Redis RESP2 protocol
HERO_DB_ENCRYPTION_KEY hero_db_default_key Encryption key for DB 0
REDIS_ADMIN_SECRET (none) Admin secret (enables auth mode)
RUST_LOG info Log level (debug, trace, etc.)

Auth behavior:

  • No --admin-secret set → open mode (any AUTH call accepted)
  • One or more --admin-secret flags → auth required before commands

User Management

Create Users

# As server admin — create a user with a secret
USER.CREATESECRET <username> <secret>

# Example
USER.CREATESECRET alice mysecretpassword

Grant / Revoke Permissions

# Grant a user access to a specific database
USER.GRANT <db_number> <username> <read|write|admin>

# Examples
USER.GRANT 1 alice write
USER.GRANT 2 bob read

# Revoke
USER.REVOKE <db_number> <username>
USER.REVOKE 1 alice

Delete a User

USER.DELETE <username>

Permission Levels

Level Can Read Can Write Can FLUSHDB Can USER.GRANT Can DATABASE.CREATE
read Yes No No No No
write Yes Yes No No No
admin Yes Yes Yes Yes (same db) No
server admin Yes Yes Yes Yes Yes

Admin Commands

Server Admin Commands

Command Description
DATABASE.CREATE <encryption_key> Create new database, returns db number
DATABASE.STATUS [db|all] Show database info
DATABASE.PUBLIC <db> <on|off> Enable/disable public read-only access
USER.CREATESECRET <username> <secret> Create a secret-based user
USER.DELETE <username> Delete a user

Database Admin Commands

Command Description
USER.GRANT <db> <username> <perm> Grant permission (read/write/admin)
USER.REVOKE <db> <username> Revoke permission
FLUSHDB Clear current database

Public Read-Only Access

# Make database 1 readable by anyone (no auth required for reads)
DATABASE.PUBLIC 1 on

# Reads work without AUTH; writes still require it
GET publickey # OK
SET key value # ERR not authenticated

Supported Redis Commands

Authentication

AUTH, SAUTH

String Commands

GET, SET, MGET, MSET, DEL, EXISTS, EXPIRE, TTL, KEYS, SCAN, INCR, INCRBY, DECR, DECRBY, APPEND, STRLEN, GETRANGE, SETNX, SETEX, GETSET, TYPE

Hash Commands

HSET, HGET, HMSET, HMGET, HGETALL, HDEL, HEXISTS, HLEN, HKEYS, HVALS, HINCRBY, HSETNX, HSCAN

List Commands

LPUSH, RPUSH, LPOP, RPOP, LRANGE, LLEN, LINDEX, LSET, LREM

Set Commands

SADD, SREM, SMEMBERS, SISMEMBER, SCARD, SPOP, SUNION, SINTER, SDIFF, SSCAN

Stream Commands

XADD, XLEN, XRANGE, XREVRANGE, XREAD, XINFO, XTRIM, XGROUP, XREADGROUP, XACK, XPENDING

Vector Commands

VECTOR.CREATE, VECTOR.ADD, VECTOR.SEARCH, VECTOR.SEARCHBYID, VECTOR.GET, VECTOR.DEL, VECTOR.BUILD, VECTOR.INFO, VECTOR.LIST, VECTOR.DROP, VECTOR.CLEAR, VECTOR.EXISTS, VECTOR.LEN

Connection Commands

PING, AUTH, SAUTH, SELECT, QUIT, COMMAND

Management Commands

COMPACT, SHUTDOWN, MEMORY USAGE, MEMORY STATS, DBSIZE, FLUSHDB, INFO, CONFIG, CLIENT

Admin UI

Hero Redis includes an admin dashboard at $PATH_SOCKET/hero_db/admin.sock. Access it through hero_router at http://localhost:9988/hero_db/ui/.

When both services are running (lab service db --start), log in with your admin secret (or user secret).

The dashboard is a hash-routed single page (deep-linkable, e.g. …/ui/#/keys) with these panes:

Pane Route What it does
Command #/command Run arbitrary Redis commands and see the raw reply
RedisUI #/redis_ui Full keyspace tree browser (see below)
Redis Cmds #/redis-cmds Per-command form panels for every supported command
API Docs #/api-docs Live OpenRPC method browser for the running server
Ontology #/ontology Ontology document editor
Vector #/vector Vector index management and similarity search
Benchmark / Graph Bench #/benchmark, #/graph-bench Throughput/latency benchmarks
Graph #/graph Property-graph node/edge explorer
Server #/server Server info, config, and runtime stats

RedisUI key browser (#/redis_ui)

A proper Redis UI for inspecting and editing the live keyspace:

  • Namespace tree — keys are split on : into a collapsible folder tree (so user:1:name, user:1:email, user:2:name nest under user → 1 / 2), with a per-branch leaf count, expand/collapse-all, and a live text filter that auto-expands matches. Keys are discovered with a full SCAN sweep (not a single KEYS snapshot) and each leaf shows a colour-coded type badge.
  • Type-aware detail panel — selecting a key renders it according to its type:
    • string — editable textarea (pretty-prints JSON), Save writes back via SET.
    • hash — field/value table with inline add / edit / delete (HSET / HDEL).
    • list — indexed item list with LPUSH / RPUSH.
    • set — member list with add (SADD) and remove (SREM).
    • zset — members with scores.
    • stream — entries with their ID and field badges.
  • Key operations — create a new key (string / hash / list / set), view & set TTL (or persist), reload, and delete the whole key.

The pane talks to the server over the per-domain rpc_kvs.sock OpenRPC socket (proxied through the admin as /d/kvs/rpc); it is built as a server-rendered Askama template (templates/pane_keys.html, rendered by panes::keys::KeysPane) using Bootstrap + the shared Hero admin runtime, no build step.

SDK / Rust Client

[dependencies]
hero_db_sdk = { path = "crates/hero_db_sdk" }
use hero_db_sdk::hero_db_client::HeroDbClient;

// TCP connection (auth mode)
let mut client = HeroDbClient::new("127.0.0.1", 6378, "my-secret")?;

// Unix socket connection
let mut client = HeroDbClient::new_unix(
 "~/hero/var/sockets/hero_db/resp.sock",
 "my-secret",
)?;

// Open mode (pass any string as secret)
let mut client = HeroDbClient::new("127.0.0.1", 6378, "")?;

client.select(1)?;

// String operations
client.set("name", "Alice")?;
let name = client.get("name")?.unwrap();

// Hashes
client.hset("user:1", "name", "Bob")?;
let user = client.hgetall("user:1")?;

// Lists
client.rpush("queue", "job1")?;
let job = client.lpop("queue")?;

// Sets
client.sadd("tags", "rust")?;
let tags = client.smembers("tags")?;

// Admin operations
use hero_db_sdk::hero_db_client::AdminOperations;
let db_num = client.admin().create_database("db-encryption-key")?;
client.admin().grant_permission(db_num, "alice", Permission::Write)?;

Hero Redis includes HNSW-based vector similarity search using the hannoy library.

Quick Start

# Create a vector index (128 dimensions, cosine similarity)
VECTOR.CREATE embeddings 128 METRIC cosine

# Add vectors (JSON format)
VECTOR.ADD embeddings 1 [0.1, 0.2, 0.3, ...]
VECTOR.ADD embeddings 2 [0.4, 0.5, 0.6, ...]

# Build the HNSW index (required before searching)
VECTOR.BUILD embeddings

# Search for similar vectors (returns top 10)
VECTOR.SEARCH embeddings [0.1, 0.2, 0.3, ...] 10

# Search by existing vector ID
VECTOR.SEARCHBYID embeddings 1 10

Vector Commands Reference

Command Description
VECTOR.CREATE <index> <dims> METRIC <cosine|euclidean|manhattan> Create index
VECTOR.ADD <index> <id> <json_vector> Add single vector
VECTOR.BUILD <index> Build HNSW graph (required before search)
VECTOR.SEARCH <index> <json_vector> <k> Find k nearest neighbors
VECTOR.SEARCHBYID <index> <id> <k> Find neighbors of existing vector
VECTOR.GET <index> <id> Get vector by ID
VECTOR.DEL <index> <id> Delete vector
VECTOR.INFO <index> Get index statistics
VECTOR.LEN <index> Get vector count
VECTOR.LIST List all indexes
VECTOR.DROP <index> Delete index
VECTOR.CLEAR <index> Remove all vectors

Distance Metrics

Metric Description Use Case
cosine Cosine similarity Text embeddings (OpenAI, etc.)
euclidean L2 distance Image embeddings
manhattan L1 distance Sparse vectors

Common Embedding Dimensions

Model Dimensions
OpenAI text-embedding-ada-002 1536
OpenAI text-embedding-3-small 1536
Cohere embed-english-v3.0 1024
all-MiniLM-L6-v2 384
BGE-base-en 768

See docs/ai_embeddings.md for complete documentation.

Graph

Hero Redis includes a built-in property graph engine supporting nodes and edges with arbitrary JSON properties, multi-hop traversal, shortest-path queries, and statistics. Graphs are stored per-database alongside regular key/value data.

Graph Commands Reference

Command Description
graph.node.add <id> <props_json> Add a node with properties
graph.node.get <id> Get a node by ID
graph.node.set <id> <props_json> Update node properties
graph.node.del <id> Delete a node
graph.node.find <filter_json> Find nodes matching a property filter
graph.node.count Count all nodes
graph.edge.add <src> <dst> <label> <props_json> Add a directed edge
graph.edge.get <src> <dst> <label> Get an edge
graph.edge.del <src> <dst> <label> Delete an edge
graph.edge.find <filter_json> Find edges matching a property filter
graph.edge.count Count all edges
graph.neighbors <id> List neighbors of a node
graph.traverse <start_id> <depth> Traverse the graph from a node up to a given depth
graph.path <src_id> <dst_id> Find shortest path between two nodes
graph.stats Return node/edge counts and graph statistics
graph.clear Remove all nodes and edges

Data Storage

  • Data directory: ~/.hero_db/ (configurable with --data-dir)
  • Database files: db0.db, db1.db, ... db999.db
  • DB 0 is reserved for admin metadata (secrets, ACLs, database registry)
  • Each database has its own encryption key
  • Values are encrypted with ChaCha20-Poly1305

Building & Publishing

Lab Commands

lab build # release build
lab service db --install # build + install all binaries to ~/hero/bin/
cargo check # fast syntax check
cargo test --workspace # unit tests
cargo fmt # format code
cargo clippy # lint
lab service db --start # install + start services via hero_proc
lab service db --stop # stop all services
lab service db --status # show service status

Pre-built Binaries

Pre-built binaries are published to the Forgejo package registry:

Binary Platforms Description
hero_db_server x86_64-unknown-linux-musl, aarch64-unknown-linux-gnu Redis-compatible server
hero_db_admin x86_64-unknown-linux-musl, aarch64-unknown-linux-gnu Admin web dashboard

CI/CD Workflows

The Forgejo workflows (.forgejo/workflows/) build and publish on tagged releases:

  • build-linux.yaml: Builds for linux-amd64 and linux-arm64 (with UPX compression)
  • build-macos.yaml: Builds for darwin-arm64 (native macOS host)

License

Apache 2.0