Ctrl K
Memgraph — Northwind Benchmark Report
Run: 2026-10-09T09:32:41.855101-07:00 → 2026-10-09T09:33:09.733667-07:00Endpoint: bolt://localhost:17689 (database memgraph)
Workload
- Categories: 96 | Suppliers: 144 | Customers: 1,200
- Products seeded: 48,000
- Orders seeded: 48,000 (1..6 lines each)
- Random seed:
42(deterministic dataset) - Seed nodes: 97,440
- Seed relationships: 312,050
- Approx. seed payload (JSON-serialized): 35.4 MiB
- Seed duration: 1,603.15 ms
- Wipe duration: 5.33 ms
- Index setup duration: 7.24 ms
- Ingestion duration (row generation and writes): 1,590.56 ms
- Ingestion nodes/sec: 61,261.48
- Ingestion relationships/sec: 196,188.89
- Seed batch size: 500 rows
- Seed parallelism: 4 sessions per phase
- Query workloads: 14
- Iterations per query: 30
- Warmup iterations per query: 5
Query Latency
| Query | Description | Samples | Mean (ms) | Median (ms) | P95 (ms) | P99 (ms) | Min (ms) | Max (ms) | StdDev (ms) | Ops/sec |
|---|---|---|---|---|---|---|---|---|---|---|
products_per_category | Product counts grouped by category, with a full result sort. | 30 | 9.94 | 9.86 | 10.91 | 11.23 | 9.45 | 11.34 | 0.45 | 99.76 |
customer_category_distinct_orders | Four-hop customer-to-category traversal with distinct-order aggregation. | 30 | 226.41 | 225.71 | 234.03 | 238.78 | 220.45 | 239.81 | 4.08 | 4.42 |
optional_match_orders_count | Optional product-to-order traversal with zero-match preservation and top-100 sorting. | 30 | 88.75 | 87.72 | 91.99 | 103.10 | 85.67 | 107.21 | 3.90 | 11.26 |
revenue_by_product | Relationship-property arithmetic and revenue aggregation grouped by product. | 30 | 80.61 | 80.42 | 83.02 | 83.50 | 79.19 | 83.62 | 1.03 | 12.40 |
products_by_supplier | Supplier-to-product traversal with top-N aggregation and deterministic ties. | 30 | 8.80 | 8.75 | 9.12 | 9.16 | 8.51 | 9.18 | 0.19 | 113.24 |
orders_by_customer | Customer-to-order traversal grouped into a top-25 order-count ranking. | 30 | 9.66 | 9.66 | 10.04 | 10.09 | 9.21 | 10.10 | 0.23 | 103.22 |
revenue_by_category | Three-hop category revenue aggregation from order-line quantities and product prices. | 30 | 71.88 | 71.44 | 74.75 | 77.18 | 69.36 | 78.04 | 1.79 | 13.89 |
revenue_by_supplier | Supplier-to-product-to-order traversal with revenue aggregation and top-25 sorting. | 30 | 72.60 | 71.52 | 79.81 | 81.71 | 69.28 | 81.82 | 3.06 | 13.77 |
revenue_by_customer | Customer-order-product traversal with relationship-property revenue aggregation. | 30 | 99.63 | 102.97 | 108.72 | 110.04 | 82.42 | 110.31 | 8.45 | 10.03 |
order_line_sales_by_country | Order-line scan grouped by shipping country with line-count and unit aggregation. | 30 | 41.53 | 41.35 | 42.88 | 43.05 | 40.23 | 43.06 | 0.80 | 24.06 |
low_stock_products | Selective numeric property filter followed by a stable top-100 product sort. | 30 | 8.79 | 8.75 | 9.10 | 9.15 | 8.55 | 9.16 | 0.18 | 112.30 |
products_in_category | Selective category lookup and adjacent product traversal with a top-100 result. | 30 | 0.85 | 0.87 | 0.96 | 0.98 | 0.70 | 0.99 | 0.08 | 1,034.43 |
order_line_quantity_distribution | Full relationship-property scan grouped by line quantity. | 30 | 25.35 | 23.62 | 36.95 | 38.69 | 22.22 | 39.00 | 4.51 | 39.41 |
customer_order_details | Selective customer lookup followed by order-line expansion and computed row projection. | 30 | 0.65 | 0.62 | 0.98 | 1.11 | 0.45 | 1.11 | 0.17 | 1,326.59 |
- Overall mean latency: 53.25 ms
- Measured query operations: 420
- End-to-end query-loop throughput: 16.02 ops/sec
- Query-latency-only aggregate throughput: 18.78 ops/sec
- Query-loop duration: 26.220 s
- Query-loop duration includes warmups and per-query setup; only measured iterations count toward the end-to-end rate.
- Full lifecycle wall-clock (sampled): 30.389 s
Correctness
Seed counts (from the database's own count(...) queries):
| Entity | Count |
|---|---|
| Category | 96 |
| Supplier | 144 |
| Customer | 1,200 |
| Product | 48,000 |
| Order | 48,000 |
| PART_OF edges | 48,000 |
| SUPPLIES edges | 48,000 |
| PURCHASED edges | 48,000 |
| ORDERS edges | 168,050 |
Per-query result fingerprints (SHA-256 over canonicalised rows):
| Query | Rows | Hash | Stable across iterations |
|---|---|---|---|
products_per_category | 96 | 91e9f1f063680a6d… | Yes |
customer_category_distinct_orders | 10 | 5da36214d5163220… | Yes |
optional_match_orders_count | 100 | 8950fcdaab16eaeb… | Yes |
revenue_by_product | 10 | 60b64c678f4c01fd… | Yes |
products_by_supplier | 25 | af1e9b5d1d663a02… | Yes |
orders_by_customer | 25 | ecff10cfcfa9cc34… | Yes |
revenue_by_category | 96 | 23ba39858bf74ace… | Yes |
revenue_by_supplier | 25 | 41900ee05a8f994a… | Yes |
revenue_by_customer | 25 | 639a286559282c97… | Yes |
order_line_sales_by_country | 15 | a86030b2ba5eede9… | Yes |
low_stock_products | 100 | a8f2f994d920e6d8… | Yes |
products_in_category | 100 | e207262bf51ed857… | Yes |
order_line_quantity_distribution | 25 | e239e5f47878c862… | Yes |
customer_order_details | 100 | 9d6ef178ee445057… | Yes |
No intra-run correctness errors.
Power Consumption
- Samples collected: 29 (~1s each)
- Sampled duration: 29.94 s
- Avg CPU power: 7,462.7 mW
- Avg GPU power: 28.1 mW
- Avg package power: 7,490.8 mW
- Estimated energy (benchmark window): 224.25 J
Memory Pressure
- Samples collected: 33 (~1s each)
- Avg used (active + wired + compressor): 22.8 GiB
- Peak used: 24.0 GiB
- Avg free: 8.2 GiB
- Min free: 6.7 GiB
- Avg compressed (logical): 7.2 GiB
- Peak compressed: 7.2 GiB
Storage
- Raw data files: 388.4 MiB (407,228,416 bytes)
- Indexes/stats: 0 B (0 bytes)
- Write-ahead logs: 86.8 MiB (91,017,216 bytes)
- Metadata/bookkeeping: 0 B (0 bytes)
- Preallocated scratch (excluded): 57.6 MiB (60,399,616 bytes)
- Unclassified (other): 0 B (0 bytes)
- Full data directory
du: 532.8 MiB (558,645,248 bytes) - Classified sum: 532.8 MiB (558,645,248 bytes, Δ vs du = +0 bytes)
Raw-data size is the comparison headline. Preallocated memtable/WAL scratch files (8 MiB memtable on Badger, 1 MiB GC discard log, etc.) are excluded because they hold the same bytes regardless of dataset size.
Top raw-data files
| File | Size |
|---|---|
settings/000004.log | 70.4 MiB |
databases/.durability/000004.log | 70.4 MiB |
auth/000004.log | 70.4 MiB |
.system/000004.log | 70.4 MiB |
telemetry/000004.log | 70.4 MiB |
settings/MANIFEST-000005 | 4.0 MiB |
databases/.durability/MANIFEST-000005 | 4.0 MiB |
auth/MANIFEST-000005 | 4.0 MiB |
triggers/MANIFEST-000005 | 4.0 MiB |
streams/MANIFEST-000005 | 4.0 MiB |
Queries
products_per_category
cypher
MATCH (c:Category)<-[:PART_OF]-(p:Product)
RETURN c.categoryName AS categoryName, count(p) AS productCount
ORDER BY productCount DESCcustomer_category_distinct_orders
cypher
MATCH (c:Customer)-[:PURCHASED]->(o:Order)-[:ORDERS]->(p:Product)-[:PART_OF]->(cat:Category)
RETURN c.companyName AS companyName, cat.categoryName AS categoryName, count(DISTINCT o) AS orders
ORDER BY orders DESC, companyName ASC, categoryName ASC
LIMIT 10optional_match_orders_count
cypher
MATCH (p:Product)
OPTIONAL MATCH (p)<-[r:ORDERS]-(o:Order)
RETURN p.productName AS productName, count(o) AS orderCount
ORDER BY orderCount DESC, productName ASC
LIMIT 100revenue_by_product
cypher
MATCH (p:Product)<-[r:ORDERS]-(:Order)
WITH p, sum(p.unitPrice * r.quantity) AS revenue
RETURN p.productName AS productName, revenue
ORDER BY revenue DESC, productName ASC
LIMIT 10products_by_supplier
cypher
MATCH (s:Supplier)-[:SUPPLIES]->(p:Product)
RETURN s.companyName AS supplier, count(p) AS products
ORDER BY products DESC, supplier ASC
LIMIT 25orders_by_customer
cypher
MATCH (c:Customer)-[:PURCHASED]->(o:Order)
RETURN c.companyName AS customer, count(o) AS orders
ORDER BY orders DESC, customer ASC
LIMIT 25revenue_by_category
cypher
MATCH (c:Category)<-[:PART_OF]-(p:Product)<-[r:ORDERS]-(:Order)
RETURN c.categoryName AS category, sum(p.unitPrice * r.quantity) AS revenue
ORDER BY revenue DESC, category ASCrevenue_by_supplier
cypher
MATCH (s:Supplier)-[:SUPPLIES]->(p:Product)<-[r:ORDERS]-(:Order)
RETURN s.companyName AS supplier, sum(p.unitPrice * r.quantity) AS revenue
ORDER BY revenue DESC, supplier ASC
LIMIT 25revenue_by_customer
cypher
MATCH (c:Customer)-[:PURCHASED]->(:Order)-[r:ORDERS]->(p:Product)
RETURN c.companyName AS customer, sum(p.unitPrice * r.quantity) AS revenue
ORDER BY revenue DESC, customer ASC
LIMIT 25order_line_sales_by_country
cypher
MATCH (o:Order)-[r:ORDERS]->(:Product)
RETURN o.shipCountry AS country, count(r) AS orderLines, sum(r.quantity) AS units
ORDER BY orderLines DESC, country ASClow_stock_products
cypher
MATCH (p:Product)
WHERE p.unitsInStock < 25
RETURN p.productName AS product, p.unitsInStock AS unitsInStock, p.unitPrice AS unitPrice
ORDER BY unitsInStock ASC, product ASC
LIMIT 100products_in_category
cypher
MATCH (c:Category {categoryID: 7})<-[:PART_OF]-(p:Product)
RETURN p.productName AS product, p.unitPrice AS unitPrice, p.unitsInStock AS unitsInStock
ORDER BY product ASC
LIMIT 100order_line_quantity_distribution
cypher
MATCH ()-[r:ORDERS]->()
RETURN r.quantity AS quantity, count(r) AS lineCount
ORDER BY quantity ASCcustomer_order_details
cypher
MATCH (c:Customer {customerID: 42})-[:PURCHASED]->(o:Order)-[r:ORDERS]->(p:Product)
RETURN o.orderID AS orderID, p.productName AS product, r.quantity AS quantity,
p.unitPrice * r.quantity AS extendedPrice
ORDER BY orderID ASC, product ASC
LIMIT 100