A blazingly fast, lightweight RDF quad store for .NET 10 — minimal dependencies, pure performance.
✨ Sub-microsecond queries — Indexed lookups in <200ns (faster than most in-memory operations)
🎯 Batch load 1M triples in 3.65 seconds — 274K triples/sec throughput
📦 Lightweight — TriG loading without need for external RDF libraries
🔍 SPARQL support — Full graph pattern matching and variable binding
✅ Well tested — 200+ passing tests, W3C TriG compliance
QuadStore is the core in-memory quad store.
QuadStoreStorageProvider adapts it to the standard dotNetRDF storage interfaces.
That means Leviathan can run SPARQL queries against your QuadStore data.
usingTripleStore.Core;usingVDS.RDF.Query;usingVDS.RDF.Storage;// 1) Define a tiny in-memory TriG document with two FOAF name triples.conststringtrigContent="""@prefix foaf: <http://xmlns.com/foaf/0.1/> .{ <http://example.org/alice> foaf:name "Alice" . <http://example.org/bob> foaf:name "Bob" .}""";// 2) Persist the TriG content to disk so the loader can read it from a file.vardataFilePath=Path.Combine(AppContext.BaseDirectory,"data.trig");File.WriteAllText(dataFilePath,trigContent);// 3) Create/open the QuadStore data directory.varstorePath=Path.Combine(AppContext.BaseDirectory,"store-data");usingvarstore=newQuadStore(storePath);// 4) Load TriG quads directly into QuadStore in a single pass.varloader=newSinglePassTrigLoader(store);loader.LoadFromFile(dataFilePath);// 5) Wrap QuadStore with the dotNetRDF storage adapter so Leviathan can query it.IStorageProviderprovider=newQuadStoreStorageProvider(store);varqueryable=(IQueryableStorage)provider;// 6) Run a SPARQL SELECT query through Leviathan.varquery=@"SELECT ?person ?nameWHERE { ?person <http://xmlns.com/foaf/0.1/name> ?name .}";varresults=(SparqlResultSet)queryable.Query(query);// 7) Print the SPARQL result rows.Console.WriteLine("Leviathan query results:");foreach(varrowinresults){Console.WriteLine($"{row["person"]} -> {row["name"]}");}This example exposes a simple /sparql endpoint that accepts a SPARQL query and returns:
- SPARQL JSON results for
SELECT/ASK - Turtle for
CONSTRUCT/DESCRIBE
usingTripleStore.Core;usingVDS.RDF;usingVDS.RDF.Query;usingVDS.RDF.Storage;usingVDS.RDF.Writing;vardataDir=args.Length>0?args[0]:"./quadstore-data";varqs=newQuadStore(dataDir);varprovider=newQuadStoreStorageProvider(qs);varqueryable=(IQueryableStorage)provider;// ---------------------------------------------------------------------------// Section B: Seed Data// ---------------------------------------------------------------------------// On first run (empty store), load a small set of FOAF triples so the sample// can be queried immediately without manual data loading.if(!qs.Query().Any()){varseedTriG=""" @prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix ex: <http://example.org/> . { ex:alice foaf:name "Alice" ; foaf:knows ex:bob . ex:bob foaf:name "Bob" ; foaf:knows ex:alice . } """;varloader=newSinglePassTrigLoader(qs);loader.LoadFromString(seedTriG);qs.SaveAll();}// ---------------------------------------------------------------------------// Section C: Host Configuration// ---------------------------------------------------------------------------// Build the ASP.NET Core minimal API host and register QuadStore and its// storage provider as singletons so they are available to the request pipeline.varbuilder=WebApplication.CreateBuilder(args);builder.Services.AddSingleton(qs);builder.Services.AddSingleton(provider);builder.Services.AddSingleton<IQueryableStorage>(provider);varapp=builder.Build();app.MapSparqlEndpoints();// ---------------------------------------------------------------------------// Section G: Shutdown// ---------------------------------------------------------------------------// Dispose the QuadStore when the application is stopping to release// memory-mapped file handles cleanly.app.Lifetime.ApplicationStopping.Register(()=>{qs.Dispose();});app.Run();QuadStore + QuadStoreStorageProvider is intentionally append-only currently:
- ❌ No graph deletion (
DeleteGraphis not supported) - ❌ No triple removal in
UpdateGraph(additions only) - ❌ No SPARQL Update (
IUpdateableStorage.Updatethrows) - ℹ️ Per-query in-memory snapshot for Leviathan queries (simple and correct, but can be slower on very large datasets)
| Operation | 10K Triples | 100K Triples | 1M Triples |
|---|---|---|---|
| Subject lookup | <200ns | <200ns | <200ns |
| Predicate query | 36µs | 536µs | 4.4ms |
| Object lookup | <200ns | <200ns | <200ns |
| Graph filter | 138µs | 1.9ms | 17.6ms |
| Multiple patterns | 1.6µs | 21µs | 285µs |
| Full enumeration | 852µs | 7.9ms | 80.3ms |
| Dataset | Time | Throughput |
|---|---|---|
| 10K triples | 370ms | 27K/sec |
| 100K triples | 299ms | 335K/sec |
| 1M triples | 3.65s | 274K/sec |
Benchmarks on Intel Core Ultra 7 265H, .NET 10.0. See detailed benchmark analysis for all metrics.
QuadStore is built for .NET 10.0 and ships as a library. Add it to your project:
# If published to NuGet (coming soon)
dotnet add package QuadStore.CoreFor now, clone and reference locally:
git clone https://github.com/aabs/QuadStore.git
# Add project reference in your .csproj:# <ProjectReference Include="path/to/src/TripleStore.Core/TripleStore.Core.csproj" />QuadStore maintains roaring bitmap indexes for fast intersection:
- Subject index → O(1) lookup by URI
- Predicate index → O(1) lookup by property
- Object index → O(1) lookup by resource
- Graph index → O(1) lookup by named graph
Multi-dimensional queries use two-pointer intersection over sorted result sets, keeping complex queries sub-millisecond even at scale.
- API Reference — Explore core types and methods
- Benchmark Report — See performance analysis in detail
- Test Suite — Working examples of every operation
- TriG Spec — Supported data format
# Build
dotnet build -c Release
# Run all tests
dotnet test -c Release --nologo
# Run benchmarks
dotnet run -c Release --project benchmark/TripleStore.Benchmarks/TripleStore.Benchmarks.csprojHave ideas? Found a bug? Jump in!
- 🐛 Open an issue for bugs or feature requests
- 💬 Start a discussion to share ideas
- 🔀 PRs welcome — see DEVELOPMENT.md for setup
All contributions welcome, from bug reports to performance improvements.
MIT — Use freely in commercial and personal projects.
Made with ⚡ for .NET developers who demand performance.