Performance

Pure C, static musl binaries, ~2MB RSS, <5ms startup, SIMD JSON parsing, double-buffered TUI, zero-copy streaming — performance by design, not afterthought.

<5ms Startup
~2MB RSS Memory
78 Static Binaries
850KB Avg Binary

Contents

Overview

scorpiox code is written in pure C11 and compiled to fully static musl binaries. Every performance decision is deliberate — from memory allocation patterns to I/O multiplexing to the choice of JSON parser. The result: a 78-binary toolchain where the average binary is 850KB and the entire system runs in ~2MB RSS.

There is no runtime, no garbage collector, no JIT compiler, no interpreter layer. The binary you ship is the binary that runs — statically linked against musl libc, OpenSSL, libcurl, nghttp2/3, brotli, zstd, c-ares, and libidn2.

libsxutil

Base Utilities

Zero external dependencies — config parsing, session management, conversation persistence, background tasks, metrics, JSON wrapper, TCP fetch, HTML stripping.

15 source files
libsxnet

Network Layer

Provider abstraction, HTTP with SSE streaming, agentic loop, MCP client, state management — supports 8 LLM providers through a unified C interface.

10 source files
libsxui

TUI Rendering

Double-buffered cell-based terminal rendering, input handling, file explorer, bash terminal — minimal ANSI escape output via dirty-cell diffing.

6 source files
yyjson

JSON Engine

Vendored yyjson — SIMD-accelerated C99 JSON parser. 3-10x faster than cJSON/jansson. In-situ parsing for zero-copy string access.

11,224 LOC

Binary Sizes

78 binaries, all statically linked with musl libc. No runtime dependencies — copy the binary, run it. The smallest is 32KB (scorpiox-otp), the largest is 4.2MB (scorpiox-server-email including full SMTP/IMAP stack).

Metric Value
Total binaries78
Smallest binaryscorpiox-otp — 32 KB
Largest binaryscorpiox-server-email — 4,200 KB
Average size850 KB
LinkingFully static (musl libc)
Runtime depsNone — zero .so files

Memory Management

No garbage collector. No reference counting runtime. Memory is managed through a combination of static allocation, fixed-size pools, and bounded buffers — every allocation has a known maximum, making the memory footprint completely predictable.

compile-time

Static Cell Buffers

Terminal rendering uses static SxCell front/back arrays allocated at compile time on WASM, avoiding heap fragmentation entirely.

SxCell[1024×512] front + back
sx_term.c
bounded

Fixed Task Pool

8 max concurrent background tasks with 64KB rolling output buffers each. Zero dynamic pool resize — the pool size is a compile-time constant.

SX_BGTASK_MAX=8, 64KB/task
libsxutil/sx_bgtask.h
safe

OOM-Safe Strdup

sx_strdup() aborts on allocation failure instead of returning NULL — prevents silent corruption propagating through the codebase.

abort() on OOM
libsxutil/sx_platform.h
O(1)

Doubling Buffers

HTTP response accumulation uses exponential growth (cap *= 2) — amortized O(1) append, minimizes realloc calls during streaming.

Initial alloc, double on overflow
libsxnet/sx_http.c
circular

Rolling Output Buffer

Per-task circular buffer — fixed 64KB window, oldest output discarded automatically. Bounded memory regardless of command output volume.

SX_BGTASK_OUTPUT_MAX=65536
libsxutil/sx_bgtask.h
zero-heap

Static Message Queue

8KB static char queue for inter-thread message passing. Zero heap allocation for enqueued agent messages and callbacks.

MAX_QUEUE_SIZE=8192
sx.c
O(1) access

Fixed Conversation Array

2000-slot fixed-size message array — no linked list overhead. O(1) index access with predictable memory footprint.

SX_CONV_MAX_MESSAGES=2000
libsxutil/sx_conversation.h
demand-paged

mmap Guest Memory

MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE for VM guest memory — demand-paged, zero-copy initialization, kernel manages physical backing.

Page-aligned, configurable RAM
scorpiox-vm.c

I/O Model

Poll-based multiplexing with streaming callbacks. No event loop framework — just poll(2)/select(2) with tight timeouts and callback-driven data forwarding.

Subsystem I/O Strategy
Command exec fork()+exec() with pipe, poll() at 100ms timeout for non-blocking output drain
PTY exec forkpty()-based — child sees real terminal, disables output buffering in Python/Ruby/etc
SSE streaming libcurl write_cb with real-time forwarding — on_data callback per chunk, zero buffering delay
Thunderbolt4 Busy-poll mode with 4MB write buffers for low-latency raw Ethernet I/O
MCP poll() with configurable timeout on stdio pipes to MCP server processes
// SSE streaming — tokens appear as they arrive size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) { SxHttpCtx *ctx = userdata; ctx->on_data(ptr, size * nmemb, ctx->user); // forward immediately return size * nmemb; }

JSON Performance

API request/response handling is JSON-heavy — every LLM API call serializes and parses large JSON payloads. scorpiox uses vendored yyjson, a SIMD-accelerated C99 parser that's 3-10x faster than cJSON or jansson.

yyjson Core

11,224 LOC vendored. SIMD-accelerated parsing, in-situ (zero-copy) strings, immutable + mutable document model. YYJSON_WRITE_ALLOW_INVALID_UNICODE for robustness with malformed API responses.

vendor/yyjson/yyjson.c

sx_json_yy Wrapper

Thin convenience layer — sx_yy_read(), sx_yy_write(), sx_yy_obj_add_raw() for Anthropic Messages API. No abstraction overhead.

libsxutil/sx_json_yy.c
zero-alloc

Streaming JSON Parser

sx_json_find_string_end_bounded() — operates on partial JSON buffers from SSE streams without full parse or allocation. Pure pointer arithmetic to find closing quotes in incomplete JSON fragments.

libsxnet/sx_json.c

TUI Rendering

Double-buffered cell-based rendering. Every character position on screen is a cell with foreground color, background color, and attributes. Each frame diffs the front buffer against the back buffer — only changed cells emit ANSI escape sequences.

// Cell comparison — skip unchanged cells static inline int cell_eq(SxCell *a, SxCell *b) { return a->ch == b->ch && a->fg == b->fg && a->bg == b->bg && a->attr == b->attr; }
FeatureDetail
Buffer sizeSX_TERM_MAX_WIDTH=1024 × MAX_HEIGHT=512 (~12 bytes/cell)
Output buffer1MB native / 64KB WASM — batched flush
Dirty checkingcell_eq() diff — O(dirty_cells) not O(total_cells)
Cursor optimizationSkip sequential positions — minimize escape sequences
Attribute dedupOnly emit changed fg/bg/attr per cell
WASM adaptationStatic pre-allocated cell arrays, reduced buffer sizes

Threading Model

Minimal threading — just enough to keep the UI responsive during API calls. Main thread handles input and rendering. Agent thread runs the agentic loop. A mutex protects the shared conversation array.

main

UI Thread

Input handling, display rendering, callback dispatch. Never blocks on network I/O.

sx.c — main()
pthread

Agent Thread

Dedicated pthread for API calls. Runs agentic loop — tool calls, retries, conversation building. Mutex protects chat array.

g_chat_mutex, CHAT_LOCK/UNLOCK
sx.c
pool

Background Tasks

PTY-based background command execution — 8 concurrent slots, per-task mutex, poll-based output collection.

SX_BGTASK_MAX=8
libsxutil/sx_bgtask.c
timer

Keep-Alive Timer

Separate thread for cache keep-alive. Only sets a flag — never touches provider directly. Main loop picks up the flag.

sx_cache_keepalive.c
C# FFI

DLL Event Queue

Thread-safe linked-list event queue for C# P/Invoke — mutex-protected push/pop, non-blocking sx_recv().

sx_dll.c
WASM

Single-Thread Adaptation

sx_thread_wasm.h provides pthread stubs — agent runs synchronously. JSPI suspends C stack during async fetch.

libsxutil/sx_thread_wasm.h

Compile-Time Optimizations

C11 standard, -O2 optimization, security hardening flags that add negligible runtime cost. Cross-compilation to 7 platform targets from a single codebase.

Security Hardening

-fstack-protector-strong # Stack canaries -D_FORTIFY_SOURCE=2 # Buffer overflow detection -Wl,-z,noexecstack # NX stack -Wl,-z,relro,-z,now # Full RELRO -fcf-protection # CFI (GCC x86/x86_64)

Static Linking per Platform

PlatformStatic Dependencies
Linuxmusl libc + curl + OpenSSL + nghttp2 + nghttp3 + brotli + zstd + c-ares + libidn2
WindowsMinGW static curl + OpenSSL + zstd + nghttp2/3 + brotli + libssh2
macOSMostly-static (system frameworks required)
AndroidStatic curl + mbedTLS
iOSStatic curl + mbedTLS
WASMEmscripten + JSPI, reduced buffers (256×64 cells, 64KB output)

Cross-Compilation Targets

x86_64 Linux (musl) aarch64 Linux (cross-gcc) macOS (Apple Silicon + Intel) Windows (MinGW-w64) Android (NDK) iOS (Xcode) WASM (Emscripten + JSPI)

Benchmarks vs Alternatives

Comparison against common runtime environments for AI coding assistants. All measurements are approximate — the point is order-of-magnitude differences, not micro-benchmarks.

Memory Usage (RSS)

scorpiox (C)
~2MB
Go binary
~20MB
Python
~30MB
Node.js
~200MB
Electron
~200MB+

Startup Time

scorpiox (C)
<5ms
Go binary
~20ms
Node.js
~250ms
Python
~500ms

Binary Size (average)

scorpiox (C)
~850KB
Rust
~4MB
Go
~8MB

Head-to-Head

vsAdvantage
Node.js100x less memory (~2MB vs 200MB+), 50x faster startup, no GC pauses
Python50x less memory, instant startup, no interpreter overhead, no pip/venv
Go10x smaller binary (~850KB vs 8MB+), similar speed, no goroutine scheduler
RustSimilar performance, faster compile times, simpler FFI for C# P/Invoke
Electron1000x less memory, 100x faster startup, zero Chromium overhead

Platform Abstraction

Single C codebase compiles to 7 platforms via preprocessor guards and build-time source selection. Each abstraction layer swaps the implementation at compile time — zero runtime dispatch overhead.

LayerScope
sx_platform.hPath separators, temp dirs, exe discovery, CA bundle, sx_fopen CLOEXEC
sx_http.hHTTP — libcurl (native) vs Emscripten Fetch (WASM)
sx_pty.hPTY — forkpty (Unix) vs ConPTY (Windows) vs stub (WASM)
sx_thread_wasm.hThreading — pthreads (native) vs synchronous stubs (WASM)
sx_exec.hCommand execution — fork+exec (native) vs JS interop (WASM)
sx_term.hTerminal — POSIX termios (Unix) vs Console API (Windows) vs xterm.js (WASM)