Skip to content

oxyzenQ/zelynic

Repository files navigation

Project status: active again

zelynic is active again after the v2.0.0 Renaissance release. Core features such as monitor, list, profile, watch, QoS, auto-throttle, Backend Doctor, and per-process bandwidth limiting through zelynic strict have been validated on a modern Arch/CachyOS cgroup v2 host.

Validation scope: strict limiting is validated on tested modern cgroup v2 systems, including CachyOS/Arch with kernel 6.18.33-1-cachyos-lts, nftables v1.1.6, tc/iproute2 7.0.0, pure cgroup v2, and interface wlp1s0. This is not yet a universal all-distro guarantee.

Troubleshooting: use zelynic strict --diagnose ... to print target PID selection, cgroup v2, nftables, and tc diagnostics when validating a host.

zelynic logo

zelynic

A serious Linux bandwidth control system for process-aware monitoring, shaping, and validation.

Built around `tc`, `nftables`, and cgroup v2 to make per-process network behavior inspectable and controllable from the terminal.

Support on Ko-fi

zelynic is a Rust CLI tool for monitoring, limiting, and shaping per-process network bandwidth on Linux. It uses Linux traffic control (tc) with HTB qdisc, nftables for packet marking, and cgroup v2 for process-aware rate limiting. Real-time monitoring is powered by ss, while the built-in TUI dashboard provides a live, htop-like view of network traffic.


Renamed from Oxy

Zelynic was previously named Oxy. The old repository and package name were oxy, and the command is now zelynic. Runtime state, cgroups, and nftables identifiers now use the zelynic namespace; v2.0.0-era oxy runtime artifacts are treated as legacy cleanup targets.

Renaissance Validation

The v2.0.0 Renaissance release validates zelynic strict on tested modern cgroup v2 systems. On CachyOS/Arch with kernel 6.18.33-1-cachyos-lts, nftables v1.1.6, tc/iproute2 7.0.0, pure cgroup v2, and interface wlp1s0, Brave bandwidth limiting was observed within the expected range for both byte-based and bit-based limits.

This does not guarantee identical behavior on every Linux distribution. Hosts need cgroup v2, nftables, and tc support, and zelynic strict --diagnose should be used when validating or troubleshooting a new environment. See docs/validation.md for details.

Backend Doctor

Zelynic detects host capabilities and recommends the safest available backend. The read-only Backend Doctor checks kernel, cgroup, nftables, tc, conntrack, systemd, and eBPF signals without modifying nftables, tc, or cgroups:

zelynic backend              # Summary and eBPF capability check
zelynic backend doctor       # Detailed capability matrix
zelynic backend doctor --json

The zelynic run command provides systemd scope wrapper planning and a live probe lab for system-scope units. zelynic run --dry-run renders the planned scope/cgroup wiring and preview-only systemd-run launch command without launching a process or modifying nftables, tc, cgroups, or state. The v2.5 Scope Runner adds --probe-live for a root-only, system-scope live probe that launches a real transient systemd scope, discovers ControlGroup and PID(s) via cgroup.procs, and renders a non-mutating Future Attach Preview. User scope is the default planning mode to avoid accidental system Polkit prompts; system scope can be previewed explicitly with --scope-mode system. zelynic run --execute without --probe-live remains gated as an experimental opt-in and returns a non-mutating not-implemented boundary. --attach-live exists but is hard-blocked. Full live limiting still needs a privilege handoff design because user-scope launch and root-required limiter attachment have different requirements. zelynic strict remains the only validated active limiter path. See docs/scope-lab.md for the full Scope Lab design and probe findings.

Support matrix — see docs/distro-matrix.md for the full distribution support matrix with validation status:

Host type Status
Arch/CachyOS pure cgroup v2 Validated
Modern systemd + cgroup v2 distros (Fedora, Ubuntu 22.04+, Debian 12+) Candidate
Older Ubuntu/Debian, hybrid cgroup, containers, WSL, non-systemd distros Partial / Unsupported
systemd-scope backend, cgroup v1 fallback, eBPF backend Future

The strict limiter path is validated on tested modern cgroup v2 Linux hosts. Other distributions are listed as candidates pending explicit validation. See the distro matrix for details and the validation reports for per-distro evidence.

Features

  • Monitor bandwidth usage per process/program with cumulative and real-time rates
  • Limit download and/or upload speeds per process with tc + nftables + cgroup v2
  • Experimental run planning and live probe — preview future systemd scope wrapper wiring, live system-scope probe with PID discovery and attach preview
  • QoS priority shaping — assign high/low priority tiers instead of hard limits
  • TUI dashboard — live bandwidth monitor with sparklines, scrolling, and dual RX/TX graphs
  • Auto-throttle daemon — background mode that auto-limits when thresholds are exceeded
  • Watch & alert — background monitor with desktop notifications on bandwidth thresholds
  • Bandwidth profiles — save, load, and apply named bandwidth limit presets
  • Bandwidth logging — snapshot and review historical bandwidth usage
  • Shell completions — bash, zsh, fish, elvish, powershell
  • Man page generation — roff format for system manual installation
  • Interface management — auto-detect or explicitly specify network interfaces
  • Strict CLI validation — invalid commands, interfaces, and values are rejected with clear errors
  • Supports multiple bandwidth units: byte/bs, kb, mb, gb, kbit, mbit, gbit
  • Built-in presets: gaming, streaming, background
  • Clean, colored terminal output (respects NO_COLOR)
  • JSON output mode for scripting integration
  • Persistent state across invocations (survives restarts)

Requirements

  • Linux (kernel 5.4+ recommended for full cgroup v2 support)
  • Root privileges (for bandwidth limiting, QoS, and auto-throttle operations)
  • iproute2 package (provides tc and ip commands)
  • nftables (for packet marking on download limiting)
  • Rust 1.88+ (for building from source)

Installation

Download Release

Download the latest release from GitHub Releases:

# Download tarball and checksum
curl -L -O https://github.com/oxyzenQ/zelynic/releases/download/v3.0.1/zelynic-v3.0.1-x86_64-linux.tar.gz
curl -L -O https://github.com/oxyzenQ/zelynic/releases/download/v3.0.1/zelynic-v3.0.1-x86_64-linux.tar.gz.sha256

# Verify checksum
sha256sum -c zelynic-v3.0.1-x86_64-linux.tar.gz.sha256

# Extract (creates zelynic-v3.0.1-x86_64-linux/ directory)
tar -xzf zelynic-v3.0.1-x86_64-linux.tar.gz
cd zelynic-v3.0.1-x86_64-linux

# Verify binary
./zelynic --version

# Install system-wide
sudo install -Dm755 zelynic /usr/local/bin/zelynic
zelynic --version

The tarball extracts into zelynic-v3.0.1-x86_64-linux/ with the binary at zelynic-v3.0.1-x86_64-linux/zelynic. SHA256 checksums are published alongside each release for download verification.

Man Page

The release tarball includes a pre-generated man page at man/zelynic.1.gz.

# View man page from extracted tarball
man ./man/zelynic.1.gz

# Or install system-wide
sudo install -Dm644 man/zelynic.1.gz /usr/share/man/man1/zelynic.1.gz
man zelynic

Minimal systems may need man-db or mandoc installed to view man pages.

Scripting with jq

The usage --sample --delta --json output is machine-readable and pipes well with jq for monitoring scripts and dashboards:

zelynic usage --sample --delta --json | jq '.command'
zelynic usage --sample --delta --json | jq '.totals.total_delta_combined_bytes'
zelynic usage --sample --delta --json | jq '.interfaces[] | {name, delta: .delta_combined_bytes}'

Release naming convention:

  • Tag: v3.0.1
  • Title: Zelynic v3.0.1 Post-Release Docs + Install Polish

See the v3.0.1 changelog entry for release details.

From Source

git clone https://github.com/oxyzenQ/zelynic.git
cd zelynic
cargo build --release

# Install system-wide
sudo install -Dm755 target/release/zelynic /usr/local/bin/zelynic

Quick Build

cargo build --release
sudo install -Dm755 target/release/zelynic /usr/local/bin/zelynic

Shell Completions

# Bash
zelynic completions bash | sudo tee /usr/share/bash-completion/completions/zelynic > /dev/null

# Zsh
zelynic completions zsh > ~/.zsh/completions/_zelynic

# Fish
zelynic completions fish > ~/.config/fish/completions/zelynic.fish

Usage

Quick Reference

zelynic [FLAGS] [COMMAND] [ARGS]

FLAGS:
    -i, --info              Print detailed package information
    -v, --ver               Print version (short)
    -V, --version           Print complete version and build information
    --check-update          Check the latest upstream release
    --check-updated         Alias for --check-update
    --help-all              Show comprehensive help with all commands and examples
    --iface [INTERFACE]     Specify network interface (no value = list available)
    --no-color              Disable colored output

COMMANDS:
    list                    List network bandwidth usage per process
    strict                  Set bandwidth limits for a process
    unstrict                Remove all bandwidth limits
    refresh                 Refresh an existing limit after process respawn
    status                  Show active bandwidth limits
    clean                   Clean up orphaned bandwidth limits
    profile                 Manage named bandwidth profiles
    qos                     QoS priority-based bandwidth shaping
    watch                   Monitor and alert on bandwidth threshold
    auto                    Auto-throttle daemon mode
    log                     Bandwidth usage history
    backend                 Show backend info and capability checks
    completions             Generate shell completions
    man                     Generate man page
    usage                   Show live interface usage (single snapshot or delta)

List Network Usage

Show all programs/ports with active bandwidth usage:

# List all processes with bandwidth usage (default)
zelynic list

# Real-time TUI dashboard (like htop for network)
zelynic list --live

# Live mode with custom refresh interval (2 seconds)
zelynic list --live --interval 2

# Sort by highest to lowest bandwidth usage
zelynic list --high-to-low-usage-net

# Show individual socket connections per process
zelynic list --verbose

# Output as JSON for scripting
zelynic list --json

Limit Bandwidth (strict)

Apply download and/or upload speed limits to a specific process:

# Limit both download and upload
sudo zelynic strict -d 500kb -u 500kb brave

# Limit only download (omit -u)
sudo zelynic strict -d 1mb firefox

# Limit only upload (omit -d)
sudo zelynic strict -u 250kb 1234

# Limit by PID
sudo zelynic strict -d 1mb -u 1mb 8100

# Use a preset profile
sudo zelynic strict --preset gaming discord
sudo zelynic strict --preset background steam
sudo zelynic strict --preset streaming zoom

Note: PID 0 (kernel idle thread) and user names (e.g., root) cannot be limited. zelynic targets processes by PID or binary name. PID 0 is not a userspace process and has no network sockets or cgroup association.

Re-limiting without unstrict first is supported — old rules are auto-cleaned:

sudo zelynic strict -d 500kb brave       # apply limit
sudo zelynic strict -d 10mb brave        # auto-overrides to 10mb

Reloads, tabs, and child processes normally remain limited while the browser process tree stays inside the target cgroup. If the application is closed completely and reopened, run refresh to move the new PIDs into the existing limit without duplicating nftables or tc rules:

sudo zelynic refresh brave

Strict applies to new connections after the target has been moved into the Zelynic cgroup. An already-running download or speed test can keep using its existing socket until the request reconnects. Apply zelynic strict before starting the network activity, or reload/restart the target's network request after strict is applied. Zelynic does not flush conntrack entries or forcibly reset existing connections by default.

Remove Bandwidth Limits (unstrict)

Remove all bandwidth restrictions from a process:

# By process name
sudo zelynic unstrict brave

# By PID
sudo zelynic unstrict 8100

When available, strict records the process's original cgroup before moving it. unstrict tries to restore live PIDs to that recorded cgroup safely; if the destination cannot be validated, Zelynic warns and falls back to the Zelynic parent cgroup instead of guessing systemd paths.

Show Active Limits

zelynic status

Clean Up Orphans

Remove tc/cgroup rules for processes that have already exited:

sudo zelynic clean

Network Interface

Auto-detect is used by default. Explicitly specify an interface with --iface:

# List available interfaces
zelynic --iface

# Use a specific interface for any command
zelynic --iface wlan0 list --live
sudo zelynic --iface eth0 strict -d 1mb brave
sudo zelynic --iface enp3s0 qos high firefox

For strict limits, the interface is auto-detected when zelynic strict is applied by reading the current default route. If the host later switches from WiFi to Ethernet, VPN, tethering, or another default route, upload shaping can remain attached to the old interface. For now, run sudo zelynic unstrict <target> and re-apply zelynic strict after the network changes. zelynic status warns when saved limits are attached to a different interface than the current default route.

QoS Priority Shaping

Assign priority tiers instead of hard limits. High priority processes get bandwidth first; idle bandwidth from low-priority processes redistributes automatically:

# High priority for browser
sudo zelynic qos high brave

# Low priority for download manager
sudo zelynic qos low wget

# Show current QoS assignments
zelynic qos status

# Clear all QoS rules
sudo zelynic qos reset

Profile Management

Save and load custom bandwidth profiles:

# Save a profile
zelynic profile save slow --dl 50kb --ul 50kb
zelynic profile save streaming --dl 5mb --ul 2mb

# Apply a profile
sudo zelynic profile apply slow steam

# List all profiles
zelynic profile list

# Delete a profile
zelynic profile delete slow

Watch & Alert

Monitor a process and send a desktop notification when bandwidth exceeds a threshold:

# Alert when wget rate exceeds 500KB/s
zelynic watch -a 500kb wget

# Check every 30 seconds
zelynic watch -a 5mb firefox -i 30

Auto-Throttle Daemon

Continuously monitor and automatically apply limits when thresholds are exceeded:

# Auto-limit when download exceeds 100MB/s and upload exceeds 50MB/s
sudo zelynic auto --download 100mb --upload 50mb

# Kill heavy processes instead of limiting
sudo zelynic auto --download 80mb --kill firefox

# Run as a background daemon
sudo zelynic auto --daemon

Bandwidth Logging

Record and review historical bandwidth usage:

# Show recent history
zelynic log

# Record a snapshot of current state
zelynic log --snapshot

# Show last hour
zelynic log --last 1h

# JSON output for analysis
zelynic log --json

Live Interface Usage (v3.0)

Show live interface counters from /proc/net/dev — single snapshot or delta between two samples:

# Single snapshot (text)
zelynic usage --sample

# Single snapshot (JSON)
zelynic usage --sample --json

# Delta between two samples (text)
zelynic usage --sample --delta

# Delta between two samples (JSON)
zelynic usage --sample --delta --json

All usage commands are read-only, interface-level only, single-shot. No loop, no watch, no persistence, no enforcement.

Presets

Built-in presets for common use cases:

Preset Download Upload Use Case
gaming 50 mb/s 50 mb/s Low latency, prioritizes responsive gameplay
streaming 10 mb/s 5 mb/s Balanced for video calls and streaming
background 500 kb/s 100 kb/s Minimal bandwidth for background downloads

Supported Units

Unit Description Example
b, byte, bs Bytes per second 100bs, 500byte
kb, kbs Kilobytes per second (1 KB = 1024 B) 500kb, 2kbs
mb, mbs Megabytes per second (1 MB = 1024 KB) 1mb, 50mbs
gb, gbs Gigabytes per second (1 GB = 1024 MB) 1gb, 2gbs
kbit, kbits Kilobits per second 100kbit, 500kbits
mbit, mbits Megabits per second 10mbit, 100mbits
gbit, gbits Gigabits per second 1gbit

Note: Minimum rate is 1 KB/s (1024 B/s). Values below this are rejected because the Linux kernel's HTB scheduler cannot accurately enforce sub-KB/s rates due to clock tick granularity.

Architecture

zelynic works by combining several Linux kernel features:

Bandwidth Monitoring

Uses the ss (socket statistics) command to discover all active TCP/UDP sockets on the system, maps them to their owning processes via /proc filesystem, and extracts per-socket byte counters (available on kernels 4.6+).

Bandwidth Limiting

Uses a layered approach:

  1. Cgroup v2 — Places target PIDs in /sys/fs/cgroup/zelynic/target_<name>.
  2. nftables socket matching — Matches target sockets with socket cgroupv2.
  3. Packet and conntrack marks — Marks target flows so upload and download can be identified.
  4. tc fw filter + HTB class — Shapes upload/egress traffic on the selected interface.
  5. nftables input policer — Limits marked download/ingress responses with limit/drop.

How It Works

Upload / egress
  Process PID
    -> cgroup v2 target (/sys/fs/cgroup/zelynic/target_<name>)
    -> nft output: socket cgroupv2 match
    -> meta mark / ct mark
    -> tc fw filter
    -> HTB class
    -> network interface

Download / ingress
  Process opens connection
    -> nft output marks socket/flow
    -> conntrack mark is stored

  Incoming response
    -> nft input matches ct mark
    -> nft limit/drop policer
    -> process receives limited download

Package Information

# Print version
zelynic -v

# Print complete version and build info
zelynic -V

# Check the latest upstream release
zelynic --check-update

Example output of zelynic -V:

Version: v3.0.1
Build: linux-x86_64 (COMMIT_HASH)
Copyright: (c) 2026 rezky_nightky (oxyzenQ)
License: GPL-3.0
Source: https://github.com/oxyzenQ/zelynic

Building

# Recommended local quality gate for Rust/core changes
./build.sh check-all

# Build release binary
./build.sh release

# Full CI pipeline (checks + release build)
./build.sh ci

Manual fallback:

cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test
cargo audit
cargo deny check all
python3 scripts/check-policy.py

See RULES.md for source policy rules and docs/supply-chain.md for dependency policy and supply-chain check details.

License

GNU General Public License v3.0 — Copyright (c) 2026 rezky_nightky (oxyzenQ)

See LICENSE for details.

Author

rezky_nightky (oxyzenQ)GitHub

Sponsor this project

Contributors