Skip to content

Performance and comparisons

The closest alternative inside PostgreSQL is pgGraph (Apache-2.0, Rust/pgrx), so it comes first below. Its column was checked against pgGraph 1.2.1, its latest release on 29 October 2026: its user guide and, for threading, its source. Where pg_warren fits compares the two in more depth. pgGraph has not been benchmarked against pg_warren, so it has no column under Performance.

Outside PostgreSQL, pg_warren was timed against igraph (python-igraph 1.0.0) and Neo4j 2026.10 Community. Neo4j ran both as plain Cypher and with the Graph Data Science library (GDS). All three ran on the same machine, over 12 real graphs from the benchmark corpus, from 77 nodes up to 1.4M nodes and 3.8M edges. A time counts only if that engine’s answer matched the reference.

pg_warren pgGraph 1.2.1 igraph Neo4j (Cypher) Neo4j + GDS
Where it lives
Runs inside PostgreSQL, over your existing tables ✅ ✅ ❌ ❌ ❌
No separate service to run ✅ ✅ ✅ (in-process library) ❌ ❌
Queried from SQL, joined with relational data ✅ ✅ ❌ ❌ ❌
Discovers the graph from primary and foreign keys ❌ (you write node and edge queries) ✅ — — —
Consistency and freshness
Analytics see the live data with no rebuild ❌ (reads a built version) ✅ (trigger sync, applied on read) ❌ (load on each run) ✅ ❌ (projections)
Graph built inside your transaction, rolled back with it ✅ ❌ (a build needs your changes committed) ❌ ✅ (the store is the graph) ❌
Versioned graphs: stage, diff, promote ✅ ❌ (generations published under MVCC; no staging or diff) ❌ ❌ ❌
Saved results bound to the graph version that made them ✅ ❌ (results are returned, not stored) ❌ ❌ partial (mutate mode, in the in-memory projection)
Graph stored in WAL-logged PostgreSQL tables ✅ ❌ (validated files under $PGDATA) — — —
Replicated to streaming standbys ✅ ❌ (documented: no standby support) ❌ Enterprise Enterprise
Querying and algorithms
Path pattern matching: multi-step paths by relation, direction, node filter and hop range ✅ (warren.walk) ✅ (GQL and openCypher MATCH) partial (subgraph isomorphism) ✅ ✅
Graph query language (Cypher, GQL): variables and joins inside a pattern ❌ (SQL functions; join walks in SQL) ✅ (bounded GQL and openCypher subsets) ❌ ✅ ✅
Traversals (BFS, reach, k-hop, paths) ✅ ✅ (BFS, DFS, weighted paths) ✅ ✅ ✅
Connected components ✅ ✅ ✅ ❌ ✅
PageRank and centralities ✅ (core set) ❌ ✅ (very broad) ❌ ✅ (broad)
Community detection (Louvain, Leiden) ✅ ❌ ✅ ❌ ✅
Node embeddings, link prediction, ML pipelines ❌ (building blocks only) ❌ ❌ ❌ ✅
Semiring linear algebra, spectral analysis ✅ ❌ partial ❌ ❌
Multi-threaded ✅ ❌ (one thread per query; builds can run in a background worker) ❌ Enterprise ✅ (4 threads in Community)
Maturity
Production track record, tooling, visualisation ❌ (pre-1.0) partial (1.x since July 2026; SQL playground) ✅ ✅ ✅

— : the row is about PostgreSQL tables and does not apply to an engine outside PostgreSQL. pgGraph’s cells are sourced from its supported features, limits and fit, sync, persistence and SQL API pages.

Faster than pgGraph 1.2.1, the closest alternative inside PostgreSQL, on every workload both support (2.4–89× on shortest paths, 1.7–14× on connected components), with versions, standbys and whole-graph algorithms it doesn’t have.

Times are warm medians.

Workload pg_warren pgGraph igraph Neo4j + GDS Verdict
Shortest paths, 25 pairs (dblp) 5.8 ms 73 ms 0.26 s 2.22 s 🟢 Bidirectional BFS, all pairs in one call: faster than pgGraph on 12 of 12 graphs (2.4–89×), than igraph’s early-exit get_shortest_path on 7 of 12 (2.7–44×; igraph up to 2.7× faster on tiny and road graphs), than Cypher’s like-for-like shortestPath on 11 of 11 (2.6–23×)
Louvain communities (dblp) 1.16 s — 5.49 s 12.7 s 🟢 Faster than GDS on every graph, than igraph on 7 of 12
Triangles (hetionet) 0.12 s — 0.49 s 2.88 s 🟢 Faster than igraph on 10 of 12 graphs
Time to first query 0.01–3.8 s 0.07–78 s about the same 13–18 s 🟢 No server to start or data to import; pgGraph’s build takes 5–21× longer
PageRank, 20 iterations (roadNet-TX) 0.22 s — 0.81 s 0.62 s 🟢 Faster than igraph on 7 of 12 graphs; slower on 5, by 1.2–3× and on the tiny lesmis 100× (a call’s fixed cost); faster than GDS on all 12
BFS and connected components 🟡 slowest fastest slower 🟡 Ahead of GDS, and of pgGraph by 1.7–420×; igraph 1.2–66× faster on all but 3 of 36 cells
Leiden communities (FB15k-237) 0.21 s — 0.14 s 0.46 s 🟡 Within 1.6× of igraph on medium graphs, faster on 4 of 12; faster than GDS on 7 of 11

Plain Cypher is not in the table. It cannot express PageRank, components, Louvain, Leiden or betweenness. On the larger graphs, its traversal and triangle queries ran past a 300-second timeout. pgGraph’s SQL API has traversal, shortest paths and components, but no degree, PageRank, triangles or community detection (—).

Caveats. Most rows are one run on a shared 4-vCPU VM. pg_warren and GDS used 4 threads; igraph, Cypher and pgGraph are single-threaded. Every time includes the client round trip. A warm pg_warren traversal call costs 25–70 µs more than SELECT 1. A function that writes a vector costs about 1 ms more, to persist it and commit. These fixed costs dominate on tiny graphs. The Louvain figure predates two later optimisations, so pg_warren’s time there may now be lower. The triangles row was re-timed after them, and the PageRank and Leiden rows on 0.8.0’s native pagerank and leiden, against igraph only (PageRank in three interleaved rounds on all 12 graphs). The shortest-paths, time-to-first-query and BFS rows, and every pgGraph figure, are from a later run of 0.8.0 beside pgGraph 1.2.1 (its recommended configuration) and igraph, where igraph’s pairs used get_shortest_path, which stops at the target without first rebuilding the adjacency list as distances does; the Cypher margins are from the earlier run, against 0.7.0. GDS was not re-run: every GDS figure is from the earlier run, against 0.7.0. Full tables, settings and caveats are in bench/results/corpus/head_to_head.