rkat-rpc download. This page is for
everyone else: people who run cargo install rkat, embed the crates in their
own binary, build inside a container, or need to know where the prebuilt
binaries will and will not run. Every number below was measured against this
repository; the memory and time figures come from one cold build described in
Build Cost.
What A Build Compiles
The workspace has ~50 member crates. Its lockfile resolves ~670 package entries (~600 distinct crates) for the whole workspace with every feature, dev-dependency, and optional backend enabled. A default-featurecargo install rkat compiles ~380 crates.
Most of those are ordinary. The cost is concentrated in a few very large
first-party crates, each of which is one rustc and LLVM invocation:
These four, plus the final
rkat crate that pulls the whole surface into one
binary, dominate both wall time and peak memory, which is why the release lane
and the rest of this page talk about per-package opt-level pins rather than
about the dependency count.
Toolchain and native requirements:
- The repository pins Rust
1.94.1inrust-toolchain.toml;make install-build-depsinstalls exactly that toolchain into a checkout. The published crates declarerust-version = "1.94.0", socargo install rkatneeds Rust 1.94 or newer. - The default feature set needs a C compiler and libc headers (bundled SQLite
and a few other C sources compile through the
cccrate) and nothing else. TLS isrustls; no OpenSSL development package is required and the release gate rejects binaries that link one. cmakeis needed only by the optionallive-webrtcfeature of themeerkatfacade andmeerkat-rpccrates (meerkat-livewebrtc, bundled Opus throughaudiopus_sys).rkathas no such feature, and no shipped binary enables it by default, so acargo installof any of them never compiles it.
Build Cost
Two cold builds, measured for this page:opt-level = 1 globally,
opt-level = 0 for meerkat-machine-schema), with the same job count so the
per-crate peaks are comparable. Peaks were sampled once per second from ps.
How to translate that to your host:
- The largest single crate is the floor, and only
opt-level = 0moves it. Even withCARGO_BUILD_JOBS=1, the build needs as much memory as its biggestrustcprocess. In both runs above that wasmeerkat-mobat ~11 GiB: going fromopt-level = 3to1halved the aggregate peak, therkatcrate, andmeerkat-machine-schema, but leftmeerkat-mobwhere it was. A third run (the samerkatbuild with the low-memory profile plusmeerkat-mobpinned toopt-level = 0) broughtmeerkat-mobdown to ~6.3 GiB, after which the largest process ismeerkat-runtimeat ~7.4 GiB. Below that, the levers are the feature set (droppingmobremoves the crate), swap, and the prebuilt binaries. - Aggregate memory scales with the job count. Cargo runs up to one
rustcper core. The aggregate peaks above happened while four or five large first-party crates were compiling at once; withNjobs, budget for theNlargest crates that can be in flight together.meerkat-mob,meerkat-runtime, andmeerkat-machine-schemadid overlap in the default build, and that overlap produced its peak. - Wall time scales with cores only up to the serial tail. The hundreds of
small dependencies compile in parallel in the first few minutes, but the
large first-party crates depend on each other, and the final
rkatcrate compiled alone for roughly the last third of the wall time. A 4-core cloud VM should expect a few times the wall time above, and the tail does not shrink with more cores.cargo installalso has no warm cache to reuse, so every install is a cold build. - Disk is transient for
cargo install. The temporary target directory is deleted after the binary is installed, but it must fit while the build runs. A checkout that keeps itstarget/needs the full figure per profile.
.github/workflows/release.yml: the Windows release lane runs on a 16 GB
GitHub-hosted runner with no memory overcommit, and it documents rustc
exceeding that runner’s commit limit on the generated machine catalog. That
lane therefore builds with CARGO_BUILD_JOBS=2 and pins
meerkat-machine-schema to opt-level = 0 and meerkat-runtime and
meerkat-mcp to opt-level = 1. The Linux and macOS release binaries keep
full opt-level = 3; the pins are Windows-only. Continuous integration
(.github/workflows/ci.yml) compiles its broad lane on BuildBuddy remote
executors, with only the dense Mob topology job and the nightly lanes on
GitHub-hosted runners; release binaries are produced only by the release
workflow.
Rough sizing, derived from the peaks above:
Lowering Memory
Where profile settings come from
Cargo reads[profile.*] tables only from the root manifest of the build it
is running. Two consequences matter here:
- The Meerkat workspace ships no
[profile.release], so its own release builds run at Cargo’s defaults (opt-level = 3,codegen-units = 16,lto = false,debug = false) except where a lane injects pins. - Even if it did, that would not reach you.
cargo install rkatunpacks the publishedrkatcrate as the root of its own temporary workspace; the repository’s rootCargo.tomlis not part of that crate. A downstream binary that depends onmeerkat = "=0.8.32"is likewise governed by its own root manifest, never by Meerkat’s.
cargo install honors Cargo configuration
from a .cargo/config.toml in the directory you run it from (or
~/.cargo/config.toml), from CARGO_PROFILE_RELEASE_* environment variables,
and from --config on the command line. This was verified for this page with
cargo install -v: with CARGO_PROFILE_RELEASE_OPT_LEVEL=1 set, rustc
receives -C opt-level=1. Library embedders put the same tables in their own
root Cargo.toml.
Low-memory profile
meerkat-mob (~11.5 GiB at opt-level = 1, ~6.3 GiB
at 0); it trades CPU on the orchestration path for memory, so measure your
workload before shipping a binary built this way:
opt-level line and keep:
--config; repeat the flag with
profile.release.package.meerkat-mob.opt-level=0 for the small-host pin.
What each lever does
CARGO_BUILD_JOBS(or-j) caps the number of concurrentrustcprocesses. Aggregate memory is the sum of the compilers running at once, so this is the first lever on any memory-limited host. Wall time rises roughly in proportion.opt-level: going from3to1removes most of LLVM’s expensive passes. Measured on the crates whose peak is in LLVM, it halved therkatcrate (~10.1 to ~4.8 GiB) and, together with theopt-level = 0pin,meerkat-machine-schema(~9.4 to ~4.8 GiB), and it cut the whole build’s wall time from ~25 min 29 s to ~19 min 6 s. It did not movemeerkat-mob; onlyopt-level = 0did (~11.5 to ~6.3 GiB). The runtime cost of1is modest for an agent host that spends its time waiting on network I/O.opt-level = 0is free formeerkat-machine-schemabecause it is a generated catalog, not hot code; onmeerkat-mobit is a real trade.codegen-units: LLVM optimizes a crate’s codegen units in parallel, bounded by your core count, so a crate split into 16 units can hold 16 LLVM contexts at once. Lowering it reduces that per-crate parallelism at the cost of a longer compile for that crate, andcodegen-units = 1also widens inlining scope, which can raise memory for the largest crates. Measure on your host before changing it; the release lane leaves it at 16.lto: leave it at the defaultfalse."thin"or"fat"LTO pulls the whole dependency graph into one optimization pass at link time and multiplies link-stage memory.- Features:
meerkat-cli/Cargo.tomllists the subsystems behindrkat’s default features (mob,rpc-surface,openai-realtime,comms,schedule,workgraph,mcp,skills, storage backends, providers). A narrower--no-default-features --features ...build compiles fewer crates; droppingmobremovesmeerkat-mob, the crate that sets the memory floor above, along withmeerkat-mob-mcpandmeerkat-mob-pack. The repository’s surface feature matrix (scripts/run-surface-feature-matrix, behindmake test-feature-matrix-surface) keeps three reducedrkatcombinations compiling:--no-default-features --features session-store,session-store,mcp, andsession-store,comms,mcp,workgraph. Other subsets are not exercised, so check that yours builds before relying on it. Reduced builds are source builds only; no reduced binaries are published (see the note under Homebrew Tap).
Containerizing The Binaries
A Rust binary built for a*-unknown-linux-gnu target links the builder’s
glibc dynamically and records the newest glibc symbol version it used. The
runtime image must provide a glibc at least that new, or the loader refuses to
start the binary with version 'GLIBC_2.xx' not found. The reliable way to
get that right in a two-stage image is to pin one Debian release for both
stages, so the builder’s glibc is the runtime’s glibc:
ARG DEBIAN_RELEASEis declared before the firstFROMand used in bothFROMlines, so the two stages cannot drift apart when someone bumps one of them.rust:1.94-bookwormmatches the pinned toolchain family.--lockedbuilds with theCargo.lockshipped inside therkatcrate, so the container compiles the dependency set the release was tested with.- To build from a checkout instead of crates.io (unreleased commits, local
patches), replace the
RUN cargo installline withWORKDIR /src,COPY . ., andcargo build --locked -p rkat --release, and copy/src/target/release/rkat(the build stage above sets noWORKDIR, so without that line the checkout lands in/). The repository’s ownexamples/035-mdm-tux-rs/Dockerfiledoes exactly that for the example’s binaries, with the samerust:1.94-bookwormbuild stage anddebian:bookworm-slimruntime stage. - The companion surfaces are separate crates with the same shape:
cargo install meerkat-rpc(binaryrkat-rpc),meerkat-rest(rkat-rest), andmeerkat-mcp-server(rkat-mcp). rkatresolves project realm state under.rkat/in its working directory and the global realm’s config under~/.rkat/(see Configuration); mount a volume at/data, and pointHOMEat persisted storage if the global realm matters, so state outlives the container.
debian:bookworm-slim ships glibc 2.36, above
the 2.31 floor the release binaries are built against (next section):
checksums.sha256 (and, if you use
the GitHub CLI, its build provenance attestation; see below) before trusting it
in production.
Not covered by the prebuilt binaries: Alpine and other musl-based images. No
musl target is published, and the glibc binaries are not tested under
gcompat. Build from source on such a base or use a Debian-family image.
Where The Prebuilt Binaries Come From
.github/workflows/release.yml builds and publishes the release assets when a
v* tag is pushed. Each of the four binaries (rkat, rkat-rpc, rkat-rest,
rkat-mcp) is packaged per target as <binary>-<version>-<target>.tar.gz
(.zip on Windows), alongside checksums.sha256 and index.json. The
Homebrew tap and the
SDK bootstrap consume these same
assets. Targets:
x86_64-unknown-linux-gnuaarch64-unknown-linux-gnuaarch64-apple-darwinx86_64-apple-darwinx86_64-pc-windows-msvc
actions/attest-build-provenance), which binds the file’s digest to the
workflow run and commit that produced it:
Linux glibc floor
The Linux GNU binaries are built inside thebuildpack-deps:bullseye image
(Debian 11, glibc 2.31) on both release lanes: the BuildBuddy lane pins that
image as the execution container in platforms/BUILD.bazel, and the
GitHub-hosted lane runs its Linux jobs under the same container:, because
building directly on the Ubuntu 24.04 runner (glibc 2.39) would silently raise
the floor. Packaging then runs
scripts/check-linux-release-binary-portability.sh on every Linux binary and
fails the release if either check trips:
- Any versioned glibc symbol reference is newer than the declared floor
(
MEERKAT_GLIBC_FLOOR=2.31). - The binary has a dynamic
NEEDEDentry onlibsslorlibcrypto. All first-party TLS isrustls, so an OpenSSL dependency means a crate regressed into a native-TLS stack.
GLIBC_2.34 that
Debian 11 could not load; the floor is enforced on the produced file, not
assumed from the build image.
What that guarantees: a published Linux binary starts on any x86_64 or aarch64
distribution whose glibc is 2.31 or newer (Debian 11 and later, Ubuntu 20.04
and later, Debian-based container images from bullseye onward) and needs no
OpenSSL runtime package. What it does not guarantee: musl-based systems (see
above), or distributions older than glibc 2.31.
Other platforms
The macOS binaries carry no notarization and the release workflow asserts no minimum macOS version (there is no deployment-target pin or gate); the GitHub-hosted lane ad-hoc codesigns them. The Windows binary is x86_64 only. The packaging step checks that every binary embeds the release version, sorkat --version on an installed binary tells you exactly which release it is.
MobKit
MobKit’s gateway binaries are built and released by the meerkat-mobkit repository’s own lane; the glibc floor and portability gate described on this page do not apply to them. Start from the MobKit quickstart for its install and build paths.See Also
- CD and distribution for the release pipeline, Homebrew tap, SDK bootstrap, and credentials.
- Build And CI for the contributor build, test, and BuildBuddy lanes.
- Quickstart for the featured install paths.
