Skip to content

Add Rayforce - #1375

Open
alexey-milovidov wants to merge 2 commits into
mainfrom
add-rayforce
Open

Add Rayforce#1375
alexey-milovidov wants to merge 2 commits into
mainfrom
add-rayforce

Conversation

@alexey-milovidov

@alexey-milovidov alexey-milovidov commented Aug 14, 2026

Copy link
Copy Markdown
Member

Adds Rayforce — a zero-dependency
columnar analytics and graph engine in pure C (MIT), queried through Rayfall,
its Lisp-like language. queries.sql therefore holds 43 Rayfall expressions,
one per line, the way jd and bqn hold their own dialects.

(Not the same as the closed #940 — that was RayforceDB's internal 10M-row
harness, opened against this repo by mistake. This is a standard-harness entry
on the full dataset.)

Two measured engine properties shaped the entry

Text columns load as SYM (dictionary-encoded), not STR. STR pool
offsets are uint32_t, so a column's pool is capped at 4 GiB, while at 100M
rows URL/Title/Referer/OriginalURL hold 5–11 GB of bytes each. Opening a
splayed table also validates every STR element, and that cost is superlinear:
0.4 s at 2M rows, 199 s at 9.6M rows (99 s for the parted layout). All-SYM
opens in 17 s at 9.6M rows and stores the same subset in 4.4 GB instead of
7.5 GB.

It runs as an IPC server, with BENCH_RESTARTABLE=yes. The table open is
eager (validate every column file, load the dictionary), so a CLI-per-query
would pay it 129 times per run; the server pays it once per start and times
queries with timeit server-side. The restart is not optional either: with the
server left up, drop_caches cannot evict pages a live process still maps, and
a "cold" query measured 0.029 s versus 0.44 s after a real restart — keeping the
process alive would report every run as warm. BENCH_CHECK_TIMEOUT is raised to
1800 s because the readiness probe now waits for that open.

Query notes

HAVING becomes an outer select over the grouped one; LIMIT n OFFSET m is
take: [m n]; DATE_TRUNC('minute', EventTime) is
(xbar EventTime 60000000000); CASE WHEN is the row-wise (if ...). Q29's
REGEXP_REPLACE is rebuilt from str-find/substr/if and reproduces the
regex exactly on this dataset, fallback rows included. Q25/Q27 project
EventTime alongside SearchPhrase because sorting runs after projection, and
Q35 projects its constant group key in an outer select.

Validation

All 43 queries were diffed against clickhouse-local on a 2M-row subset of the
same CSV: 33 match exactly or modulo row order, and the other 10 differ only in
which of several equally-ranked rows a LIMIT over ties returns (the sort-key
multisets are identical). install, load, the stop/drop_caches/start/check
cold cycle, all 43 queries through ./query, 10 concurrent clients, and the
error paths were exercised end to end.

Upstream bugs found on the way

Neither affects this entry, both filed with minimal repros:

🤖 Generated with Claude Code

Rayforce (https://github.com/RayforceDB/rayforce) is a zero-dependency
columnar analytics and graph engine in pure C, queried through Rayfall,
its Lisp-like language. queries.sql therefore holds 43 Rayfall
expressions, one per line, the way jd/bqn hold their own dialects.
(Not to be confused with the closed #940, which was RayforceDB's
internal 10M-row harness opened against this repo by mistake.)

Two measured engine properties shaped the entry:

  - Text columns are loaded as SYM (dictionary-encoded), not STR. STR
    pool offsets are uint32_t, so a column's pool is capped at 4 GiB,
    and at 100M rows URL/Title/Referer/OriginalURL need 5-11 GB each.
    Opening a splayed table also validates every STR element, and that
    cost is superlinear: 0.4 s at 2M rows, 199 s at 9.6M rows (99 s for
    the parted layout). All-SYM opens in 17 s at 9.6M rows and stores
    the same subset in 4.4 GB instead of 7.5 GB.

  - It runs as an IPC server, with BENCH_RESTARTABLE=yes. Opening the
    table is eager (validate every column file, load the dictionary),
    so a CLI-per-query would pay that 129 times per run; the server
    pays it once per start and times queries with `timeit` server-side.
    The restart is not optional either: with the server left up,
    drop_caches cannot evict pages a live process still maps, and a
    "cold" query measured 0.029 s against 0.44 s after a real restart,
    so keeping the process alive would report every run as warm.
    BENCH_CHECK_TIMEOUT is raised to 1800 s because the readiness probe
    now waits for that table open.

Query notes: HAVING becomes an outer select over the grouped one;
LIMIT/OFFSET is take: [m n]; DATE_TRUNC('minute', EventTime) is
(xbar EventTime 60000000000); CASE WHEN is the row-wise (if ...);
Q29's REGEXP_REPLACE is rebuilt from str-find/substr/if and reproduces
the regex exactly on this dataset, fallback rows included. Q25/Q27
project EventTime alongside SearchPhrase because sorting runs after
projection, and Q35 projects the constant group key in an outer select.

All 43 queries were checked against clickhouse-local on a 2M-row subset
of the same CSV: 33 match exactly or modulo row order, and the other 10
differ only in which of several equally-ranked rows a LIMIT over ties
returns (the sort-key multisets are identical). install, load, the
stop/drop_caches/start/check cold cycle, 43 queries through ./query, 10
concurrent clients and the error paths were all exercised end to end.

Two upstream bugs found on the way, neither affecting this entry:
RayforceDB/rayforce#404 (take: drops pool-backed STR values) and
RayforceDB/rayforce#405 (ungrouped count(distinct) in a select
projection returns the row count).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@alexey-milovidov
alexey-milovidov deployed to benchmark-approval August 14, 2026 19:37 — with GitHub Actions Active
@github-actions

Copy link
Copy Markdown
Contributor

Results for rayforce are ready for: c6a.4xlarge.
The result files are committed as 74e151f.

Logs:

@alexey-milovidov alexey-milovidov added the machine:all PR benchmark on every machine type label Aug 15, 2026
@alexey-milovidov
alexey-milovidov deployed to benchmark-approval August 15, 2026 16:01 — with GitHub Actions Active
@github-actions

Copy link
Copy Markdown
Contributor

The run of rayforce on c6a.xlarge did not produce results.

Logs:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

machine:all PR benchmark on every machine type

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant