Zornux docs
Get started Spec

Tooling

Profiling

Zornux can profile a running program — where it spends time, what it allocates, the shape of its live data, and an ordered timeline of what it did — with no external, platform-specific tooling. Profiling is off by default: a normal run pays nothing for it, and you turn it on for a single run with zornux profile.

Getting started

bash
zornux profile run app.zx            # hot spots
zornux profile allocations app.zx    # allocations by type and function
zornux profile heap app.zx           # live data at program end
zornux profile timeline app.zx       # an ordered timeline

Every form runs your program normally — you still see its output — then prints a report.

Commands

CommandShows
profile runHot spots — where your program spends its time (tree-walking interpreter).
profile vm-runHot spots on the bytecode virtual machine.
profile allocationsWhat the program allocates, by type and function.
profile heapA snapshot of the live data at program end.
profile timelineAn ordered timeline of what ran.
profile serveProfile a live web server; report on shutdown.

What the report shows

Hot spots — the functions and methods your program spent the most time in, with how often each was called, how many execution samples landed in it, how many values it allocated, and its share of the total.

text
Hot spots
  Function/Method   Calls   Samples   Allocs   Percent   Source
  render            1200    842       3600     71.30     app.zx:44
  layout            1200    260       1200     22.01     app.zx:31
  • Hot source lines — the individual lines most samples landed on.
  • Allocations by type — how many numbers, text, lists, maps, and items were created. Reused values (small numbers, yes/no, nothing) are shared, so they never inflate the count.
  • Allocations by call stack — the same allocations, joined to the callers that made them, so you can trace one back through the chain that produced it rather than only learning which function it happened in. Add --allocation-stacks. The stack is bounded, and anything allocated outside a function belongs to the program itself.
  • Subsystems — how many async tasks, background jobs, messages, and database queries ran.
  • Heap — a snapshot of the live data still reachable at the end: live counts by type and item class, the largest lists and maps, and how deeply data is nested.

Tracing

A trace is an ordered, redacted stream of what your program did. Turn on the categories you care about:

bash
zornux profile run app.zx --trace calls      # function/method enter and exit
zornux profile run app.zx --trace jobs       # tasks, jobs, and message handlers
zornux profile run app.zx --trace queries    # database queries
zornux profile run app.zx --trace requests   # web requests
zornux profile run app.zx --trace all

Output and options

OptionDoes
--jsonMachine-readable JSON instead of a table.
--output <file>Write the report (or timeline) to a file.
--trace <kind>Capture a trace: calls, jobs, queries, requests, or all.
--max-samples <n>Cap on execution samples.
--max-events <n>Cap on timeline / trace events.
--sampling-interval <n>How much work passes between samples (smaller = finer).
--allocation-stacksRecord the call stack behind each allocation.
--timestampsStamp timeline events with elapsed microseconds.
--gc-statsReport memory-reclamation activity for the run.
bash
zornux profile run app.zx --json
zornux profile timeline app.zx --output run.timeline.json

Time and memory

Every timeline event carries a sequence number and a depth, and the sequence is what orders a timeline: it's a counter, so two runs of the same program produce the same order on every machine. --timestamps adds an elapsed time in microseconds beside it — read it to see how long something took, never to sort by, because a clock isn't deterministic and the sequence is.

--gc-stats reports how much memory reclamation the run provoked: reclamation passes and total bytes allocated. These are measured at the run's edges, so nothing is paused to collect them. They answer "did this run cause reclamation?", while allocations answer how many values the program itself made.

Profiling a live server

Profile a running web service and get a report when you stop it. Every request — the route and everything it calls, queries, or publishes — is profiled while the server runs.

bash
zornux profile serve app.zx          # serve; Ctrl+C prints the profile
zornux profile serve app.zx --trace requests --output serve.json

From an editor

An editor that speaks the Debug Adapter Protocol can profile a debug session through optional Zornux profiling requests — start a profile, then ask for the report, heap snapshot, timeline, or allocation summary. Editors that don't support them are unaffected; standard debugging is unchanged.

Safe by construction

A profile is names, counts, and source locations only — never a value. A secret is counted but never read, and a private field counts toward the live data but its contents are never shown. Counts and event order are deterministic; every stream is bounded and truncates rather than using unbounded memory; and with no profile requested, your program runs exactly as it would otherwise.