{"about":"The API behind perf.julialang.org: Julia's CI timing, Nanosoldier benchmarks, PkgEval, TTFX, package downloads and Buildkite agents, from one SQLite database refreshed every half hour. All routes are GET and answer JSON, gzipped when asked (curl --compressed), with an ETag for revalidation. It is the site's own interface, so shapes can change; the database schema is the stable reference.","guide":"https://perf.julialang.org/llms.txt","sql":"https://perf.julialang.org/db/ (Datasette, read-only SQL; 2 s and 5000 rows per query)","snapshot":"https://perf.julialang.org/data/ci-timing.sqlite.gz (the whole database, taken once a week, about 220 MB)","schema":"https://github.com/JuliaCI/julia-ci-timing/blob/main/db/schema.sql","health":"https://perf.julialang.org/healthz","routes":[{"path":"/api/status","params":{},"description":"The global change sequence, each source's sequence (the ETag of its routes, which moves when an ingest changes its rows), when each source's last successful ingest finished, and the server's time. Never cached, so it is the cheap thing to poll."},{"path":"/api/ready","params":{},"description":"Whether this server has finished warming up: 200 once the routes the site loads on landing are rendered into its cache, 503 before. A deploy starts the new server beside the old one and switches to it when this answers 200."},{"path":"/api/timing/runs","params":{"since":"start of the window: YYYY-MM-DD, or YYYY-MM-DDTHH:MM:SSZ. Omitted means all history, so pass it.","until":"end of the window (exclusive), same forms as since","changed_since":"a change_seq from an earlier response: only the builds changed since then, for an incremental refresh"},"description":"CI job runs by job name, newest first, plus a map of their builds (commit, author, message, date) and coverage per commit. The window is on the build's creation time; 30 days is about 0.2 MB gzipped."},{"path":"/api/timing/builds","params":{"since":"start of the window: YYYY-MM-DD, or YYYY-MM-DDTHH:MM:SSZ. Omitted means all history, so pass it."},"description":"Master builds newest first: state, wall time, job count and time, and the queue wait of their jobs (median, max, total). Builds before September 2026 have no timestamps and are left out."},{"path":"/api/benchmarks/summary","params":{"metric":"time (default), gctime, memory or allocs"},"description":"Geometric mean of every Nanosoldier benchmark group on every daily report, and the reports' dates and commits."},{"path":"/api/benchmarks/groups/<group>","params":{"since":"start of the window: YYYY-MM-DD, or YYYY-MM-DDTHH:MM:SSZ. Omitted means all history, so pass it.","metric":"time (default), gctime, memory or allocs"},"description":"Every benchmark of one group on every daily report in the window, for the minimum and mean estimates. The group names are the keys of benchmarks/summary."},{"path":"/api/benchmarks/verdicts","params":{"since":"start of the window: YYYY-MM-DD, or YYYY-MM-DDTHH:MM:SSZ. Omitted means all history, so pass it."},"description":"Nanosoldier's own regressions and improvements on each daily report: benchmark, time and memory ratios and tolerances."},{"path":"/api/pkgeval/summary","params":{},"description":"PkgEval daily reports: date, Julia version, commit and the counts of ok, fail, crash, skip and kill."},{"path":"/api/pkgeval/packages","params":{"q":"a name prefix, case-insensitive"},"description":"Up to 25 package names starting with q, for looking a package up."},{"path":"/api/pkgeval/package/<name>","params":{},"description":"One package's status, reason, version and test duration on every daily report with package results."},{"path":"/api/pkgeval/reasons","params":{"path":"a report as YYYY-MM/DD; the newest by default"},"description":"How many packages failed each way (status and reason) on one report."},{"path":"/api/pkgeval/popular","params":{"days":"download window in days, 30 by default","client":"whose downloads rank the packages: user (default), ci or all","limit":"packages to list, 50 by default, at most 500"},"description":"The most downloaded packages not passing the newest report, with their download rank, reason and how long each has been failing; the download-weighted pass rate; the packages newly broken since the report before."},{"path":"/api/ttfx/summary","params":{"since":"start of the window: YYYY-MM-DD, or YYYY-MM-DDTHH:MM:SSZ. Omitted means all history, so pass it."},"description":"TTFX on every master build: per task, the precompile, load, run and warm seconds (and load, run and warm with the GC off), plus failed tasks. releases holds the same for the weekly runs of the newest stable release on the same tasks and machines, each with the release's version and commit, as a reference."},{"path":"/api/ttfx/prs","params":{},"description":"Open julia pull requests ranked by their latest TTFX comparison (head against the master build of the merge-base), best first: the job's verdict and robust improvements and regressions, the suite geomean ratio per metric and block, and the flagged tasks. score is the estimated ratio of the suite's total time: the precompile, load, run and warm ratios weighted by each metric's time on master, taking per metric the block nearest no change (1 when the blocks disagree); below 1 is faster. outdated means the pull request has moved on since the job's commit. stack is null unless the pull request targets another one's branch: then the job measured it against that branch, own_score is that comparison, and score and stack.suite estimate the whole stack against master by multiplying in the suite geomeans of the pull requests below it (stack.parents, nearest first; complete false when one has no comparison, which leaves score null; exact false when a lower one has moved on since this job's base). ci is the state of the newest julia-pr build of the pull request's current head (null until looked up, state none when it has no build)."},{"path":"/api/sizes/summary","params":{"since":"start of the window: YYYY-MM-DD, or YYYY-MM-DDTHH:MM:SSZ. Omitted means all history, so pass it.","metrics":"comma-separated metric names (the summary set by default, all for every one)","source":"ci or manyjulias for that source alone"},"description":"Size of the unpacked linux-x86_64 distribution of master commits: the commits in merge order with their merge time, version, julia-ci build, subject and source, and one array per metric aligned with them, in bytes (files and pkgimg.count are counts). metrics lists every metric there is. The sizes are of the tarball CI built from the first commit measured that way (the nightlies bucket keeps them about 60 days), and of manyjulias builds of master back to 2020 before it; markers has that switch, where the series steps because the manyjulias builds have fewer CPU targets."},{"path":"/api/sizes/commit/<sha>","params":{},"description":"One commit's size measurement in each source next to the previous commit that source measured: every metric, and every file of at least 1 MiB in either, the files that changed most first."},{"path":"/api/sizes/prs","params":{},"description":"Every open julia pull request with a measured julia-pr build, newest build first: the pull request, its build and head commit, its merge-base with master, base (the merge-base's measurement as a master commit, null until its julia-ci build job has finished and it is measured), and values and base_values, the summary metrics of the head and the base in bytes. The tarball is left out: julia-pr builds compress theirs differently."},{"path":"/api/sizes/pr/<number>","params":{},"description":"One open pull request's measurement next to its merge-base's: every metric, and every file of at least 1 MiB in either, the files that changed most first."},{"path":"/api/downloads/summary","params":{},"description":"Package server requests per day (total, user, CI), by Julia version and release stage, with Julia release tags."},{"path":"/api/downloads/packages","params":{"q":"a name prefix, case-insensitive"},"description":"Up to 25 General registry package names starting with q."},{"path":"/api/downloads/package/<name>","params":{},"description":"One registered package's successful requests per day, user and CI."},{"path":"/api/downloads/top","params":{"days":"window in days, 7 by default","client":"whose downloads rank the packages: user (default), ci or all"},"description":"The 50 most requested packages over the window."},{"path":"/api/agents/latest","params":{},"description":"Every Buildkite agent seen in the last year: host, queue, OS, state, first and last seen, and its job if it has one now."},{"path":"/api/agents/snapshots","params":{"since":"start of the window: YYYY-MM-DD, or YYYY-MM-DDTHH:MM:SSZ. Omitted means all history, so pass it."},"description":"The connected agents at every ingest, as a list of snapshots."},{"path":"/api/agents/backlog","params":{"since":"start of the window: YYYY-MM-DD, or YYYY-MM-DDTHH:MM:SSZ. Omitted means all history, so pass it."},"description":"Per agent pool (queue, os, arch): how many julia-pr and julia-ci jobs were waiting for an agent and how many were running, sampled every step_s seconds from start (the jobs are kept for 60 days), with the longest current wait in seconds at each sample, the agent slots seen for the pool in the last 30 days (capped per host at the most jobs the host was seen running at once), its hosts, and shared_with, the other pools that draw on the same hosts' slots; host_slots has the most jobs each host was seen running at once; by_pipeline has the same series for julia-ci (master) and julia-pr (pull requests) jobs separately."},{"path":"/api/agents/usage","params":{"days":"window in days before the latest agents snapshot, 7 by default, at most 60 (the jobs are kept for 60 days)"},"description":"Agent time spent on julia-pr and julia-ci jobs that finished in the window, from start to finish: seconds and job count per pipeline, job name, pool (queue, os, arch) and final state, busiest first. Jobs still running are left out."},{"path":"/api/commits","params":{"before":"the first_at of the last commit already listed, to page back","limit":"commits per page, 100 by default, at most 500"},"description":"Master commits newest first, one row per commit: first build time, latest build state, author, subject, and whether a daily benchmark or PkgEval report ran on it."},{"path":"/api/commit/<ref>","params":{},"description":"Everything recorded for one master commit: its builds, each job's time and state against the previous commit's build, TTFX against the previous run, the first benchmark and PkgEval daily reports that include it, and coverage. ref is a SHA prefix of 7 to 40 hex digits or a PR number; a ref matching several commits returns them under matches."}]}