rcq is a transparent local resource queue for commands launched by coding
agents. It keeps expensive tests, builds, and compilers from stampeding a
workstation while leaving stdout, stderr, stdin, exit status, signals, argv,
environment, and the working directory attached to the invoking agent.
Linux and macOS are supported.
Build and place rcq on PATH:
cargo install --path .
rcq cargo test --workspaceA missing or empty ~/.rcq.conf is useful immediately. Common compilers,
builds, test runners, and package installs enter a default queue with four
slots. Everything else, including ls, rg, and Git commands, runs directly.
The daemon starts automatically on the first queued command and remains nearly
idle between requests.
RCQ accepts argv rather than a shell string. Use an explicit shell when shell syntax is needed:
rcq bash -c 'producer | consumer >result.txt'Configuration is one TOML file at ~/.rcq.conf. All settings are optional.
See examples/rcq.conf for a valid, fully annotated
configuration covering every option, and
examples/default.conf for the explicit equivalent of
an empty configuration.
This routes tests separately and limits all builds together through an ancestor queue:
notify_queued = true
[queue.build]
capacity = 3
[queue."build/test"]
capacity = 2
[queue."build/compile"]
capacity = 3
[[rule]]
glob = ["cargo test*", "pytest*"]
queue = "build/test"
[[rule]]
program = ["gcc", "clang", "cc"]
queue = "build/compile"A command in build/test consumes one build/test slot and one build slot.
Only explicitly declared ancestors impose a shared cap. A queue selected by a
rule but not declared gets one slot; an undeclared fallback queue gets four.
Weighted pools model resources shared across otherwise unrelated queues:
[pool.cpu]
capacity = 8
[pool.memory_gib]
capacity = 32
[[rule]]
regex = '^(?:make|ninja) -j(?:8|16)(?: |$)'
queue = "build/compile"
resources = { cpu = 6, memory_gib = 8 }
[fallback]
direct = trueClaims are admission units, not runtime enforcement. Queue slots, declared
ancestor slots, and pool units are reserved atomically. After 30 seconds, the
oldest blocked queue head reserves its conflicting resources as running work
drains, preventing large claims from starving. Set
starvation_after_seconds = 0 to disable that reservation.
Every queued command claims one slot from its queue and each declared ancestor.
The resources table adds weighted pool claims; omit it when none are needed.
Claims must be positive, so direct execution is an action rather than a
zero-claim queue entry.
Rules are checked in file order before the built-in expensive-command policy
and fallback. Each rule has one of program, glob, or regex, and one of
direct = true or queue = "name". Use rcq explain -- <command> to inspect a
decision and rcq config check to validate the complete effective
configuration.
RCQ can apply a wrapper after classification. This lets agents use RCQ as their only hook while still receiving RTK output reduction:
command_prefix = ["rtk"]rcq cargo test then classifies cargo test and executes rtk cargo test.
An exact prefix already present is not added again, so rcq rtk cargo test also
contains one RTK layer. --no-prefix disables insertion for one command.
rcq status [--json]
rcq daemon start
rcq daemon stop
rcq daemon restart
rcq --direct -- <command...>Queued execution fails closed if the daemon or configuration is unavailable.
--direct and RCQ_BYPASS=1 are explicit operator escape hatches. Status does
not start a stopped daemon.
A nested rcq using the same configuration runs directly inside its live outer
allocation instead of consuming another slot. The inherited marker is tied to
the outer ticket lease, so stale descendants queue normally; a different
configuration source remains an independent queue namespace.
The daemon owns scheduling state, while a private foreground runner owns each started command. Kernel file leases preserve capacity safety if the daemon or public client is killed. A replacement daemon accepts waiting clients but does not grant new work until every command from the previous generation has finished. Normal client loss retains only that command's exact queue and pool claims.
Install the included Codex instructions in a workspace or globally:
rcq init --codex
rcq init --codex --globalThe managed AGENTS.md import is idempotent and preserves unrelated content.
Agent command timeouts must include both queue wait and execution time.
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features -- --test-threads=1