FlureeLabs
GuideMarch 30, 2026

Coming from Stardog / GraphDB

How to move from Stardog or GraphDB to Fluree. Covers what's compatible, what differs, and what Fluree has that they don't.

MigrationStardogGraphDB

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.

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

CapabilityFlureeStardogGraphDB
SPARQL 1.1FullFullFull
Time travelBy t, ISO, commit hashNoNo
Branch / mergeYes, with conflict resolutionNoNo
Content-addressed storageCID per commitNoNo
HNSW vector searchBuilt-in (embedded or remote)Via external serviceNo
BM25 full-text searchBuilt-inBuilt-inLucene integration
Triple-level access controlYesNamed-graph levelStatement-level
Iceberg/ParquetNative graph sourceNoNo
OWL/RDFS reasoningYesYesYes
SHACL validationYesYesYes
Virtual graphs (SQL)R2RMLVirtual graphsOntoRefine
Encryption at restAES-256-GCMYesNo
GeoSPARQLS2 spatial indexingYesYes
Embeddable (library mode)Yes (Rust)NoNo
Verifiable Credentials / DIDW3CNoNo
RuntimeRust (native binary)JavaJava

Performance reference

SPARQLoscope DBLP evaluation (105 queries). Stardog is not in the published evaluation; GraphDB is:

EngineGeo MeanArith MeanFailed Queries
Fluree0.28s0.95s0%
GraphDB5.80s26.23s0%

Full results and methodology in the benchmark report.