Repository navigation
Graphersal 0.3.0
The engine learns what its graph holds and how it is used, and acts on it:
- workload statistics
- scheduled jobs
- memory report
- storage advisor
- Optimize panel in the playground
Dates and times reach nanosecond resolution, the in-memory graph takes markedly less memory (from 10 to 40% depending on the graph structure) and execute queries faster (10%).
It is not a drop-in update for every caller: read "Upgrading from 0.2" first.
Prebuilt binaries
The graphersal command line tool is attached to this release for Linux (x86_64, aarch64), macOS (arm64, x86_64) and Windows (x86_64), with a SHA256SUMS file and build provenance attestations (gh attestation verify <archive> --repo graphersal/graphersal); cargo binstall graphersal-cli installs it too. The Linux binaries are static musl builds, which run on every distribution but use musl's slower memory allocator: build from source for benchmarks (Performance of the prebuilt Linux binaries).
Upgrading from 0.2
- Graphersal's own DSL functions are snake_case only. The camelCase twins of 63 extensions are removed (
createIndex,defineQuery,memoryReport,removeProperty,globPath,addLabel,setLabel,dropLabel,toJson,toTable,toMermaid,toPlantUML,firstName,dateTrunc,localDateTime, ...). TinkerPop's steps and functions keep both spellings (hasLabelandhas_label), as do five names of the Java API (containsKey,isEmpty,toMap,Set.ofList,UUID.fromString). A script that still calls a removed name fails with a help that names the snake_case function (Writing Queries). Rendering in camelCase (render.spelling) keeps these names in snake_case, so the text still runs. - File format version 3. Every file this version writes (snapshots, journal segments,
.gsnap, backups) is of format version 3, which holds the new temporal values. 0.3.0 reads every older file; 0.2.x refuses a version 3 file with a clear "unsupported version" error (never as damage). Keep a backup made by 0.2.x if you may need to go back. The store format version is unchanged (Format Versions and Upgrade). - Temporal values hold nanoseconds (were microseconds); see "Dates and times" below.
- Rust API: the
DTtoken gainedDT::Nanosecondas its first unit, so the numeric values of its variants moved (only code casting aDTwithassees it;cargo-semver-checksreports nothing else). Every other change is an addition: new modulesadvisor,jobsandworkload, new methods (Graph::advise,Graph::attach_workload_stats,memory_report, ...) and#[non_exhaustive]structs.
Added
- Memory report (Memory and Profiling):
g.memory_report()(REPL/memory, MCPmemory_report, dev serverPOST /api/memory/report, Pythonmemory_report()): one row per label and property with the bytes it takes, value types, a size histogram, distinct strings, what is compressed or indexed, and the structure's own share (slots, ids, labels, shapes, indexes). Sampled on large labels. - Workload statistics (Workload Statistics): a store counts what its queries do, per minute, hour and day (kept for 60 minutes, 48 hours and 90 days, persisted in the sidecar file
WORKLOAD): queries by normalized plan (apg_stat_statementsanalogue), how each property is used (filtered by a scan or an index, read, ordered, compared by similarity, written), the graph lock's wait and hold times, and the scheduled jobs; per channel (playground, MCP, CLI, Python, job, host). The playground's own drawing and panels are not counted. Read throughGET /api/workload[?history=minutes|hours|days], the MCP toolworkload_statistics, REPL/workload, Pythonworkload_report(); their memory shows asworkload_bytesing.memory_usage(). - Scheduled jobs (Scheduled Jobs): a cron scheduler the host ticks (no thread in the engine; the dev server and the browser playground tick it). System jobs (
stats_flush,compact) whose schedule and switch can be changed, and jobs of users as catalog definitions (kindjob):g.define_job(#{name, schedule, action, ...})runs a saved query with fixed arguments, a checkpoint or a backup, with the definer's rights checked once and stored as the job's effects; limits per run (timeout, memory); every run recorded. Managed in the playground's Catalog ▸ Scheduled jobs, over/api/jobs*, MCPlist_jobs. - Storage advisor and the Optimize panel (Optimize): recommendations from the memory report, the workload statistics and the catalog: create an index for a key filtered often by a full scan, drop an index no query used, compress or deduplicate large strings (savings measured on the data), stop compressing a key read often. Each names the catalog command that applies it; Apply runs it, Snooze and Dismiss hide it, and an applied one reports what it changed for 30 days. The playground's Optimize panel also shows the workload statistics as tables with sparklines and charts, and the memory report. Over HTTP
/api/advise*, MCPadvise, RustGraph::advise(modulegraphersal::advisor). - Process memory in the statistics:
process.memory(resident set size where the system reports it, the live heap, WebAssembly memory), loaded models and the AI Chat history, beside the graph's own footprint (playground Profile ▸ Statistics). - Dates and times (Dates and Times): nanosecond resolution for
time,localdatetime,datetimeandduration;offsettime; a zone name given to adatetimeis kept; the wholejava.time.Durationrange; ISO GQL temporal literals and clocks; Python returns nanosecond values aspandas.Timestamp/pandas.Timedeltawhere pandas is installed. - Playground: a filter for the drawn graph (labels and property conditions), a compact Graph toolbar with a Display menu (vertex size by degree), in/out degree in the inspector, reloads throttled while the graph changes fast, shape bytes on the Statistics tab, four
subgraph()examples; the Share link is hidden with the dev server (it cannot carry a server's graph). - OpenAPI description of the dev server's HTTP API (EXPERIMENTAL, The HTTP API):
crates/graphersal-cli/openapi.jsonin the repository, served bygraphersal --serveratGET /openapi.json, its version the release's; a test keeps it in step with the router. - CLI and dev server:
--args-file FILE/@FILE(a JSON file of arguments),--mcp-instructions FILE(operator notes in the MCP instructions); MCP answers are compact JSON, cut at whole results, withoffsetpaging; the AI Chat accepts a customsystem_prompt, reports lenient keys with hints, and shows each answer's time.
Changed
- Less memory for the same graph. Stored property maps share their key lists (property shapes), the id index keeps no second copy of an id, vertex and edge slots are an own topology (petgraph is no longer a dependency) with interned label sets, and a load leaves no spare capacity. On the project's own knowledge graph (40k vertices, 190k edges) the graph took about half the memory of 0.2.3.
- GQL
MERGEwithout an index finds its match through a scan lookup, about ten times faster. - The MCP instructions and tool descriptions prefer GQL for reading and writing data.
Format
- File format version 3 (format spec, section 3): new value tags for the nanosecond temporal values; versions 1 and 2 stay readable.
- The workload statistics sidecar
WORKLOAD(format spec, section 4.4, version 2): instance data, never in the journal, a snapshot or a backup; an unreadable or newer file means the statistics start anew. It also keeps the system jobs' settings and the advisor's marks. - Catalog kind 4: a scheduled job of a user (format spec, section 6.3).