FAQ
What languages does Peppy support?
Peppy supports Rust and Python. The daemon and tooling are built in Rust; nodes in either language use the same peppy.json5 interfaces through the generated peppygen code and the peppylib runtime.
What tech are you using under the hood?
Peppy is written in Rust. Nodes communicate over Zenoh, messages are encoded with Cap’n Proto, and container nodes run on Apptainer (with Lima providing the Linux VM on macOS).
Can Peppy instances on different machines communicate with each other?
Yes. Core nodes connect into a unified network through federation: each core node manages its own machine, and a single launch can place nodes across machines, with the coordinator resolving every deployment once and the other machines running exactly what it resolved. Machines join the same network by enrolling in the same project with peppy platform enroll.
Will Peppy maintain backward compatibility?
Not until version 1.0. Since Peppy is still in alpha/beta, maintaining backward compatibility would introduce additional complexity and divert effort away from core development.
Any plans to make Peppy compatible with Windows?
No. Official support is limited to Linux (x86_64 and ARM64) and macOS (Apple Silicon).
Is Peppy free to use?
Peppy is source-available under the Business Source License 1.1. You can use it in production for free, provided your use does not include offering a product or service to third parties whose value derives primarily from Peppy itself; that kind of use requires a commercial license. Each release converts to the Apache License 2.0 on its Change Date (2031-01-01 for current releases).
Alongside the open code, the Peppy platform lets you sign in and enroll a machine in a project with peppy platform login, and watch your machines with peppy platform peers (the peers of a project’s cloud router) and peppy platform status (this machine’s enrollment and the state of its router link).
My launch failed with an error that looks unrelated to what I changed. Where do I start?
Check peppy repo list on the machine you submitted the launch to, before reading the error too literally.
Peppy’s default repositories read the hub content released with your Peppy version, so it changes only when you install another version. A repository whose ref names a branch moves with that branch at each peppy repo refresh, so a change merged there reaches your machine without a Peppy release. peppy repo list shows what each repository reads. Only the submitting machine’s repositories decide what a launch runs: it resolves every deployment once and every other machine in the launch runs those exact bytes, so a stale or differently-configured cache on another machine is never the cause. A repository cannot declare the same name:tag twice: peppy repo index refuses to generate an index for it and names both manifests, so the duplicate is caught when the repository is published rather than at your launch. See When a repository fails.
Why is peppy repo refresh reporting repositories it could not update, and can I still work?
Yes, you can almost certainly still work. A refresh failure is scoped to the repository that caused it: every other repository is indexed as usual, and the failing one keeps the entries it last published, so everything that launched before still launches. The run itself succeeds, names every repository that failed in one message so you know which parts of the state are not current, and asks you to run peppy repo refresh again.
Read the read failure of the repository. unreachable means the repository could not be read at all: network, a bad ref, an unmounted path, or a root with no committed peppy_repository.json5 (the fix for that last one is authoring, not waiting: run peppy repo index in the repository and commit the result). conflict means the repository was read fine but its committed index contradicts itself or the tree, and the message names what to fix.
peppy repo list marks a failing repository’s entries [retained, last read <date>]. Watch that date: retention is deliberate so that identities do not vanish out from under your launchers, but a repository failing for weeks is still serving weeks-old entries.
The one case with no local workaround is a machine that has never read that repository successfully: it has nothing to fall back to. Excluding the repository is the only lever, and it removes every identity that repository provides, not just the broken one.
What does Ctrl+C do while a peppy command waits for the daemon?
peppy stack launch, build, join, remove and benchmark, peppy node add, build and run, and peppy repo refresh each follow one goal on the daemon. The first Ctrl+C sends the daemon a cancel. The daemon stops the work at the step it reached and ends it as a failure there ends it, for example a cancelled launch clears the stack and a cancelled join is undone. The command waits for that end, under its max budget alone, prints how the goal ended, and exits with the status of that end: 5 for a cancel, 0 for a goal that completed before the cancel reached it, 4 for a failure (see Exit statuses of the other commands). A command that sends another goal after this one, such as peppy node add --run, exits with code 130 also when the goal completed before the cancel reached it, and sends no further goal. A second Ctrl+C stops the wait for the end: the command waits only until the cancel reaches the daemon, which goes on with it, and exits with code 130. A third Ctrl+C ends the command at once. A command whose process goes away, for example when its terminal closes, cancels its goal the same way. See Stopping a stack command with Ctrl+C and When a node command ends early.
The watchdog of a command bounds its wait: a command that hears nothing from the daemon for longer than its budgets allow stops waiting and exits with code 1. It sends no cancel, but its process ends, so the daemon cancels the goal, as for a command whose process goes away. The budgets that a stack command sends with its goal, --node-add-idle-timeout-secs and the others of Launch timeouts, are the daemon’s: a change that outlasts one fails with the kind timeout.
Is there an LLM-friendly version of the documentation?
Yes! LLM-optimized versions of the documentation are available at /llms.txt (index with links) and /llms-full.txt (full content). Those are always in sync with the latest version of the documentation.