Lynxes
A Fast, Zero-Copy Graph Analytics Engine Built Natively on Apache Arrow.
Why Lynxes | Quickstart | API Overview | Architecture
Lynxes is a blazingly fast, lazy-evaluated graph analytics engine. Unlike traditional Python libraries that wrap generic structures, Lynxes builds a graph-native engine directly over Arrow, completely bypassing the overhead of NetworkX or igraph.
Why Lynxes
- Zero-Copy Arrow Backing —
NodeFrameandEdgeFramedirectly own Apache ArrowRecordBatch. No intermediate copies, no Pandas/Polars dependency. - Graph Structure as a First-Class Citizen —
EdgeFramealways maintains a Compressed Sparse Row (CSR) index. Neighbor lookups are O(degree) from day one — no full table scans. - Lazy by Default — No computation happens until you call
.collect(). The built-in optimizer runs Predicate Pushdown, Projection Pushdown, Traversal Pruning, and Subgraph Caching before execution. - Language-Agnostic Core — The query engine, storage engine, and graph algorithms are written entirely in Rust. Python is a thin zero-overhead PyO3 wrapper.
Quickstart
Install
pip install lynxes
# or
uv add lynxes
Build from source
git clone https://github.com/your-org/lynxes
cd lynxes/py-lynxes
uv run maturin develop --release
Python API
import lynxes as lx
# Load from .gf text, .gfb binary, or Parquet
g = lx.read_gf("graph.gf")
# g = lx.read_parquet_graph("nodes.parquet", "edges.parquet")
# g = lx.read_gfb("graph.gfb")
# Build a lazy plan — nothing executes yet
result = (
g.lazy()
.filter_nodes(lx.col("age") > 25)
.expand("KNOWS", hops=2, direction="out")
.aggregate_neighbors("KNOWS", lx.count().alias("friend_count"))
.sort("friend_count", descending=True)
.limit(10)
.collect()
)
print(result)
Pattern Matching
Cypher-like pattern matching over the lazy execution engine:
result = (
g.lazy()
.match_pattern(
[
lx.node("person", "Person"),
lx.edge("WORKS_AT"),
lx.node("company", "Company"),
],
where_=lx.col("person.age") > 25,
)
.collect()
)
Graph Algorithms
# PageRank
pr = g.pagerank() # → NodeFrame with 'pagerank' column
# Shortest path
path = g.shortest_path("alice", "charlie") # → ["alice", "bob", "charlie"]
# Connected components
cc = g.connected_components() # → NodeFrame with 'component_id' column
# Betweenness centrality
bc = g.betweenness_centrality()
# Community detection (Louvain / Label Propagation)
cm = g.community_detection()
Remote Connectors
# Neo4j (Cypher)
g = lx.read_neo4j("bolt://localhost:7687", "neo4j", "password")
# ArangoDB (AQL)
g = lx.read_arangodb(
endpoint="http://localhost:8529",
database="mydb",
graph="social",
vertex_collection="persons",
edge_collection="knows",
)
# SPARQL endpoint
g = lx.read_sparql(
endpoint="https://dbpedia.org/sparql",
node_template="SELECT ?id WHERE { ?id a <Thing> }",
edge_template="SELECT ?s ?o WHERE { ?s ?p ?o }",
)
Distributed Graph Partitioning
# Partition a large graph across N shards
pg = g.partition(4, strategy="hash") # or "range" / "label"
print(pg.n_shards) # 4
print(pg.stats()) # imbalance ratio, boundary edges, …
# BFS across shard boundaries
nodes, edges = pg.distributed_expand(["alice"], hops=2, direction="out")
# Merge shards back into one GraphFrame
merged = pg.merge()
CLI
# Inspect a .gfb file
lynxes inspect graph.gfb
# Convert formats
lynxes convert graph.gf graph.gfb
# Run a filter query
lynxes query graph.gfb --filter "age > 25" --limit 10
API Overview
Top-level functions
| Function | Description |
|---|---|
lx.read_gf(path) |
Load a .gf text graph |
lx.read_gfb(path) |
Load a .gfb binary graph |
lx.read_parquet_graph(nodes, edges) |
Load from Parquet files |
lx.read_neo4j(uri, user, password) |
Connect to Neo4j |
lx.read_arangodb(...) |
Connect to ArangoDB |
lx.read_sparql(endpoint, ...) |
Connect to SPARQL endpoint |
lx.col(name) |
Create a column expression |
lx.count() / lx.sum(e) / lx.mean(e) |
Aggregation expressions |
lx.node(alias, label?) |
Pattern node descriptor |
lx.edge(type?) |
Pattern edge descriptor |
lx.partition_graph(g, n) |
Partition a GraphFrame |
GraphFrame methods
| Method | Returns |
|---|---|
.lazy() |
LazyGraphFrame |
.nodes() / .edges() |
NodeFrame / EdgeFrame |
.node_count() / .edge_count() |
int |
.subgraph(ids) / .subgraph_by_label(l) |
GraphFrame |
.pagerank(...) |
NodeFrame |
.shortest_path(src, dst) |
list[str] |
.connected_components() |
NodeFrame |
.betweenness_centrality() |
NodeFrame |
.community_detection() |
NodeFrame |
.partition(n, strategy) |
PartitionedGraph |
.write_gf(path) / .write_gfb(path) |
— |
.write_parquet_graph(nodes, edges) |
— |
LazyGraphFrame methods
| Method | Description |
|---|---|
.filter_nodes(expr) |
Keep nodes matching expression |
.filter_edges(expr) |
Keep edges matching expression |
.select_nodes(cols) / .select_edges(cols) |
Project columns |
.expand(type?, hops, direction) |
BFS graph traversal |
.aggregate_neighbors(type, agg) |
Aggregate over neighbor edges |
.match_pattern(steps, where_?) |
Cypher-like pattern matching |
.sort(by, descending) |
Sort result |
.limit(n) |
Cap result size |
.explain() |
Print logical plan |
.collect() |
Execute → GraphFrame |
.collect_nodes() |
Execute → NodeFrame |
.collect_edges() |
Execute → EdgeFrame |
Architecture
Lynxes is organized as a multi-crate Rust workspace with a thin Python layer on top:
py-lynxes/ ← Python package (maturin / PyO3)
src/lynxes/ ← lynxes Python namespace
tests/unit/ ← pytest integration tests
tests/benchmark/ ← NetworkX / igraph comparisons
crates/
lynxes/ ← Umbrella re-export crate
lynxes-core/ ← Arrow frames, CSR index, algorithms,
│ expression types, logical plan, optimizer
lynxes-plan/ ← Logical plan re-exports (thin)
lynxes-io/ ← File I/O (.gf parser, .gfb binary, Parquet)
lynxes-connect/ ← Remote connectors (Neo4j, ArangoDB,
│ SPARQL, Arrow Flight, GFConnector)
lynxes-lazy/ ← LazyGraphFrame + query executor
lynxes-python/ ← PyO3 binding crate (_lynxes.so)
lynxes-cli/ ← `lynxes` command-line tool
Execution Pipeline
Python call
│
▼
LazyGraphFrame (plan tree)
│
▼
Optimizer ──── PredicatePushdown
── ProjectionPushdown
── TraversalPruning
── SubgraphCaching
── EarlyTermination
│
▼
Executor ─────────────────────────────────────┐
│ │
▼ ▼
NodeFrame / EdgeFrame CSR Index (O(degree))
(Arrow RecordBatch) BFS / Traversal / Algorithms
Crate Dependency Graph
lynxes-python ──┐
lynxes-cli ──┤
├──► lynxes-lazy ──► lynxes-connect ──┐
│ ├──► lynxes-io ──┐
│ └──► lynxes-plan ─┤
│ ├──► lynxes-core
└───────────────────────────────────────────────────────►┘
Documentation Map
DESIGN.md— In-depth architectural design and engine principlesdocs/spec/— Feature and restructure specificationspy-lynxes/tests/benchmark/— Performance benchmarks vs NetworkX / igraph
Contributing
Please read DESIGN.md first. Core principles that are non-negotiable:
- Never wrap Polars —
NodeFrame/EdgeFrameown ArrowRecordBatchdirectly - CSR is mandatory —
EdgeFramealways holds a CSR index; no linear scan fallbacks - Lazy by default — All operations build a
LogicalPlan; execution only on.collect() - No optimization without measurement — Run
cargo benchbefore claiming speedups
Metadata
Release files for lynxes 1.3.12
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| lynxes-1.3.12.tar.gz | 251.3 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| lynxes-1.3.12-cp310-abi3-win_amd64.whl | CPython 3.10 | abi3 | Windows x86-64 | Details |
| lynxes-1.3.12-cp310-abi3-manylinux_2_28_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ x86-64 | Details |
| lynxes-1.3.12-cp310-abi3-manylinux_2_28_aarch64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ ARM64 | Details |
| lynxes-1.3.12-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
Total release size: 25.1 MB
Release files / lynxes-1.3.12.tar.gz
| Download URL | lynxes-1.3.12.tar.gz |
|---|---|
| Size | 251.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6f597ebadbaeebf8278fa864fae2451823e47be289a89955d09e639ade951091
|
|
BLAKE2b-256 checksum How to use checksums |
6ecd924014e613f346ee3e4ef5978977fef34ce0eb35a9d98a2ef472716dd03d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency logRelease files / lynxes-1.3.12-cp310-abi3-win_amd64.whl
| Download URL | lynxes-1.3.12-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 5.9 MB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
89a175d52f4ed970c7bf5b83bf39ceac6b329723ad4a3901b2a701d813843969
|
|
BLAKE2b-256 checksum How to use checksums |
bd77503e017c9146fb68296450c51d3a32711bdb10fd1147e7f784c5d489b456
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency logRelease files / lynxes-1.3.12-cp310-abi3-manylinux_2_28_x86_64.whl
| Download URL | lynxes-1.3.12-cp310-abi3-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 6.7 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
d75fb42c9c0cfdb8c7e50b0156fc90b88de8517816128448f955db9e180899b2
|
|
BLAKE2b-256 checksum How to use checksums |
157822214177bad3f2df8f648c2a94d41846f0a2e940e62ffe66f18a495f101e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency logRelease files / lynxes-1.3.12-cp310-abi3-manylinux_2_28_aarch64.whl
| Download URL | lynxes-1.3.12-cp310-abi3-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 6.5 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
a95bc9d02eb8341b71270eee0ce36eea4916aeab92d22025811c9455fb058cf9
|
|
BLAKE2b-256 checksum How to use checksums |
abdb121799e00027b62655db1f57f0882b64e3bc9d117a1210d2088d3955f9f1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency logRelease files / lynxes-1.3.12-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | lynxes-1.3.12-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 5.8 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
0bce07521050d15d3ef3ff8bd294a7a6d2ebd5f28f19d8216cb51539cede879b
|
|
BLAKE2b-256 checksum How to use checksums |
04bae36d0934d93808275f0bfc51e27d42597c7af73f3f6173a686ff1fc1805f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 15, 2026.
Transparency log