<feed xmlns='http://www.w3.org/2005/Atom'>
<title>pure/benchmarks/http/load.c, branch master</title>
<subtitle>Verified execution runtime unifying state, persistence, and replication.
</subtitle>
<id>http://git.yeowoo.org/pure/atom?h=master</id>
<link rel='self' href='http://git.yeowoo.org/pure/atom?h=master'/>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/'/>
<updated>2026-10-04T11:46:34Z</updated>
<entry>
<title>Take an app's requests only with a token its tokens file grants (017, 3b)</title>
<updated>2026-10-04T11:46:34Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-04T11:46:34Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=9fd2e16b68e1a83e2605e8a9cbd9b6d04a4da2f6'/>
<id>urn:sha1:9fd2e16b68e1a83e2605e8a9cbd9b6d04a4da2f6</id>
<content type='text'>
An app given a tokens file (tokens=FILE in --apps, --tokens FILE for the
one app of a host) answers a request only when it bears a token
(Authorization: Bearer) whose SHA-256 the file lists with a grant: read
for its views, queries and documents, write for all, input=NAME for
those inputs alone; 401 unauthorized (WWW-Authenticate: Bearer) without
one, 403 forbidden past its grant. A delivery sealed by a key --sender
names needs none. The digests are compared in constant time; a
connection keeps its last token's digest, so the same token is hashed
once. SHA-256 is the host's own (serve/sha256.c), no OpenSSL loaded. A
reading puts a changed tokens file in place with the app running on; a
file that is not one stops the app. pure-serve --make-token GRANT makes
a token and its line. load takes PURE_LOAD_TOKEN.
</content>
</entry>
<entry>
<title>Let the load tool put an app's name before its paths</title>
<updated>2026-10-01T02:23:27Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-10-01T02:23:27Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=a0840d6ebfcc6d992d60d119fb596cf76d54c7cc'/>
<id>urn:sha1:a0840d6ebfcc6d992d60d119fb596cf76d54c7cc</id>
<content type='text'>
load takes a ninth argument, PREFIX, put before every path: /NAME for
an app of a host of apps (pure-serve --apps, 017). Without it, as
before.
</content>
</entry>
<entry>
<title>Run pgbench's transaction on a bank of 100,000 accounts, beside SQLite (090)</title>
<updated>2026-09-27T22:39:29Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-27T22:39:29Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=44740eb93a69a052ee7b4c46f2ccac384c9d4f36'/>
<id>urn:sha1:44740eb93a69a052ee7b4c46f2ccac384c9d4f36</id>
<content type='text'>
benchmarks/bank/bank.aup keeps accounts, tellers and branches as keyed
lists and a history list; a transfer changes a row of each and appends a
history row in one event, as pgbench's TPC-B-like transaction does in
SQL. run.py makes a scale's rows and drives transfers through the load
generator's new transfer kind; sqlite-bank.c runs the same tables and
SQL on SQLite 3.46.1, a connection a thread, WAL.

With lists as trees, transfers run at 30.5k a second on 1,000 accounts
and 24.5k on 100,000 (RAM store, one connection thread, HTTP and JSON
included), where they ran at 3.2k on 30,000 before. Durable on the SD
card, Pure makes 1,339 a second and SQLite with synchronous=FULL 84 to
153. SQLite in process with no HTTP makes about 40k in RAM: recorded as
it is, with the write amplification of 100,000-row tables on the card
and ad hoc queries as what comes next.
</content>
</entry>
<entry>
<title>Read JSON bodies in place, groups included (082)</title>
<updated>2026-09-27T06:30:51Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-27T06:30:51Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=eb37aad3ae7f9df1d6c0b09108e3a2d69d0d4d82'/>
<id>urn:sha1:eb37aad3ae7f9df1d6c0b09108e3a2d69d0d4d82</id>
<content type='text'>
pure-serve no longer copies a JSON body's strings into the message's
payload. The ingress is the prefix, a table of each field's start and
size, and the body as it came; the connection thread scans the body
once, puts numbers into the prefix and records where each string is.
Only a string with escapes is unescaped, over itself (it never grows).
A group of fields comes as an object inside the body and, for a fixed
field, as its path in the query (?to.zip=7). A group where a field
belongs, a value where a group does, an array or true/false/null is
json_type; an unknown member, inside a group too, json_field.

The string scan and UTF-8 checks now pass over eight bytes at a time
while none needs a look (pure_utf8_step, so every text check gains).
On the Pi, posting {"name":"k","text":"x..."} to a stateless app went
from 652-655 to 3,737-3,953 requests/s with 256 KiB of text (server
CPU 1.52 to 0.25 ms a request, peak RSS 5.2 to 3.2-3.4 MiB) and from
29.1k to 76.3-76.7k/s with 4 KiB; the load generator gains a json
method and benchmarks/http/echo.aup is the app.

</content>
</entry>
<entry>
<title>Lend a text state's stored extents for its view (079)</title>
<updated>2026-09-26T20:54:49Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T20:54:49Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=d693cc750b75b2d862614b6f79f81a311f6294ca'/>
<id>urn:sha1:d693cc750b75b2d862614b6f79f81a311f6294ca</id>
<content type='text'>
A view that shows a text state as it is (pure_module_text_state) now goes
out as the state's stored extents, as a document read does: the answer
holds the store mapping, charged to the budget, until it is sent and its
ticket released; a state with edits not yet stored is copied as before.
Documents and views share one loan path, and the extent array grows as
needed. A 1 MiB note read by 8 connections: 776-817 answers a second
copied, 1,875-1,901 lent, p50 9.2 to 3.5 ms, peak RSS 10.3 to 5.7 MiB.
The load generator learns GET /views/page.

</content>
</entry>
<entry>
<title>Benchmark an app served by its views and inputs</title>
<updated>2026-09-26T15:56:08Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T15:56:08Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=768317d789a01d722fe7455d792fed11e6579b5c'/>
<id>urn:sha1:768317d789a01d722fe7455d792fed11e6579b5c</id>
<content type='text'>
run.py --suite app serves the scoreboard of scores.aup (22 lines of aup)
with pure-serve against the same scoreboard written by hand in axum and
drogon: POST /inputs/score?points=N with a name as the body, GET
/views/total and a page of 20 rows as JSON. Durable, the baselines append
each score to a log and fdatasync it before answering (replayed at
start); the load generator learns the three requests.

</content>
</entry>
<entry>
<title>Benchmark the HTTP hosts against axum</title>
<updated>2026-09-26T04:29:48Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T04:29:44Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=f0bec42645aa845d1c1d71c6e18ac1521e808fcc'/>
<id>urn:sha1:f0bec42645aa845d1c1d71c6e18ac1521e808fcc</id>
<content type='text'>
A C load generator, an axum service with the same document contract (in
memory, fdatasync, and crash-safe replacement), and a runner that pins the
servers and the load to separate CPUs. On the Pi 5, Pure uses about 40%
less memory, wins with a new connection per request and with eight durable
writers (3.2x the crash-safe axum), but loses 5x on keep-alive reads and
1.5x on 64 durable writers: no persistent connections, one thread, eight
connection slots and two fsyncs per commit. Note 075 records the numbers
and the targets.

</content>
</entry>
</feed>
