Skip to content
Merged
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: 4 additions & 9 deletions apps/web/app/benchmark.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useInView } from "./reveal";
type Row = {
label: string;
bytes: number;
kind?: "baseline" | "generic" | "binary" | "hyperfly" | "profile" | "full";
kind?: "baseline" | "generic" | "binary" | "hyperfly" | "full";
};

type Payload = {
Expand All @@ -26,10 +26,9 @@ const PAYLOADS: Payload[] = [
{ label: "JSON + Brotli — edge q4", bytes: 2512, kind: "generic" },
{ label: "Protobuf", bytes: 7190, kind: "binary" },
{ label: "Hyperfly", bytes: 2013, kind: "hyperfly" },
{ label: "Hyperfly + Brotli", bytes: 1974, kind: "profile" },
{ label: "Hyperfly Profiled", bytes: 574, kind: "full" },
],
note: "An audit log repeats itself across requests, not within one — the same actors, the same user agents, request after request — and its ids are machine-made: evt_, a sequence number, eight hex digits. The profile learns the recurring values as a dictionary, the id shape as a grammar whose lanes ship the sequence as deltas and the hex at four bits a digit, and actorEmail as a function of actorId, which then costs nothing at all. Brotli takes 39 bytes off this route; the profile takes 1 439. Adding Brotli on top of the profiled stream makes it four bytes larger — at this density there is nothing left for it to find.",
note: "An audit log repeats itself across requests, not within one — the same actors, the same user agents, request after request — and its ids are machine-made: evt_, a sequence number, eight hex digits. The profile learns the recurring values as a dictionary, the id shape as a grammar whose lanes ship the sequence as deltas and the hex at four bits a digit, and actorEmail as a function of actorId, which then costs nothing at all. The profile takes 1 439 bytes off this route.",
},
{
route: "GET /v1/devices",
Expand All @@ -40,7 +39,6 @@ const PAYLOADS: Payload[] = [
{ label: "JSON + Brotli — edge q4", bytes: 1422, kind: "generic" },
{ label: "Protobuf", bytes: 2007, kind: "binary" },
{ label: "Hyperfly", bytes: 755, kind: "hyperfly" },
{ label: "Hyperfly + Brotli", bytes: 725, kind: "profile" },
{ label: "Hyperfly Profiled", bytes: 542, kind: "full" },
],
note: "An enum with six members is three bits, not a string and not a byte. Integers ship bit-packed against the narrowest frame the column needs, outliers pay for themselves alone, and booleans pack into bitmaps — that is the first row, before anything has been learned. The profile then learns the fleet: the device ids that recur on every page.",
Expand All @@ -54,10 +52,9 @@ const PAYLOADS: Payload[] = [
{ label: "JSON + Brotli — edge q4", bytes: 408, kind: "generic" },
{ label: "Protobuf", bytes: 388, kind: "binary" },
{ label: "Hyperfly", bytes: 271, kind: "hyperfly" },
{ label: "Hyperfly + Brotli", bytes: 273, kind: "profile" },
{ label: "Hyperfly Profiled", bytes: 180, kind: "full" },
],
note: "The single-entity response, and the case a general compressor handles worst: under a kilobyte there is nothing yet to build a window from. Brotli actually costs two bytes here rather than saving any — at this size its framing outweighs what it finds. What does work is knowing the catalogue in advance.",
note: "The single-entity response, and the case a general compressor handles worst: under a kilobyte there is nothing yet to build a window from. What does work is knowing the catalogue in advance.",
},
{
route: "GET /v1/feed",
Expand All @@ -68,7 +65,6 @@ const PAYLOADS: Payload[] = [
{ label: "JSON + Brotli — edge q4", bytes: 2294, kind: "generic" },
{ label: "Protobuf", bytes: 4396, kind: "binary" },
{ label: "Hyperfly", bytes: 1871, kind: "hyperfly" },
{ label: "Hyperfly + Brotli", bytes: 1868, kind: "profile" },
{ label: "Hyperfly Profiled", bytes: 1466, kind: "full" },
],
note: "Prose is the hard case: the bodies are genuinely new every time and nothing can invent redundancy that is not there. What does recur are the authors, so that is what the profile takes. This is the narrowest margin on the page, and it is the honest one to look at first.",
Expand All @@ -82,10 +78,9 @@ const PAYLOADS: Payload[] = [
{ label: "JSON + Brotli — edge q4", bytes: 842, kind: "generic" },
{ label: "Protobuf", bytes: 2034, kind: "binary" },
{ label: "Hyperfly", bytes: 384, kind: "hyperfly" },
{ label: "Hyperfly + Brotli", bytes: 362, kind: "profile" },
{ label: "Hyperfly Profiled", bytes: 384, kind: "full" },
],
note: "Timestamps arrive at a constant stride, so the differences between them are identical and pack to a width of zero bits — the column carries its first value and nothing else. Exact-decimal prices travel as integer mantissas bit-packed to the span actually present. The profiled row matches the base row exactly, and is left in to show it: this route's only string sits outside the array, so training buys nothing at all — here the honest win still belongs to Brotli's 22 bytes.",
note: "Timestamps arrive at a constant stride, so the differences between them are identical and pack to a width of zero bits — the column carries its first value and nothing else. Exact-decimal prices travel as integer mantissas bit-packed to the span actually present. The profiled row matches the base row exactly, and is left in to show it: this route's only string sits outside the array, so training buys nothing at all.",
},
];

Expand Down
6 changes: 0 additions & 6 deletions apps/web/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -517,17 +517,12 @@ h3 {
background: rgba(95, 217, 255, 0.26);
}

.bar[data-kind="profile"] .bar-fill {
background: rgba(95, 217, 255, 0.55);
}

.bar[data-kind="full"] .bar-fill {
background: rgba(95, 217, 255, 0.85);
box-shadow: 0 0 26px rgba(95, 217, 255, 0.3);
}

.bar[data-kind="hyperfly"] .bar-label,
.bar[data-kind="profile"] .bar-label,
.bar[data-kind="full"] .bar-label {
color: var(--text);
}
Expand All @@ -549,7 +544,6 @@ h3 {
}

.bar[data-kind="hyperfly"] .bar-ratio,
.bar[data-kind="profile"] .bar-ratio,
.bar[data-kind="full"] .bar-ratio {
color: var(--accent);
}
Expand Down
4 changes: 2 additions & 2 deletions apps/web/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ export default function Home() {
<p className="footnote">
Bytes per message, averaged over 500 independent responses per route, measured
with the TypeScript reference implementation — reproduce with `bun run bench`. Each
Hyperfly row adds exactly one thing: schema-compiled layout, then generic
compression on top of it, then a dictionary trained on the route&apos;s own traffic.
Hyperfly row adds exactly one thing: schema-compiled layout, then a dictionary
trained on the route&apos;s own traffic.
That dictionary is an out-of-band artifact; the repo reports its size and how many
requests it takes to pay for itself — ten for events, thirty-five for orders. The
Brotli rows are q4, the level edges actually run on dynamic responses. Protobuf
Expand Down
Loading