Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions lib/download-hits-json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash
# Standalone version: the ClickBench Playground bakes a pre-decompressed
# hits.json into /opt/clickbench/datasets_ro and symlinks to it here. Outside
# the Playground that path doesn't exist, and parseable/load already falls
# back to downloading+decompressing hits.json.gz itself, so this script is a
# no-op there. Kept as a stub only so bench_download() has something to call.
set -e
if [ -d /opt/clickbench/datasets_ro ]; then
dir="${1:-.}"
mkdir -p "$dir"
cd "$dir"
ln -sf /opt/clickbench/datasets_ro/hits.json hits.json
fi
1 change: 1 addition & 0 deletions parseable/benchmark.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/bin/bash
export BENCH_DOWNLOAD_SCRIPT="download-hits-json"
chmod +x ../lib/download-hits-json
exec ../lib/benchmark-common.sh
2 changes: 1 addition & 1 deletion parseable/data-size
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
set -eu

du -bcs local-store | grep total | awk '{print $1}'
du -bcs data | grep total | awk '{print $1}'
2 changes: 1 addition & 1 deletion parseable/install
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ if [ ! -x ./parseable ]; then
# v2.7.2 fixes the inference; verified locally end-to-end against
# the bundled static_schema.json and hits.json.
wget --continue --progress=dot:giga \
https://github.com/parseablehq/parseable/releases/download/v2.7.2/Parseable_OSS_x86_64-unknown-linux-gnu
https://github.com/parseablehq/parseable/releases/download/v3.0.0/Parseable_OSS_x86_64-unknown-linux-gnu
mv Parseable_OSS_x86_64-unknown-linux-gnu parseable
chmod +x parseable
fi
10 changes: 8 additions & 2 deletions parseable/load
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,14 @@ fi
# subsequent chunk fails. 3 × 1000 lines is ~4x lower peak pressure
# and empirically clears without 408s. curl --retry survives short
# stalls so a briefly-saturated parseable doesn't fail the load.
LINES_PER_CHUNK=1000
INGEST_JOBS=3
NUM_CORES=$(nproc)
if [ "$NUM_CORES" -ge 190 ]; then
LINES_PER_CHUNK=2500
INGEST_JOBS=20
else
LINES_PER_CHUNK=1000
INGEST_JOBS=3
fi
pv hits.json | parallel --pipe -N$LINES_PER_CHUNK --block 10M \
--jobs "$INGEST_JOBS" --halt-on-error 0 '
awk "BEGIN{print \"[\"} NR>1{print prev \",\"} {prev=\$0} END{if (prev) print prev; print \"]\"}" |
Expand Down
48 changes: 38 additions & 10 deletions parseable/query
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,44 @@ set -e

query=$(cat)

# Parseable filters every query by [startTime, endTime] against the
# row's ingest timestamp. The original benchmark used today's calendar
# day, which only works if the dataset was loaded today. In the
# playground the data is ingested during initial provisioning and
# then frozen into a snapshot, so "today" from the query script's
# point of view drifts past the load day and every row falls outside
# the window → all queries return zero. Use a wide window that
# covers any plausible load + query date.
START_TIME="2000-01-01T00:00:00.000Z"
END_TIME="2099-12-31T23:59:00.000Z"
# Derive Parseable's mandatory query window from the stream itself. Keep a
# five-minute margin so events exactly at either reported boundary are not
# lost to timestamp precision or boundary semantics. This lookup happens
# before the query timer starts.
stream_info=$(curl -sS --fail-with-body \
-u "admin:admin" 'http://localhost:8000/api/v1/logstream/hits/info')

mapfile -t time_range < <(
printf '%s' "$stream_info" | python3 -c '
import json
import sys
from datetime import datetime, timedelta, timezone

info = json.load(sys.stdin)

def parse_timestamp(field):
value = info.get(field)
if not value:
raise ValueError(f"stream info has no {field}")
return datetime.fromisoformat(value.replace("Z", "+00:00")).astimezone(timezone.utc)

def format_timestamp(value):
return value.isoformat(timespec="milliseconds").replace("+00:00", "Z")

print(format_timestamp(parse_timestamp("firstEventAt") - timedelta(minutes=5)))
print(format_timestamp(parse_timestamp("latestEventAt") + timedelta(minutes=5)))
'
)

if [ "${#time_range[@]}" -ne 2 ]; then
echo "could not derive query time range from hits stream info" >&2
exit 1
fi

START_TIME=${time_range[0]}
END_TIME=${time_range[1]}

echo "==> query time range: $START_TIME .. $END_TIME" >&2

# JSON-escape quotes inside the query.
escaped=$(printf '%s' "$query" | sed 's/"/\\"/g')
Expand Down
60 changes: 60 additions & 0 deletions parseable/results/20260818/c6a.4xlarge.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"system": "Parseable (Parquet, partitioned)",
"date": "2026-08-18",
"machine": "c6a.4xlarge",
"cluster_size": 1,
"proprietary": "no",
"hardware": "cpu",
"tuned": "no",
"tags": ["Rust","column-oriented","lukewarm-cold-run"],
"load_time": 4931,
"data_size": 14023558981,
"concurrent_qps": 0.88,
"concurrent_error_ratio": 0,
"result": [
[0.477, 0.068, 0.065],
[0.321, 0.06, 0.059],
[0.79, 0.106, 0.118],
[1.036, 0.118, 0.112],
[1.148, 0.513, 0.509],
[1.569, 0.694, 0.72],
[0.313, 0.048, 0.042],
[0.353, 0.074, 0.076],
[1.626, 0.83, 0.861],
[2.234, 0.927, 0.954],
[1.317, 0.251, 0.242],
[1.35, 0.274, 0.276],
[1.66, 0.798, 0.795],
[3.182, 1.38, 1.373],
[1.651, 0.908, 0.946],
[1.324, 0.615, 0.673],
[3.065, 1.552, 1.539],
[2.96, 1.538, 1.536],
[5.412, 2.636, 2.649],
[0.672, 0.088, 0.09],
[9.009, 2, 1.995],
[10.67, 2.762, 2.698],
[15.419, 4.219, 4.185],
[13.271, 1.074, 0.873],
[3.111, 0.231, 0.255],
[1.422, 0.442, 0.428],
[3.458, 0.364, 0.324],
[9.095, 2.894, 2.867],
[9.497, 8.115, 8.389],
[0.872, 0.519, 0.5],
[3.284, 0.854, 0.884],
[6.862, 1.068, 1.086],
[5.168, 3.15, 3.153],
[9.669, 4.369, 4.466],
[9.658, 4.382, 4.402],
[1.489, 1.222, 1.184],
[0.584, 0.109, 0.114],
[0.514, 0.081, 0.071],
[0.541, 0.056, 0.057],
[0.703, 0.191, 0.189],
[0.492, 0.04, 0.038],
[0.482, 0.037, 0.035],
[0.476, 0.033, 0.031]
]
}