vs HelixDB
LoraDB vs HelixDB
LoraDB is 57.2× faster overall. HelixDB is an graph-vector database (enterprise-dev image). Numbers from the same suite as the overview — identical fixtures, identical seed, identical iteration count.
Overall
LoraDB sets the row; HelixDB sits at 57.2× slower.
Geometric-mean slowdown across every workload both engines run. Empty rows happen when the language can’t express the workload — they’re called out below, not hidden.
Per group
Wins by group.
For each group, the workload count, who wins it, and how the per-row tally breaks down between LoraDB, HelixDB, and any third engine that took a row.
- setup1 workload · winner GrafeoLoraDB2.70× slowerHelixDB1247× slowerRows · 10·0·1
- writes7 workloads · winner GrafeoLoraDB0.61× slowerHelixDB125× slowerRows · 73·0·4
- scans4 workloads · winner LoraDBLoraDBfastestHelixDB287× slowerRows · 44·0
- predicates12 workloads · winner LoraDBLoraDBfastestHelixDB20.9× slowerRows · 128·0·4
- numerics2 workloads · winner KuzuLoraDB1.08× slowerHelixDB20.4× slowerRows · 20·0·2
- aggregates4 workloads · winner LoraDBLoraDBfastestHelixDB35.5× slowerRows · 44·0
- pipeline4 workloads · winner LoraDBLoraDBfastestHelixDB17.2× slowerRows · 42·0·2
- lists1 workload · winner LoraDBLoraDBfastestHelixDB15.0× slowerRows · 10·0·1
- sort3 workloads · winner LoraDBLoraDBfastestHelixDB16.4× slowerRows · 33·0
- traversals11 workloads · winner LoraDBLoraDBfastestHelixDB133× slowerRows · 1111·0
- patterns3 workloads · winner LoraDBLoraDBfastestHelixDB22.2× slowerRows · 33·0
Per workload
Raw timings, workload by workload.
Two columns — LoraDB and HelixDB — across every workload they share. Rows with no comparable HelixDBrun are hidden here; they’re listed in the omissions block at the bottom.
setup(1)
WinnerGrafeo| Workload | Size | LoraDB | HelixDB | Winner |
|---|---|---|---|---|
| construct_empty | — | 4.06 µs2.70× slower | 1.87 ms1247× slower | Grafeo |
writes(7)
WinnerGrafeo| Workload | Size | LoraDB | HelixDB | Winner |
|---|---|---|---|---|
| bulk_edges | 200 | 606.63 µsfastest | 309.68 ms510× slower | LoraDB |
| bulk_set_match | 1000 | 552.39 µs1.84× slower | 3.57 ms11.9× slower | Kuzu |
| delete_node | 1000 | 355.70 µs1.47× slower | 151.74 ms629× slower | Grafeo |
| set_multiple_props | 1000 | 21.15 µsfastest | 2.37 ms112× slower | LoraDB |
| update_set | 1000 | 18.01 µsfastest | 2.91 ms162× slower | LoraDB |
| write_bulk | 1000 | 1.46 ms1.93× slower | 771.22 ms1020× slower | Grafeo |
| write_single | 1000 | 14.90 µs2.20× slower | 153.86 ms22704× slower | Grafeo |
scans(4)
WinnerLoraDB| Workload | Size | LoraDB | HelixDB | Winner |
|---|---|---|---|---|
| lookup_by_id | 1000 | 716.64 nsfastest | 2.30 ms3205× slower | LoraDB |
| lookup_by_id_indexed | 1000 | 684.00 nsfastest | 2.62 ms3831× slower | LoraDB |
| scan_filtered | 1000 | 149.08 µsfastest | 3.82 ms25.6× slower | LoraDB |
| scan_label | 1000 | 124.96 µsfastest | 2.70 ms21.6× slower | LoraDB |
predicates(12)
WinnerLoraDB| Workload | Size | LoraDB | HelixDB | Winner |
|---|---|---|---|---|
| where_compound_and_or | 1000 | 213.07 µsfastest | 3.23 ms15.2× slower | LoraDB |
| where_contains | 1000 | 145.04 µsfastest | 3.02 ms20.8× slower | LoraDB |
| where_ends_with | 1000 | 143.60 µsfastest | 2.99 ms20.8× slower | LoraDB |
| where_id_in_range | 1000 | 142.71 µs2.02× slower | 3.13 ms44.3× slower | Grafeo |
| where_in_list | 1000 | 162.42 µsfastest | 2.92 ms18.0× slower | LoraDB |
| where_modulo_eq | 1000 | 127.32 µsfastest | 3.01 ms23.7× slower | LoraDB |
| where_not | 1000 | 166.05 µs1.01× slower | 4.64 ms28.3× slower | Kuzu |
| where_or | 1000 | 147.16 µsfastest | 3.29 ms22.3× slower | LoraDB |
| where_starts_with | 1000 | 146.91 µsfastest | 3.29 ms22.4× slower | LoraDB |
| where_string_gte | 1000 | 180.97 µs1.07× slower | 4.11 ms24.4× slower | Kuzu |
| where_subexpr | 1000 | 227.59 µs1.69× slower | 4.73 ms35.1× slower | SurrealDB |
| where_two_props | 1000 | 152.69 µsfastest | 2.56 ms16.8× slower | LoraDB |
numerics(2)
WinnerKuzu| Workload | Size | LoraDB | HelixDB | Winner |
|---|---|---|---|---|
| numeric_modulo | 1000 | 144.95 µs1.02× slower | 2.97 ms20.8× slower | Kuzu |
| numeric_pow | 1000 | 166.22 µs1.16× slower | 2.87 ms20.0× slower | Kuzu |
aggregates(4)
WinnerLoraDB| Workload | Size | LoraDB | HelixDB | Winner |
|---|---|---|---|---|
| aggregate_avg | 1000 | 81.43 µsfastest | 3.20 ms39.3× slower | LoraDB |
| aggregate_max | 1000 | 79.97 µsfastest | 2.86 ms35.7× slower | LoraDB |
| aggregate_min | 1000 | 79.67 µsfastest | 2.49 ms31.3× slower | LoraDB |
| aggregate_sum | 1000 | 78.09 µsfastest | 2.82 ms36.1× slower | LoraDB |
pipeline(4)
WinnerLoraDB| Workload | Size | LoraDB | HelixDB | Winner |
|---|---|---|---|---|
| case_when | 1000 | 173.33 µsfastest | 2.78 ms16.1× slower | LoraDB |
| coalesce_existing | 1000 | 161.92 µsfastest | 3.32 ms20.5× slower | LoraDB |
| computed_in_return | 1000 | 151.15 µs1.07× slower | 2.99 ms21.2× slower | Kuzu |
| with_two_chained | 1000 | 313.64 µs1.41× slower | 4.25 ms19.1× slower | Kuzu |
lists(1)
WinnerLoraDB| Workload | Size | LoraDB | HelixDB | Winner |
|---|---|---|---|---|
| list_in_construction | 1000 | 177.94 µs1.05× slower | 2.67 ms15.8× slower | Kuzu |
sort(3)
WinnerLoraDB| Workload | Size | LoraDB | HelixDB | Winner |
|---|---|---|---|---|
| order_by_id_asc | 1000 | 167.95 µsfastest | 3.20 ms19.1× slower | LoraDB |
| order_by_multi_key | 1000 | 211.99 µsfastest | 2.80 ms13.2× slower | LoraDB |
| skip_limit | 1000 | 162.19 µsfastest | 2.87 ms17.7× slower | LoraDB |
traversals(11)
WinnerLoraDB| Workload | Size | LoraDB | HelixDB | Winner |
|---|---|---|---|---|
| direct_record_traversal | 500 | 831.70 nsfastest | 1.55 ms1861× slower | LoraDB |
| recursive_depth2 | 500 | 968.69 nsfastest | 1.69 ms1742× slower | LoraDB |
| recursive_depth3 | 500 | 1.04 µsfastest | 1.46 ms1402× slower | LoraDB |
| recursive_depth5 | 500 | 1.16 µsfastest | 1.65 ms1425× slower | LoraDB |
| relation_filter | 500 | 117.78 µsfastest | 2.50 ms21.2× slower | LoraDB |
| traversal_filter_one_hop | 500 | 138.99 µsfastest | 3.15 ms22.7× slower | LoraDB |
| traversal_one_hop | 500 | 125.98 µsfastest | 2.59 ms20.5× slower | LoraDB |
| traversal_reverse | 500 | 123.67 µsfastest | 2.62 ms21.2× slower | LoraDB |
| traversal_three_hop | 500 | 236.10 µsfastest | 5.16 ms21.9× slower | LoraDB |
| traversal_two_hop | 500 | 165.58 µsfastest | 64.61 ms390× slower | LoraDB |
| traversal_undirected | 500 | 213.41 µsfastest | 4.20 ms19.7× slower | LoraDB |
patterns(3)
WinnerLoraDB| Workload | Size | LoraDB | HelixDB | Winner |
|---|---|---|---|---|
| edge_subquery_clause | 500 | 213.55 µsfastest | 4.12 ms19.3× slower | LoraDB |
| star_fanout | 1000 | 138.96 µsfastest | 2.75 ms19.8× slower | LoraDB |
| star_fanout_filter | 1000 | 112.53 µsfastest | 3.24 ms28.8× slower | LoraDB |
Honest omissions
Workloads HelixDB couldn’t run like-for-like.
Workloads omitted only where the engine has no like-for-like equivalent — a missing scalar function, a different MERGE semantics, a reserved word. The reason is recorded with the workload, not silently dropped.
merge_existingHelixDB- HelixDB has no MERGE/upsert; emulating it needs conditional var_as_if branching.
merge_createHelixDB- HelixDB has no MERGE/upsert (see merge_existing).
distinctHelixDB- HelixDB's dedup is node-level; there is no SELECT DISTINCT <property>.
string_to_upperHelixDB- HelixDB's DSL has no scalar string functions (upper/lower/substring/length/concat) — only property filters and graph traversal.
string_to_lowerHelixDB- No scalar string functions in the DSL (see string_to_upper).
string_substringHelixDB- No scalar string functions in the DSL (see string_to_upper).
string_sizeHelixDB- No scalar string functions in the DSL (see string_to_upper).
string_concatHelixDB- No scalar string functions in the DSL (see string_to_upper).
numeric_absHelixDB- HelixDB's Expr supports +,-,*,/,% but no abs/floor/ceil/round.
numeric_floorHelixDB- HelixDB's Expr supports +,-,*,/,% but no abs/floor/ceil/round.
numeric_ceilHelixDB- HelixDB's Expr supports +,-,*,/,% but no abs/floor/ceil/round.
numeric_roundHelixDB- HelixDB's Expr supports +,-,*,/,% but no abs/floor/ceil/round.
aggregate_countHelixDB- The HelixDB enterprise-dev image rejects `count()` dynamic queries with `rate limit exceeded` (its other 9 workloads run fine). The count handler is wired in helixdb.rs and would run on a server without that limit.
aggregate_collectHelixDB- aggregate_by offers Count/Sum/Min/Max/Mean, no list collect.
aggregate_count_distinctHelixDB- Needs count(DISTINCT); count() is rate-limited on the enterprise-dev image and value-level DISTINCT isn't exposed.
grouped_aggregationHelixDB- group_count groups by a stored property, not a computed value % 10 key.
with_pipelineHelixDB- Returns count(...); count() is rate-limited on the enterprise-dev image (see aggregate_count).
with_distinct_then_countHelixDB- count() rate-limited and no value-level DISTINCT.
with_aggregate_then_filterHelixDB- Group-then-having on a computed key (value % 10) isn't expressible; group_count keys on a stored property.
predicate_via_functionHelixDB- WHERE size(name) needs a length() scalar the DSL doesn't provide.
distinct_with_orderHelixDB- No value-level DISTINCT (see distinct).
variable_length_pathHelixDB- Range-bounded variable-length expansion isn't mapped; fixed depths are benched as recursive_depth2/3/5.
varlen_2_to_5HelixDB- Range-bounded variable-length expansion isn't mapped (see variable_length_path).
varlen_exact_5HelixDB- Range-bounded variable-length expansion isn't mapped (see variable_length_path).
star_fanout_countHelixDB- The HelixDB enterprise-dev image rejects `count()` dynamic queries with `rate limit exceeded` (its other 9 workloads run fine); see aggregate_count.