limit
limit is the operational core of RayLimit. It plans or executes a reconcile-aware traffic limit for one selected runtime-local subject.
Public Usage Shape
raylimit limit (--ip <ip|all> | --inbound <tag> | --outbound <tag>) \
[--ip-aggregation shared|per_ip] \
--device <device> \
--direction upload|download \
[--rate <bytes-per-second> | --unlimited | --remove] \
[--source host_process|docker_container] \
(--pid <pid> | --container <id-or-name> | --name <name>) \
[--execute] \
[--allow-missing-tc-state] \
[--format text|json]What limit Actually Does
limit does not blindly push traffic-control commands. It:
- validates the selected runtime and limiter subject
- derives the intended desired state
- derives any runtime evidence the selected limiter family needs and observes current
tcstate, plusnftablesstate when needed - makes an explicit reconcile decision
- produces a plan or executes that plan when
--executeis present
That is why the command can legitimately produce apply, no-op, remove, replace, or blocked outcomes.
Target Selection
Exactly one limiter family must be selected:
--ip <ip|all>--inbound <tag>--outbound <tag>
Exactly one runtime must also be selected:
--pid--container--name
Every request also needs:
--device <device>--direction upload|download
--ip-aggregation is valid only with --ip all. If omitted, --ip all defaults to shared.
Operation Modes
| Mode | Flags | Meaning |
|---|---|---|
| limit | --rate | create or reconcile a rate-limited state |
| unlimited | --unlimited | create a specific-IP no-limit exception |
| remove | --remove | remove the selected managed rule set |
--rate must be greater than zero. --unlimited is valid only with a specific --ip <ip> target. It cannot be combined with --rate, --remove, or --ip all.
IP Aggregation For --ip all
--ip all has two deliberate all-IP execution modes:
| Target shape | Flags | Meaning | Concrete backend truth |
|---|---|---|---|
| shared all-IP baseline | --ip all or --ip all --ip-aggregation shared | one runtime-local shared baseline for the selected direction | concrete through one direct matchall attachment |
| evidence-expanded all-IP set | --ip all --ip-aggregation per_ip | expand the current live client IP set into concrete specific-IP work | concrete only after live Xray-backed client IP evidence expands into usable specific IP subjects |
per_ip applies only to --ip all. It does not create an unlimited exception form. Specific unlimited behavior remains --ip <ip> --unlimited.
Dry-Run, Execute, And Missing Observation
Dry-run is the default. Add --execute only when:
- the report shows a concrete backend path
- the observation is trustworthy enough for your change window
- the host is ready for live
tcmutation
--allow-missing-tc-state is more exceptional. It exists for cases where you want live execution even though RayLimit could not observe tc state first. It is valid only with --execute.
For --ip all --ip-aggregation per_ip, RayLimit must also derive the current live client IP set before it can build concrete work:
- available live evidence expands into deterministic concrete client-IP targets
no_sessionsmeans RayLimit found no current client-IP evidence for that runtime, so there is no concrete per-IP work to plan or execute- unavailable or insufficient evidence blocks planning and refuses live execution
- available evidence that yields no usable client IPs after normalization also blocks concrete per-IP work
How To Read The Report
The text output is organized into a stable operator-facing structure:
Requested State
This confirms the direction, device, and requested limit, unlimited exception, or removal.
Per-IP Expansion
When --ip all --ip-aggregation per_ip is selected, the report adds an explicit expansion section before the concrete per-target details. It shows:
- the per-IP evidence state
- the per-IP reconcile state
- the expanded client IP list
- a grouped decision summary
- one concrete entry per expanded target
Each expanded target then carries its own observation, decision, plan, and execution outcome.
Observation
This explains whether the current tc state is:
- available
- reconcilable
- already matched
- missing expected attachment rules
- unavailable or not comparable
Decision
The reconcile decision tells you the next safe step:
applyno_opreplaceremove
In practical operator terms, replace is the reapply path. It means RayLimit saw existing state for the selected subject, but that state does not match the desired state cleanly enough to leave it alone.
Plan
The plan section shows the action kind and the commands RayLimit would run or did run.
Execution And Outcome
These sections tell you whether execution was blocked, whether commands were actually executed, and whether the result was plan-ready, no changes, blocked, executed, or failed.
High-Value Examples
Runtime-local shared all-IP baseline (default):
sudo raylimit limit --pid 1234 --ip all --device eth0 --direction upload --rate 4096Runtime-local shared all-IP baseline, explicit:
sudo raylimit limit --pid 1234 --ip all --ip-aggregation shared --device eth0 --direction upload --rate 4096Evidence-expanded per_ip planning:
sudo raylimit limit --pid 1234 --ip all --ip-aggregation per_ip --device eth0 --direction upload --rate 4096Evidence-expanded per_ip remove:
sudo raylimit limit --pid 1234 --ip all --ip-aggregation per_ip --device eth0 --direction upload --removeSpecific IP override:
sudo raylimit limit --pid 1234 --ip 203.0.113.10 --device eth0 --direction upload --rate 2048Specific IP unlimited exception:
sudo raylimit limit --pid 1234 --ip 203.0.113.20 --device eth0 --direction upload --unlimitedInbound dry-run:
sudo raylimit limit --pid 1234 --inbound api-in --device eth0 --direction upload --rate 2048Outbound live execution:
sudo raylimit limit --pid 1234 --outbound proxy-out --device eth0 --direction upload --rate 2048 --executeSpecific-IP remove:
sudo raylimit limit --pid 1234 --ip 203.0.113.10 --device eth0 --direction upload --removeJSON output for automation:
sudo raylimit limit --pid 1234 --ip all --ip-aggregation per_ip --device eth0 --direction upload --rate 4096 --format jsonWhen To Stop Instead Of Executing
Do not add --execute merely because the command is syntactically valid. Stop and review the report when:
- the selected runtime is not the one you intended
- the subject looks wrong
- the observation says state is not comparable
- the decision says blocked
- the planned commands do not match your mental model