aboutsummaryrefslogtreecommitdiffstats
path: root/research/experiments
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-30 08:54:29 +0100
committereunhhu <[email protected]>2026-09-30 08:54:29 +0100
commit9840d27a9e437de32256024a2fd6a3219a239815 (patch)
treeeba57012bcdaac8e019d1421370a570a3e9f70d9 /research/experiments
parent987d4d7aa08624e28d0ea18a1e66e359a0230c80 (diff)
downloadpure-9840d27a9e437de32256024a2fd6a3219a239815.tar.gz
pure-9840d27a9e437de32256024a2fd6a3219a239815.zip
Say what snapshots cost the owner, and what reusing their nodes gave (107)
Most of it was the allocator: leaves past glibc's thread cache, freed by whichever thread let the last snapshot go. jemalloc was 11-14% faster at more memory; reusing the nodes in Pure gave a median +9.4% over six pairs, 4-8% less CPU a transaction in all six, and 1.97x the state bytes resident where it was 2.18x. TPC-C in RAM is now 4.0x a tuned SQLite at W=1 and 3.5x at W=4; finding items is the owner's largest part now.
Diffstat (limited to 'research/experiments')
-rw-r--r--research/experiments/022-tpcc-grouped/tables.py5
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-after-1-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-after-2-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-after-3-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-after-4-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-after-5-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-after-6-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-allocator-glibc-1-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-allocator-glibc-2-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-allocator-jemalloc-1-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-allocator-jemalloc-2-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-allocator-tcache-1-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-before-1-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-before-2-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-before-3-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-before-4-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-before-5-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-before-6-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-owner-run-linux-aarch64.jsonl3
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-owner-stacks-linux-aarch64.txt80
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-ram-w1-linux-aarch64.jsonl9
-rw-r--r--research/experiments/023-node-reuse/2026-09-30-ram-w4-linux-aarch64.jsonl9
-rw-r--r--research/experiments/023-node-reuse/runs.sh54
-rw-r--r--research/experiments/023-node-reuse/summary.py50
24 files changed, 259 insertions, 2 deletions
diff --git a/research/experiments/022-tpcc-grouped/tables.py b/research/experiments/022-tpcc-grouped/tables.py
index 2c018b0..fcfd468 100644
--- a/research/experiments/022-tpcc-grouped/tables.py
+++ b/research/experiments/022-tpcc-grouped/tables.py
@@ -69,5 +69,6 @@ def table(name, device):
print()
-for name in sys.argv[1:] or ['ram-w1', 'ram-w4', 'sd-w1-*', 'sd-w4-*']:
- table(name, name.startswith('sd'))
+if __name__ == '__main__':
+ for name in sys.argv[1:] or ['ram-w1', 'ram-w4', 'sd-w1-*', 'sd-w4-*']:
+ table(name, name.startswith('sd'))
diff --git a/research/experiments/023-node-reuse/2026-09-30-after-1-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-after-1-linux-aarch64.jsonl
new file mode 100644
index 0000000..bc8e270
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-after-1-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.73, "sqlite_load_s": 1.61, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 38305, "new_orders_per_minute": 1024457, "undone_new_orders": 3268, "errors": 0, "new_order": {"done": 344754, "failed": 0, "p50_us": 1472, "p99_us": 5888}, "payment": {"done": 329403, "failed": 0, "p50_us": 1472, "p99_us": 5888}, "order_status": {"done": 30724, "failed": 0, "p50_us": 272, "p99_us": 2816}, "delivery": {"done": 30742, "failed": 0, "p50_us": 1472, "p99_us": 5888}, "stock_level": {"done": 30476, "failed": 0, "p50_us": 304, "p99_us": 3072}, "server_threads": "3", "cpu_us_per_transaction": 45.6, "core_shares": {"pure-owner": 0.83, "pure-checkpoint": 0.01}, "resident_mib": 407.4, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 407.4, "pure_state_mib": 206.7, "pure_store_mib": 214.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 24045, "burst_events": 701713, "checkpoints": 33}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-after-2-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-after-2-linux-aarch64.jsonl
new file mode 100644
index 0000000..1a4e2fd
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-after-2-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.72, "sqlite_load_s": 1.6, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 43811, "new_orders_per_minute": 1172150, "undone_new_orders": 3762, "errors": 0, "new_order": {"done": 394494, "failed": 0, "p50_us": 1472, "p99_us": 3200}, "payment": {"done": 376612, "failed": 0, "p50_us": 1472, "p99_us": 3200}, "order_status": {"done": 35142, "failed": 0, "p50_us": 256, "p99_us": 1152}, "delivery": {"done": 35080, "failed": 0, "p50_us": 1472, "p99_us": 3200}, "stock_level": {"done": 34926, "failed": 0, "p50_us": 288, "p99_us": 1280}, "server_threads": "3", "cpu_us_per_transaction": 43.8, "core_shares": {"pure-owner": 0.91, "pure-checkpoint": 0.01}, "resident_mib": 458.6, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 458.6, "pure_state_mib": 233.3, "pure_store_mib": 238.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 26432, "burst_events": 802509, "checkpoints": 39}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-after-3-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-after-3-linux-aarch64.jsonl
new file mode 100644
index 0000000..5e21714
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-after-3-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.57, "pure_load_s": 0.71, "sqlite_load_s": 1.74, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 43732, "new_orders_per_minute": 1170089, "undone_new_orders": 3746, "errors": 0, "new_order": {"done": 393776, "failed": 0, "p50_us": 1472, "p99_us": 3584}, "payment": {"done": 375969, "failed": 0, "p50_us": 1408, "p99_us": 3456}, "order_status": {"done": 35031, "failed": 0, "p50_us": 256, "p99_us": 1280}, "delivery": {"done": 35009, "failed": 0, "p50_us": 1472, "p99_us": 3328}, "stock_level": {"done": 34864, "failed": 0, "p50_us": 288, "p99_us": 1344}, "server_threads": "3", "cpu_us_per_transaction": 43.9, "core_shares": {"pure-owner": 0.9, "pure-checkpoint": 0.01}, "resident_mib": 458.0, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 458.0, "pure_state_mib": 232.9, "pure_store_mib": 238.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 26495, "burst_events": 801094, "checkpoints": 39}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-after-4-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-after-4-linux-aarch64.jsonl
new file mode 100644
index 0000000..5753c70
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-after-4-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.58, "pure_load_s": 0.73, "sqlite_load_s": 1.72, "sqlite_page_size": 4096, "pure_resident_mib": 38.9, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 41485, "new_orders_per_minute": 1110139, "undone_new_orders": 3545, "errors": 0, "new_order": {"done": 373592, "failed": 0, "p50_us": 1472, "p99_us": 4608}, "payment": {"done": 356539, "failed": 0, "p50_us": 1472, "p99_us": 4352}, "order_status": {"done": 33350, "failed": 0, "p50_us": 272, "p99_us": 1920}, "delivery": {"done": 33193, "failed": 0, "p50_us": 1472, "p99_us": 4608}, "stock_level": {"done": 33021, "failed": 0, "p50_us": 304, "p99_us": 2048}, "server_threads": "3", "cpu_us_per_transaction": 44.7, "core_shares": {"pure-owner": 0.87, "pure-checkpoint": 0.01}, "resident_mib": 438.8, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 438.8, "pure_state_mib": 222.1, "pure_store_mib": 230.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 26186, "burst_events": 759848, "checkpoints": 37}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-after-5-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-after-5-linux-aarch64.jsonl
new file mode 100644
index 0000000..f895f85
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-after-5-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.72, "sqlite_load_s": 1.57, "sqlite_page_size": 4096, "pure_resident_mib": 38.9, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 41617, "new_orders_per_minute": 1113588, "undone_new_orders": 3556, "errors": 0, "new_order": {"done": 374752, "failed": 0, "p50_us": 1472, "p99_us": 4096}, "payment": {"done": 357693, "failed": 0, "p50_us": 1472, "p99_us": 4096}, "order_status": {"done": 33407, "failed": 0, "p50_us": 256, "p99_us": 1600}, "delivery": {"done": 33347, "failed": 0, "p50_us": 1472, "p99_us": 4096}, "stock_level": {"done": 33138, "failed": 0, "p50_us": 304, "p99_us": 1856}, "server_threads": "3", "cpu_us_per_transaction": 45.0, "core_shares": {"pure-owner": 0.88, "pure-checkpoint": 0.01}, "resident_mib": 439.3, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 439.3, "pure_state_mib": 222.7, "pure_store_mib": 230.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 26099, "burst_events": 762316, "checkpoints": 37}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-after-6-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-after-6-linux-aarch64.jsonl
new file mode 100644
index 0000000..6fe89a3
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-after-6-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.72, "sqlite_load_s": 1.58, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 42292, "new_orders_per_minute": 1131652, "undone_new_orders": 3611, "errors": 0, "new_order": {"done": 380829, "failed": 0, "p50_us": 1472, "p99_us": 3968}, "payment": {"done": 363536, "failed": 0, "p50_us": 1472, "p99_us": 3968}, "order_status": {"done": 33950, "failed": 0, "p50_us": 256, "p99_us": 1536}, "delivery": {"done": 33869, "failed": 0, "p50_us": 1472, "p99_us": 3968}, "stock_level": {"done": 33663, "failed": 0, "p50_us": 304, "p99_us": 1664}, "server_threads": "3", "cpu_us_per_transaction": 44.7, "core_shares": {"pure-owner": 0.89, "pure-checkpoint": 0.01}, "resident_mib": 445.2, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 445.2, "pure_state_mib": 226.0, "pure_store_mib": 230.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 26227, "burst_events": 774708, "checkpoints": 38}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-allocator-glibc-1-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-allocator-glibc-1-linux-aarch64.jsonl
new file mode 100644
index 0000000..a156a94
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-allocator-glibc-1-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.71, "sqlite_load_s": 1.58, "sqlite_page_size": 4096, "pure_resident_mib": 38.1, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 37280, "new_orders_per_minute": 996985, "undone_new_orders": 3189, "errors": 0, "new_order": {"done": 335518, "failed": 0, "p50_us": 1664, "p99_us": 4352}, "payment": {"done": 320602, "failed": 0, "p50_us": 1664, "p99_us": 4352}, "order_status": {"done": 29884, "failed": 0, "p50_us": 272, "p99_us": 2176}, "delivery": {"done": 29906, "failed": 0, "p50_us": 1664, "p99_us": 4352}, "stock_level": {"done": 29689, "failed": 0, "p50_us": 320, "p99_us": 2560}, "server_threads": "3", "cpu_us_per_transaction": 48.2, "core_shares": {"pure-owner": 0.88, "pure-checkpoint": 0.01}, "resident_mib": 438.6, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 438.6, "pure_state_mib": 201.8, "pure_store_mib": 206.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 23125, "burst_events": 682923, "checkpoints": 32}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-allocator-glibc-2-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-allocator-glibc-2-linux-aarch64.jsonl
new file mode 100644
index 0000000..a2785f8
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-allocator-glibc-2-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.72, "sqlite_load_s": 1.63, "sqlite_page_size": 4096, "pure_resident_mib": 38.1, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 40515, "new_orders_per_minute": 1083966, "undone_new_orders": 3476, "errors": 0, "new_order": {"done": 364798, "failed": 0, "p50_us": 1600, "p99_us": 3200}, "payment": {"done": 348245, "failed": 0, "p50_us": 1600, "p99_us": 3072}, "order_status": {"done": 32579, "failed": 0, "p50_us": 256, "p99_us": 1344}, "delivery": {"done": 32449, "failed": 0, "p50_us": 1600, "p99_us": 3200}, "stock_level": {"done": 32227, "failed": 0, "p50_us": 288, "p99_us": 1536}, "server_threads": "3", "cpu_us_per_transaction": 46.8, "core_shares": {"pure-owner": 0.92, "pure-checkpoint": 0.01}, "resident_mib": 474.3, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 474.3, "pure_state_mib": 217.4, "pure_store_mib": 222.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 24336, "burst_events": 742101, "checkpoints": 36}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-allocator-jemalloc-1-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-allocator-jemalloc-1-linux-aarch64.jsonl
new file mode 100644
index 0000000..75074f5
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-allocator-jemalloc-1-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.71, "sqlite_load_s": 1.62, "sqlite_page_size": 4096, "pure_resident_mib": 51.4, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 42323, "new_orders_per_minute": 1132316, "undone_new_orders": 3622, "errors": 0, "new_order": {"done": 381061, "failed": 0, "p50_us": 1408, "p99_us": 4608}, "payment": {"done": 363847, "failed": 0, "p50_us": 1408, "p99_us": 4608}, "order_status": {"done": 33946, "failed": 0, "p50_us": 272, "p99_us": 1984}, "delivery": {"done": 33913, "failed": 0, "p50_us": 1408, "p99_us": 4352}, "stock_level": {"done": 33695, "failed": 0, "p50_us": 304, "p99_us": 2176}, "server_threads": "3", "cpu_us_per_transaction": 43.4, "core_shares": {"pure-owner": 0.85, "pure-checkpoint": 0.01}, "resident_mib": 506.0, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 506.0, "pure_state_mib": 226.1, "pure_store_mib": 230.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 27007, "burst_events": 775283, "checkpoints": 38}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-allocator-jemalloc-2-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-allocator-jemalloc-2-linux-aarch64.jsonl
new file mode 100644
index 0000000..a8e76a1
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-allocator-jemalloc-2-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.71, "sqlite_load_s": 1.61, "sqlite_page_size": 4096, "pure_resident_mib": 51.0, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 45119, "new_orders_per_minute": 1207006, "undone_new_orders": 3879, "errors": 0, "new_order": {"done": 406223, "failed": 0, "p50_us": 1408, "p99_us": 3456}, "payment": {"done": 387908, "failed": 0, "p50_us": 1408, "p99_us": 3456}, "order_status": {"done": 36167, "failed": 0, "p50_us": 256, "p99_us": 1344}, "delivery": {"done": 36140, "failed": 0, "p50_us": 1408, "p99_us": 3456}, "stock_level": {"done": 35967, "failed": 0, "p50_us": 288, "p99_us": 1408}, "server_threads": "3", "cpu_us_per_transaction": 43.5, "core_shares": {"pure-owner": 0.89, "pure-checkpoint": 0.01}, "resident_mib": 536.3, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 536.3, "pure_state_mib": 239.5, "pure_store_mib": 246.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 28362, "burst_events": 826477, "checkpoints": 40}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-allocator-tcache-1-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-allocator-tcache-1-linux-aarch64.jsonl
new file mode 100644
index 0000000..4f93d87
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-allocator-tcache-1-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.72, "sqlite_load_s": 1.57, "sqlite_page_size": 4096, "pure_resident_mib": 38.0, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 39799, "new_orders_per_minute": 1064974, "undone_new_orders": 3407, "errors": 0, "new_order": {"done": 358401, "failed": 0, "p50_us": 1664, "p99_us": 3584}, "payment": {"done": 342088, "failed": 0, "p50_us": 1600, "p99_us": 3456}, "order_status": {"done": 31982, "failed": 0, "p50_us": 256, "p99_us": 1664}, "delivery": {"done": 31892, "failed": 0, "p50_us": 1600, "p99_us": 3456}, "stock_level": {"done": 31628, "failed": 0, "p50_us": 304, "p99_us": 1792}, "server_threads": "3", "cpu_us_per_transaction": 47.0, "core_shares": {"pure-owner": 0.91, "pure-checkpoint": 0.01}, "resident_mib": 465.9, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 465.9, "pure_state_mib": 214.0, "pure_store_mib": 222.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 24127, "burst_events": 729058, "checkpoints": 36}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-before-1-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-before-1-linux-aarch64.jsonl
new file mode 100644
index 0000000..b50fef8
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-before-1-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.72, "sqlite_load_s": 1.56, "sqlite_page_size": 4096, "pure_resident_mib": 38.1, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 39304, "new_orders_per_minute": 1051376, "undone_new_orders": 3367, "errors": 0, "new_order": {"done": 353832, "failed": 0, "p50_us": 1664, "p99_us": 3584}, "payment": {"done": 337906, "failed": 0, "p50_us": 1600, "p99_us": 3584}, "order_status": {"done": 31594, "failed": 0, "p50_us": 256, "p99_us": 1536}, "delivery": {"done": 31495, "failed": 0, "p50_us": 1600, "p99_us": 3456}, "stock_level": {"done": 31267, "failed": 0, "p50_us": 304, "p99_us": 1792}, "server_threads": "3", "cpu_us_per_transaction": 47.4, "core_shares": {"pure-owner": 0.91, "pure-checkpoint": 0.01}, "resident_mib": 460.9, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 460.9, "pure_state_mib": 211.5, "pure_store_mib": 214.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 23739, "burst_events": 719932, "checkpoints": 35}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-before-2-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-before-2-linux-aarch64.jsonl
new file mode 100644
index 0000000..5b6b754
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-before-2-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.72, "sqlite_load_s": 1.58, "sqlite_page_size": 4096, "pure_resident_mib": 38.1, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 38863, "new_orders_per_minute": 1039598, "undone_new_orders": 3326, "errors": 0, "new_order": {"done": 349872, "failed": 0, "p50_us": 1664, "p99_us": 3968}, "payment": {"done": 334120, "failed": 0, "p50_us": 1600, "p99_us": 3840}, "order_status": {"done": 31207, "failed": 0, "p50_us": 256, "p99_us": 1600}, "delivery": {"done": 31184, "failed": 0, "p50_us": 1664, "p99_us": 3840}, "stock_level": {"done": 30908, "failed": 0, "p50_us": 304, "p99_us": 1856}, "server_threads": "3", "cpu_us_per_transaction": 47.0, "core_shares": {"pure-owner": 0.9, "pure-checkpoint": 0.01}, "resident_mib": 456.2, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 456.2, "pure_state_mib": 209.4, "pure_store_mib": 214.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 23303, "burst_events": 711935, "checkpoints": 34}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-before-3-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-before-3-linux-aarch64.jsonl
new file mode 100644
index 0000000..0cb9922
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-before-3-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.73, "sqlite_load_s": 1.59, "sqlite_page_size": 4096, "pure_resident_mib": 38.1, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 39952, "new_orders_per_minute": 1068823, "undone_new_orders": 3425, "errors": 0, "new_order": {"done": 359702, "failed": 0, "p50_us": 1600, "p99_us": 3584}, "payment": {"done": 343427, "failed": 0, "p50_us": 1600, "p99_us": 3456}, "order_status": {"done": 32145, "failed": 0, "p50_us": 256, "p99_us": 1600}, "delivery": {"done": 31999, "failed": 0, "p50_us": 1600, "p99_us": 3456}, "stock_level": {"done": 31779, "failed": 0, "p50_us": 288, "p99_us": 1728}, "server_threads": "3", "cpu_us_per_transaction": 47.0, "core_shares": {"pure-owner": 0.91, "pure-checkpoint": 0.01}, "resident_mib": 467.8, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 467.8, "pure_state_mib": 214.7, "pure_store_mib": 222.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 24088, "burst_events": 731789, "checkpoints": 36}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-before-4-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-before-4-linux-aarch64.jsonl
new file mode 100644
index 0000000..74be71d
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-before-4-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.72, "sqlite_load_s": 1.58, "sqlite_page_size": 4096, "pure_resident_mib": 38.0, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 37931, "new_orders_per_minute": 1014602, "undone_new_orders": 3235, "errors": 0, "new_order": {"done": 341436, "failed": 0, "p50_us": 1664, "p99_us": 4096}, "payment": {"done": 326136, "failed": 0, "p50_us": 1664, "p99_us": 4096}, "order_status": {"done": 30443, "failed": 0, "p50_us": 272, "p99_us": 1984}, "delivery": {"done": 30413, "failed": 0, "p50_us": 1664, "p99_us": 4096}, "stock_level": {"done": 30195, "failed": 0, "p50_us": 320, "p99_us": 2176}, "server_threads": "3", "cpu_us_per_transaction": 48.4, "core_shares": {"pure-owner": 0.89, "pure-checkpoint": 0.01}, "resident_mib": 445.5, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 445.5, "pure_state_mib": 204.9, "pure_store_mib": 206.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 23368, "burst_events": 694830, "checkpoints": 33}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-before-5-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-before-5-linux-aarch64.jsonl
new file mode 100644
index 0000000..8bba878
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-before-5-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.72, "sqlite_load_s": 1.69, "sqlite_page_size": 4096, "pure_resident_mib": 38.1, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 36817, "new_orders_per_minute": 984754, "undone_new_orders": 3146, "errors": 0, "new_order": {"done": 331418, "failed": 0, "p50_us": 1664, "p99_us": 4864}, "payment": {"done": 316613, "failed": 0, "p50_us": 1664, "p99_us": 4864}, "order_status": {"done": 29542, "failed": 0, "p50_us": 272, "p99_us": 2432}, "delivery": {"done": 29512, "failed": 0, "p50_us": 1664, "p99_us": 4608}, "stock_level": {"done": 29297, "failed": 0, "p50_us": 304, "p99_us": 2432}, "server_threads": "3", "cpu_us_per_transaction": 48.2, "core_shares": {"pure-owner": 0.88, "pure-checkpoint": 0.01}, "resident_mib": 433.5, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 433.5, "pure_state_mib": 199.6, "pure_store_mib": 206.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 22848, "burst_events": 674483, "checkpoints": 32}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-before-6-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-before-6-linux-aarch64.jsonl
new file mode 100644
index 0000000..b455f82
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-before-6-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.57, "pure_load_s": 0.72, "sqlite_load_s": 1.63, "sqlite_page_size": 4096, "pure_resident_mib": 38.1, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 38679, "new_orders_per_minute": 1034696, "undone_new_orders": 3302, "errors": 0, "new_order": {"done": 348201, "failed": 0, "p50_us": 1664, "p99_us": 3968}, "payment": {"done": 332513, "failed": 0, "p50_us": 1600, "p99_us": 3968}, "order_status": {"done": 31063, "failed": 0, "p50_us": 256, "p99_us": 1920}, "delivery": {"done": 31057, "failed": 0, "p50_us": 1600, "p99_us": 3968}, "stock_level": {"done": 30750, "failed": 0, "p50_us": 304, "p99_us": 2048}, "server_threads": "3", "cpu_us_per_transaction": 47.9, "core_shares": {"pure-owner": 0.9, "pure-checkpoint": 0.01}, "resident_mib": 453.6, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 453.6, "pure_state_mib": 208.5, "pure_store_mib": 214.7, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 23746, "burst_events": 708553, "checkpoints": 34}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-owner-run-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-owner-run-linux-aarch64.jsonl
new file mode 100644
index 0000000..97f3543
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-owner-run-linux-aarch64.jsonl
@@ -0,0 +1,3 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.73, "sqlite_load_s": 1.6, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 39350, "new_orders_per_minute": 1051691, "undone_new_orders": 15845, "errors": 0, "new_order": {"done": 1593393, "failed": 0, "p50_us": 1536, "p99_us": 4096}, "payment": {"done": 1523624, "failed": 0, "p50_us": 1536, "p99_us": 4096}, "order_status": {"done": 141544, "failed": 0, "p50_us": 272, "p99_us": 1664}, "delivery": {"done": 141406, "failed": 0, "p50_us": 1536, "p99_us": 4096}, "stock_level": {"done": 141524, "failed": 0, "p50_us": 304, "p99_us": 1792}, "server_threads": "3", "cpu_us_per_transaction": 45.8, "core_shares": {"pure-owner": 0.86, "pure-checkpoint": 0.02}, "resident_mib": 1683.6, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 1739.4, "pure_state_mib": 874.3, "pure_store_mib": 932.5, "sqlite_files_mib": 13.8, "grouped_sqlite_files_mib": 0.0, "pure_counts": {"bursts": 108865, "burst_events": 3242662, "checkpoints": 166}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-owner-stacks-linux-aarch64.txt b/research/experiments/023-node-reuse/2026-09-30-owner-stacks-linux-aarch64.txt
new file mode 100644
index 0000000..ed498a2
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-owner-stacks-linux-aarch64.txt
@@ -0,0 +1,80 @@
+mprotect < ?? < ?? < malloc < list_changes < pure_save_commit < pure_app_save < save_burst < save_burst < execute < execute < run_owner < ?? < ??
+upper < pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < move_items < move_items < place < pure_list_insert < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+upper < pure_list_seek < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+upper < pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_timedwait < run_owner < ?? < ??
+?? < malloc < new_node < prepare < pure_list_insert < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_timedwait < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_wait < run_owner < ?? < ??
+item_field < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < hand_back < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_wait < run_owner < ?? < ??
+pure_log_append < pure_save_commit < pure_app_save < save_burst < save_burst < execute < execute < run_owner < ?? < ??
+upper < pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < malloc < new_node < prepare < pure_list_insert < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < own < descend < pure_list_set < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_wait < run_owner < ?? < ??
+?? < ?? < ?? < free < release_extras < place < pure_list_insert < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < hand_back < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < hand_back < execute < execute < run_owner < ?? < ??
+descend < prepare < pure_list_insert < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_timedwait < run_owner < ?? < ??
+child_at < leaf_of < pure_list_get < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+lower < pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_wait < run_owner < ?? < ??
+pure_list_count < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+apply_effect < execute < execute < run_owner < ?? < ??
+mark_event < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+lower < pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+own < descend < pure_list_set < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+mix < stripes < digest_add < entry_digest < pure_log_append < pure_save_commit < pure_app_save < save_burst < save_burst < execute < execute < run_owner < ?? < ??
+descend < prepare < pure_list_insert < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_wait < run_owner < ?? < ??
+child < leaf_of < pure_list_get < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+malloc@plt < new_node < own < descend < prepare < pure_list_insert < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < hand_back < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < hand_back < execute < execute < run_owner < ?? < ??
+pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_timedwait < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_timedwait < run_owner < ?? < ??
+sum < sum < sum_path < sum_path < place < pure_list_insert < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < hand_back < execute < execute < run_owner < ?? < ??
+run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_timedwait < run_owner < ?? < ??
+new_node < own < descend < pure_list_set < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+descend < prepare < pure_list_insert < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+descend < prepare < pure_list_insert < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_timedwait < run_owner < ?? < ??
+pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+journal_room < pure_list_set < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+upper < pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+malloc < new_node < prepare < pure_list_insert < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < malloc < new_node < own < descend < prepare < pure_list_insert < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_wait < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_timedwait < run_owner < ?? < ??
+?? < malloc < pure_list_share < pure_save_snapshot < pure_app_snapshot < publish < after_save < save_burst < save_burst < execute < execute < run_owner < ?? < ??
+lower < pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+lower < pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+own < descend < prepare < pure_list_insert < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+child < pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_timedwait < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_timedwait < run_owner < ?? < ??
+new_node < own < descend < pure_list_set < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+child < pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < hand_back < execute < execute < run_owner < ?? < ??
+descend < pure_list_set < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+?? < ?? < ?? < pthread_cond_timedwait < run_owner < ?? < ??
+put_compact < pure_list_insert < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+pure_save_commit < pure_app_save < save_burst < save_burst < execute < execute < run_owner < ?? < ??
+stored_list < pure_app_checkpoint < checkpoint_round < after_save < save_burst < save_burst < execute < execute < run_owner < ?? < ??
+upper < pure_list_seek < run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
+run < run < dispatch < message < pure_app_message_fields < apply_input < apply_effect < execute < execute < run_owner < ?? < ??
diff --git a/research/experiments/023-node-reuse/2026-09-30-ram-w1-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-ram-w1-linux-aarch64.jsonl
new file mode 100644
index 0000000..c516273
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-ram-w1-linux-aarch64.jsonl
@@ -0,0 +1,9 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 1, "rows": 568758, "generate_s": 0.56, "pure_load_s": 0.74, "sqlite_load_s": 1.59, "sqlite_page_size": 4096, "pure_resident_mib": 38.2, "sqlite_file_mib": 13.8}
+{"step": "same transactions", "transactions": 20000, "pure": {"new_order": 9036, "payment": 8518, "order_status": 811, "delivery": 796, "stock_level": 839}, "sqlite": {"new_order": 9036, "payment": 8518, "order_status": 811, "delivery": 796, "stock_level": 839}, "undone_new_orders": [90, 90], "failed": [0, 0], "differing": {}, "grouped_sqlite_differing": {}, "consistency_failures": []}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 16, "transactions_per_second": 38320, "new_orders_per_minute": 1025360, "undone_new_orders": 3508, "errors": 0, "new_order": {"done": 345298, "failed": 0, "p50_us": 416, "p99_us": 1088}, "payment": {"done": 329116, "failed": 0, "p50_us": 400, "p99_us": 1024}, "order_status": {"done": 30751, "failed": 0, "p50_us": 100, "p99_us": 512}, "delivery": {"done": 30647, "failed": 0, "p50_us": 400, "p99_us": 1024}, "stock_level": {"done": 30604, "failed": 0, "p50_us": 144, "p99_us": 544}, "server_threads": "3", "cpu_us_per_transaction": 42.7, "core_shares": {"pure-owner": 0.81, "pure-checkpoint": 0.02}, "resident_mib": 425.4, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "run", "system": "pure", "warehouses": 1, "terminals": 64, "transactions_per_second": 40976, "new_orders_per_minute": 1096607, "undone_new_orders": 3513, "errors": 0, "new_order": {"done": 369053, "failed": 0, "p50_us": 1536, "p99_us": 3968}, "payment": {"done": 352111, "failed": 0, "p50_us": 1536, "p99_us": 3968}, "order_status": {"done": 32916, "failed": 0, "p50_us": 272, "p99_us": 1664}, "delivery": {"done": 32826, "failed": 0, "p50_us": 1536, "p99_us": 3968}, "stock_level": {"done": 32620, "failed": 0, "p50_us": 304, "p99_us": 1728}, "server_threads": "3", "cpu_us_per_transaction": 45.8, "core_shares": {"pure-owner": 0.89, "pure-checkpoint": 0.01}, "resident_mib": 821.5, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "run", "system": "sqlite 3.46.1", "synchronous": "full", "pragmas": "PRAGMA mmap_size=1073741824; PRAGMA cache_size=-65536; PRAGMA temp_store=MEMORY; PRAGMA wal_autocheckpoint=10000;", "warehouses": 1, "terminals": 1, "transactions_per_second": 10164, "batches": 0, "batched": 0, "new_orders_per_minute": 272459, "undone_new_orders": 964, "new_order": {"done": 91812, "failed": 0, "p50_us": 152, "p99_us": 256}, "payment": {"done": 87175, "failed": 0, "p50_us": 24, "p99_us": 44}, "order_status": {"done": 8073, "failed": 0, "p50_us": 16, "p99_us": 30}, "delivery": {"done": 8215, "failed": 0, "p50_us": 56, "p99_us": 352}, "stock_level": {"done": 8065, "failed": 0, "p50_us": 272, "p99_us": 432}, "cpu_seconds": 19.939, "peak_resident_kib": 99744, "written_bytes": 0, "cpu_us_per_transaction": 98.1, "peak_resident_mib": 97.4, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "run", "system": "sqlite 3.46.1", "synchronous": "full", "pragmas": "PRAGMA mmap_size=1073741824; PRAGMA cache_size=-65536; PRAGMA temp_store=MEMORY; PRAGMA wal_autocheckpoint=10000;", "warehouses": 1, "terminals": 4, "transactions_per_second": 9955, "batches": 0, "batched": 0, "new_orders_per_minute": 266365, "undone_new_orders": 948, "new_order": {"done": 90047, "failed": 0, "p50_us": 152, "p99_us": 304}, "payment": {"done": 85836, "failed": 0, "p50_us": 25, "p99_us": 52}, "order_status": {"done": 7969, "failed": 0, "p50_us": 20, "p99_us": 46}, "delivery": {"done": 8007, "failed": 0, "p50_us": 58, "p99_us": 136}, "stock_level": {"done": 7937, "failed": 0, "p50_us": 272, "p99_us": 608}, "cpu_seconds": 20.287, "peak_resident_kib": 42784, "written_bytes": 0, "cpu_us_per_transaction": 101.5, "peak_resident_mib": 41.8, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "run", "system": "sqlite 3.46.1, grouped", "synchronous": "full", "pragmas": "PRAGMA mmap_size=1073741824; PRAGMA cache_size=-65536; PRAGMA temp_store=MEMORY; PRAGMA wal_autocheckpoint=10000;", "warehouses": 1, "terminals": 16, "transactions_per_second": 9731, "batches": 15707, "batched": 179191, "new_orders_per_minute": 260697, "undone_new_orders": 882, "new_order": {"done": 87831, "failed": 0, "p50_us": 1600, "p99_us": 4352}, "payment": {"done": 83499, "failed": 0, "p50_us": 1472, "p99_us": 4096}, "order_status": {"done": 7845, "failed": 0, "p50_us": 136, "p99_us": 864}, "delivery": {"done": 7861, "failed": 0, "p50_us": 1536, "p99_us": 4096}, "stock_level": {"done": 7691, "failed": 0, "p50_us": 736, "p99_us": 1792}, "cpu_seconds": 26.473, "peak_resident_kib": 77728, "written_bytes": 0, "cpu_us_per_transaction": 135.9, "peak_resident_mib": 75.9, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "run", "system": "sqlite 3.46.1, grouped", "synchronous": "full", "pragmas": "PRAGMA mmap_size=1073741824; PRAGMA cache_size=-65536; PRAGMA temp_store=MEMORY; PRAGMA wal_autocheckpoint=10000;", "warehouses": 1, "terminals": 64, "transactions_per_second": 10073, "batches": 3703, "batched": 185882, "new_orders_per_minute": 268814, "undone_new_orders": 873, "new_order": {"done": 90762, "failed": 0, "p50_us": 5888, "p99_us": 12800}, "payment": {"done": 87012, "failed": 0, "p50_us": 5888, "p99_us": 12800}, "order_status": {"done": 8203, "failed": 0, "p50_us": 248, "p99_us": 1728}, "delivery": {"done": 8108, "failed": 0, "p50_us": 5888, "p99_us": 12800}, "stock_level": {"done": 8018, "failed": 0, "p50_us": 1152, "p99_us": 3840}, "cpu_seconds": 27.139, "peak_resident_kib": 129888, "written_bytes": 0, "cpu_us_per_transaction": 134.3, "peak_resident_mib": 126.8, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 821.5, "pure_state_mib": 408.9, "pure_store_mib": 447.2, "sqlite_files_mib": 82.6, "grouped_sqlite_files_mib": 80.9, "pure_counts": {"bursts": 133359, "burst_events": 1470390, "checkpoints": 77}}
diff --git a/research/experiments/023-node-reuse/2026-09-30-ram-w4-linux-aarch64.jsonl b/research/experiments/023-node-reuse/2026-09-30-ram-w4-linux-aarch64.jsonl
new file mode 100644
index 0000000..82d7c58
--- /dev/null
+++ b/research/experiments/023-node-reuse/2026-09-30-ram-w4-linux-aarch64.jsonl
@@ -0,0 +1,9 @@
+{"step": "load", "directory": "/dev/shm", "warehouses": 4, "rows": 1975536, "generate_s": 1.99, "pure_load_s": 2.64, "sqlite_load_s": 5.95, "sqlite_page_size": 4096, "pure_resident_mib": 104.1, "sqlite_file_mib": 52.8}
+{"step": "same transactions", "transactions": 20000, "pure": {"new_order": 8875, "payment": 8786, "order_status": 777, "delivery": 777, "stock_level": 785}, "sqlite": {"new_order": 8875, "payment": 8786, "order_status": 777, "delivery": 777, "stock_level": 785}, "undone_new_orders": [93, 93], "failed": [0, 0], "differing": {}, "grouped_sqlite_differing": {}, "consistency_failures": []}
+{"step": "run", "system": "pure", "warehouses": 4, "terminals": 16, "transactions_per_second": 33057, "new_orders_per_minute": 883329, "undone_new_orders": 2956, "errors": 0, "new_order": {"done": 297399, "failed": 0, "p50_us": 496, "p99_us": 1408}, "payment": {"done": 283706, "failed": 0, "p50_us": 448, "p99_us": 1344}, "order_status": {"done": 26855, "failed": 0, "p50_us": 84, "p99_us": 544}, "delivery": {"done": 26604, "failed": 0, "p50_us": 464, "p99_us": 1472}, "stock_level": {"done": 26583, "failed": 0, "p50_us": 144, "p99_us": 640}, "server_threads": "3", "cpu_us_per_transaction": 46.6, "core_shares": {"pure-owner": 0.82, "pure-checkpoint": 0.01}, "resident_mib": 459.0, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "run", "system": "pure", "warehouses": 4, "terminals": 64, "transactions_per_second": 35838, "new_orders_per_minute": 958218, "undone_new_orders": 3172, "errors": 0, "new_order": {"done": 322578, "failed": 0, "p50_us": 1856, "p99_us": 3584}, "payment": {"done": 308407, "failed": 0, "p50_us": 1792, "p99_us": 3584}, "order_status": {"done": 28642, "failed": 0, "p50_us": 272, "p99_us": 1216}, "delivery": {"done": 28624, "failed": 0, "p50_us": 1792, "p99_us": 3456}, "stock_level": {"done": 28509, "failed": 0, "p50_us": 304, "p99_us": 1344}, "server_threads": "3", "cpu_us_per_transaction": 50.2, "core_shares": {"pure-owner": 0.92, "pure-checkpoint": 0.01}, "resident_mib": 817.1, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "run", "system": "sqlite 3.46.1", "synchronous": "full", "pragmas": "PRAGMA mmap_size=1073741824; PRAGMA cache_size=-65536; PRAGMA temp_store=MEMORY; PRAGMA wal_autocheckpoint=10000;", "warehouses": 4, "terminals": 1, "transactions_per_second": 10168, "batches": 0, "batched": 0, "new_orders_per_minute": 272034, "undone_new_orders": 943, "new_order": {"done": 91652, "failed": 0, "p50_us": 152, "p99_us": 240}, "payment": {"done": 87378, "failed": 0, "p50_us": 25, "p99_us": 42}, "order_status": {"done": 8107, "failed": 0, "p50_us": 16, "p99_us": 28}, "delivery": {"done": 8122, "failed": 0, "p50_us": 56, "p99_us": 416}, "stock_level": {"done": 8167, "failed": 0, "p50_us": 272, "p99_us": 384}, "cpu_seconds": 19.95, "peak_resident_kib": 117472, "written_bytes": 0, "cpu_us_per_transaction": 98.1, "peak_resident_mib": 114.7, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "run", "system": "sqlite 3.46.1", "synchronous": "full", "pragmas": "PRAGMA mmap_size=1073741824; PRAGMA cache_size=-65536; PRAGMA temp_store=MEMORY; PRAGMA wal_autocheckpoint=10000;", "warehouses": 4, "terminals": 4, "transactions_per_second": 9732, "batches": 0, "batched": 0, "new_orders_per_minute": 259837, "undone_new_orders": 811, "new_order": {"done": 87684, "failed": 0, "p50_us": 160, "p99_us": 288}, "payment": {"done": 84068, "failed": 0, "p50_us": 25, "p99_us": 52}, "order_status": {"done": 7871, "failed": 0, "p50_us": 19, "p99_us": 38}, "delivery": {"done": 7773, "failed": 0, "p50_us": 60, "p99_us": 128}, "stock_level": {"done": 7830, "failed": 0, "p50_us": 272, "p99_us": 608}, "cpu_seconds": 20.416, "peak_resident_kib": 60048, "written_bytes": 0, "cpu_us_per_transaction": 104.6, "peak_resident_mib": 58.6, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "run", "system": "sqlite 3.46.1, grouped", "synchronous": "full", "pragmas": "PRAGMA mmap_size=1073741824; PRAGMA cache_size=-65536; PRAGMA temp_store=MEMORY; PRAGMA wal_autocheckpoint=10000;", "warehouses": 4, "terminals": 16, "transactions_per_second": 8750, "batches": 14079, "batched": 161044, "new_orders_per_minute": 234615, "undone_new_orders": 798, "new_order": {"done": 79047, "failed": 0, "p50_us": 1792, "p99_us": 8192}, "payment": {"done": 74842, "failed": 0, "p50_us": 1600, "p99_us": 8192}, "order_status": {"done": 7025, "failed": 0, "p50_us": 136, "p99_us": 928}, "delivery": {"done": 7155, "failed": 0, "p50_us": 1664, "p99_us": 8192}, "stock_level": {"done": 7024, "failed": 0, "p50_us": 736, "p99_us": 1920}, "cpu_seconds": 26.066, "peak_resident_kib": 116320, "written_bytes": 0, "cpu_us_per_transaction": 148.9, "peak_resident_mib": 113.6, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "run", "system": "sqlite 3.46.1, grouped", "synchronous": "full", "pragmas": "PRAGMA mmap_size=1073741824; PRAGMA cache_size=-65536; PRAGMA temp_store=MEMORY; PRAGMA wal_autocheckpoint=10000;", "warehouses": 4, "terminals": 64, "transactions_per_second": 8805, "batches": 3234, "batched": 162696, "new_orders_per_minute": 236411, "undone_new_orders": 770, "new_order": {"done": 79777, "failed": 0, "p50_us": 6656, "p99_us": 18432}, "payment": {"done": 75881, "failed": 0, "p50_us": 6400, "p99_us": 17408}, "order_status": {"done": 6928, "failed": 0, "p50_us": 232, "p99_us": 2048}, "delivery": {"done": 7038, "failed": 0, "p50_us": 6656, "p99_us": 17408}, "stock_level": {"done": 6924, "failed": 0, "p50_us": 1088, "p99_us": 3584}, "cpu_seconds": 26.154, "peak_resident_kib": 189424, "written_bytes": 0, "cpu_us_per_transaction": 148.1, "peak_resident_mib": 185.0, "written_bytes_per_transaction": 0.0, "device_bytes_per_transaction": null, "consistency_failures": []}
+{"step": "end", "pure_resident_mib": 817.1, "pure_state_mib": 420.9, "pure_store_mib": 434.7, "sqlite_files_mib": 123.1, "grouped_sqlite_files_mib": 117.2, "pure_counts": {"bursts": 113964, "burst_events": 1279680, "checkpoints": 29}}
diff --git a/research/experiments/023-node-reuse/runs.sh b/research/experiments/023-node-reuse/runs.sh
new file mode 100644
index 0000000..d87302e
--- /dev/null
+++ b/research/experiments/023-node-reuse/runs.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+# The runs of docs/research/107, from the repository's root. BEFORE is
+# pure-serve built at c9fda91 (nodes a snapshot let go were freed), AFTER at
+# the commit that reuses them; copy each out of build/ first, since the
+# names they run under do not matter (the owner is found by its thread).
+set -e
+out=research/experiments/023-node-reuse
+before=${BEFORE:?pure-serve built before}
+after=${AFTER:?pure-serve built after}
+jemalloc=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2
+run() {
+ name=$1
+ shift
+ python3 benchmarks/tpcc/run.py "$@" --sqlite-threads '' --sqlite-group '' > $out/2026-09-30-$name-linux-aarch64.jsonl
+}
+alone() {
+ name=$1
+ serve=$2
+ run $name --serve $serve --warehouses 1 --check 0 --terminals 64 --seconds 20
+}
+
+# Is it the allocator? The same server under jemalloc, and with glibc's
+# thread cache raised (it stays at 1,032 B: no change), against glibc.
+printf '#!/bin/sh\nLD_PRELOAD=%s exec %s "$@"\n' $jemalloc $before > $out/serve-jemalloc.sh
+printf '#!/bin/sh\nGLIBC_TUNABLES=glibc.malloc.tcache_max=4096 exec %s "$@"\n' $before > $out/serve-tcache.sh
+chmod +x $out/serve-jemalloc.sh $out/serve-tcache.sh
+alone allocator-glibc-1 $before
+alone allocator-jemalloc-1 $out/serve-jemalloc.sh
+alone allocator-tcache-1 $out/serve-tcache.sh
+alone allocator-glibc-2 $before
+alone allocator-jemalloc-2 $out/serve-jemalloc.sh
+rm $out/serve-jemalloc.sh $out/serve-tcache.sh
+
+# Before and after, taking turns: three pairs before first, three after first.
+for round in 1 2 3; do
+ alone before-$round $before
+ alone after-$round $after
+done
+for round in 4 5 6; do
+ alone after-$round $after
+ alone before-$round $before
+done
+
+# Where the owner is now (as in 106): 80 samples while AFTER runs 90 seconds.
+python3 research/experiments/022-tpcc-grouped/owner-samples.py 80 $out/2026-09-30-owner-stacks-linux-aarch64.txt &
+run owner-run --serve $after --warehouses 1 --check 0 --terminals 64 --seconds 90
+wait
+
+# 106's RAM matrix again with AFTER (SQLite as it was).
+both='--terminals 16,64 --sqlite-threads 1,4 --sqlite-group 16,64'
+python3 benchmarks/tpcc/run.py --serve $after --warehouses 1 --check 20000 $both --seconds 20 \
+ > $out/2026-09-30-ram-w1-linux-aarch64.jsonl
+python3 benchmarks/tpcc/run.py --serve $after --warehouses 4 --check 20000 $both --seconds 20 \
+ > $out/2026-09-30-ram-w4-linux-aarch64.jsonl
diff --git a/research/experiments/023-node-reuse/summary.py b/research/experiments/023-node-reuse/summary.py
new file mode 100644
index 0000000..e5fbbb0
--- /dev/null
+++ b/research/experiments/023-node-reuse/summary.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+"""docs/research/107's numbers from the result files beside this one: the
+allocators, before and after in turns (six pairs: runs.sh made the first
+three, before first; three more followed, after first), and 106's RAM
+matrix again (with 022-tpcc-grouped/tables.py)."""
+import importlib.util
+import json
+from pathlib import Path
+
+HERE = Path(__file__).resolve().parent
+
+
+def pure_run(name):
+ run = end = None
+ for line in (HERE / f'2026-09-30-{name}-linux-aarch64.jsonl').read_text().splitlines():
+ r = json.loads(line)
+ run = r if r['step'] == 'run' else run
+ end = r if r['step'] == 'end' else end
+ return run, end
+
+
+def row(label, name):
+ run, end = pure_run(name)
+ ratio = end['pure_resident_mib'] / end['pure_state_mib']
+ print(f"| {label} | {run['transactions_per_second']:,} | {run['cpu_us_per_transaction']} | "
+ f"{run['core_shares']['pure-owner']:.2f} | {end['pure_resident_mib']:.0f} / {end['pure_state_mib']:.0f} MiB "
+ f"({ratio:.2f}) |")
+ return run['transactions_per_second']
+
+
+print('| | 초당 거래 | 거래당 CPU (µs) | 소유자의 코어 몫 | 상주 / 상태 (배수) |')
+print('|---|---:|---:|---:|---:|')
+for name, label in (('allocator-glibc-1', 'glibc'), ('allocator-jemalloc-1', 'jemalloc'),
+ ('allocator-tcache-1', 'glibc, tcache_max=4096'), ('allocator-glibc-2', 'glibc'),
+ ('allocator-jemalloc-2', 'jemalloc')):
+ row(label, name)
+print()
+print('| | 초당 거래 | 거래당 CPU (µs) | 소유자의 코어 몫 | 상주 / 상태 (배수) |')
+print('|---|---:|---:|---:|---:|')
+for round in range(1, 7): # 1-3 before first, 4-6 after first
+ before = row(f'전, {round}', f'before-{round}')
+ after = row(f'후, {round}', f'after-{round}')
+ print(f'| ({(after / before - 1) * 100:+.1f}%) | | | | |')
+print()
+spec = importlib.util.spec_from_file_location('tables', HERE.parent / '022-tpcc-grouped' / 'tables.py')
+tables = importlib.util.module_from_spec(spec)
+spec.loader.exec_module(tables)
+tables.OUT = HERE
+for name in ('ram-w1', 'ram-w4'):
+ tables.table(name, False)