SPARQL compatibility
Fluree implements SPARQL 1.1. Existing SPARQL queries from Stardog or GraphDB work without modification.
Supported: all query forms (SELECT, CONSTRUCT, ASK, DESCRIBE), all graph patterns (FILTER, OPTIONAL, UNION, MINUS, EXISTS, BIND, VALUES), property paths (+, *, ^, |, /), aggregations with DISTINCT, subqueries, SPARQL UPDATE (INSERT DATA, DELETE DATA, DELETE/INSERT WHERE, MODIFY with WITH/USING/USING NAMED), named graphs (FROM, FROM NAMED, GRAPH), OWL/RDFS reasoning, and SHACL validation.
curl -X POST http://localhost:8090/v1/fluree/query \
-H "Content-Type: application/sparql-query" \
-d '
PREFIX schema: <http://schema.org/>
SELECT ?name ?email
FROM <mydb:main>
WHERE {
?person a schema:Person ;
schema:name ?name ;
schema:email ?email .
}
'
Migration path
Export data
From Stardog:
stardog data export -f TURTLE mydb > export.ttl
From GraphDB: Export via GraphDB Workbench (Explore → Export) as Turtle, or use CONSTRUCT:
CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }
Start Fluree and load data
# Start
docker run -d --name fluree \
-p 8090:8090 \
-v fluree-data:/data \
-e FLUREE_STORAGE_PATH=/data \
-e FLUREE_INDEXING_ENABLED=true \
fluree/fluree-server:latest
# Create ledger
curl -X POST http://localhost:8090/v1/fluree/create \
-H "Content-Type: application/json" \
-d '{"ledger": "mydb:main"}'
# Load data
curl -X POST "http://localhost:8090/v1/fluree/upsert?ledger=mydb:main" \
-H "Content-Type: text/turtle" \
--data-binary '@export.ttl'
Adapt queries
One change needed: add FROM <mydb:main> to specify the ledger, or use the ledger-scoped endpoint POST /v1/fluree/query/mydb:main.
What Fluree does that Stardog and GraphDB don't
Branching
Create isolated branches, work independently, rebase:
fluree branch create staging --ledger mydb
curl -X POST "http://localhost:8090/v1/fluree/insert?ledger=mydb:staging" \
-H "Content-Type: application/json" \
-d '{"@context": {"ex": "http://example.org/"}, "@graph": [{"@id": "ex:test", "ex:status": "staging"}]}'
fluree branch rebase staging --strategy take-both
Conflict resolution at the (subject, predicate, graph) tuple level. Strategies: take-both, take-source, take-branch, abort, skip.
Neither Stardog nor GraphDB has branching.
Time travel
Every transaction is immutable and timestamped. Query any historical state:
SELECT ?name FROM <mydb:main@t:500> WHERE { ?p schema:name ?name }
SELECT ?name FROM <mydb:main@iso:2024-01-15T10:30:00Z> WHERE { ?p schema:name ?name }
SELECT ?name FROM <mydb:main@commit:bafybeig...> WHERE { ?p schema:name ?name }
Track changes with RDF-star history queries:
PREFIX f: <https://ns.flur.ee/db#>
SELECT ?status ?t ?op
FROM <mydb:main@t:1>
TO <mydb:main@t:latest>
WHERE {
<< ex:order-123 ex:status ?status >> f:t ?t .
<< ex:order-123 ex:status ?status >> f:op ?op .
}
ORDER BY ?t
Returns every assertion and retraction with the exact transaction time.
Neither Stardog nor GraphDB supports time travel. Updates overwrite previous state.
Vector search
Native similarity search on @vector typed values — inline functions (cosineSimilarity, dotProduct, euclideanDistance) and HNSW indexes (embedded usearch):
{
"@context": {"ex": "http://example.org/", "f": "https://ns.flur.ee/db#"},
"select": ["?doc", "?title", "?score"],
"values": [["?queryVec"], [{"@value": [0.9, 0.1, 0.05], "@type": "f:embeddingVector"}]],
"where": [
{"@id": "?doc", "@type": "ex:Article", "ex:title": "?title", "ex:embedding": "?vec"},
["bind", "?score", "(cosineSimilarity ?vec ?queryVec)"],
["filter", "(> ?score 0.5)"]
],
"orderBy": [["desc", "?score"]],
"limit": 10
}
Vectors stored as f32 arrays with SIMD-accelerated computation. HNSW runs embedded in-process or via fluree-search-httpd.
Stardog has vector search via an external service. GraphDB has distributional similarity (not vector search).
Iceberg integration
Query Parquet tables as graph sources:
# Direct S3 (no catalog server)
fluree iceberg map warehouse-orders \
--mode direct \
--table-location s3://bucket/warehouse/orders \
--s3-region us-east-1
# REST catalog (e.g., Apache Polaris)
fluree iceberg map warehouse-orders \
--catalog-uri https://polaris.example.com/api/catalog \
--table sales.orders \
--auth-bearer $POLARIS_TOKEN
Join graph data with data lake data:
SELECT ?customerName ?orderTotal
FROM <customers:main>
WHERE {
?customer schema:name ?customerName .
GRAPH <warehouse-orders:main> {
?order ex:customer ?customer .
?order ex:total ?orderTotal .
}
}
Filters push down to Iceberg for partition pruning and column projection. R2RML mappings transform rows to RDF.
Stardog has virtual graphs for SQL databases. GraphDB has OntoRefine. Neither has native Iceberg/Parquet integration.
Content-addressed storage
Every commit has a CID. W3C Verifiable Credentials and DID support for transaction signing.
Triple-level access control
Access policies evaluated at query time on individual triples — not named-graph-level (Stardog) or statement-level with manual configuration (GraphDB).
Feature comparison
| Capability | Fluree | Stardog | GraphDB |
|---|---|---|---|
| SPARQL 1.1 | Full | Full | Full |
| Time travel | By t, ISO, commit hash | No | No |
| Branch / merge | Yes, with conflict resolution | No | No |
| Content-addressed storage | CID per commit | No | No |
| HNSW vector search | Built-in (embedded or remote) | Via external service | No |
| BM25 full-text search | Built-in | Built-in | Lucene integration |
| Triple-level access control | Yes | Named-graph level | Statement-level |
| Iceberg/Parquet | Native graph source | No | No |
| OWL/RDFS reasoning | Yes | Yes | Yes |
| SHACL validation | Yes | Yes | Yes |
| Virtual graphs (SQL) | R2RML | Virtual graphs | OntoRefine |
| Encryption at rest | AES-256-GCM | Yes | No |
| GeoSPARQL | S2 spatial indexing | Yes | Yes |
| Embeddable (library mode) | Yes (Rust) | No | No |
| Verifiable Credentials / DID | W3C | No | No |
| Runtime | Rust (native binary) | Java | Java |
Performance reference
SPARQLoscope DBLP evaluation (105 queries). Stardog is not in the published evaluation; GraphDB is:
| Engine | Geo Mean | Arith Mean | Failed Queries |
|---|---|---|---|
| Fluree | 0.28s | 0.95s | 0% |
| GraphDB | 5.80s | 26.23s | 0% |
Full results and methodology in the benchmark report.