npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

bee-network-monitor

v1.0.0

Published

Monitor Bee node network activity: scrape Prometheus metrics (metrics) or count outbound TCP SYNs (syns)

Downloads

26

Readme

bee-network-monitor

Two monitoring modes for a Bee node, both writing timestamped CSV rows:

| Mode | What it measures | |---|---| | metrics | Application-layer counters scraped from the Bee Prometheus endpoint | | syns | Outbound TCP SYN packets counted at the OS level via tcpdump |

Running both together gives a complete picture of application intent (metrics) vs. wire reality (syns), which is useful for diagnosing the port-scanning heuristic that hosting providers trigger on WSS-enabled nodes.


Requirements

  • Node.js ≥ 18
  • metrics mode: network access to the Bee metrics endpoint (default :1633/metrics)
  • syns mode: Linux, tcpdump, and CAP_NET_RAW or root

Grant CAP_NET_RAW without running as root

sudo setcap cap_net_raw,cap_net_admin+eip "$(which tcpdump)"

Installation

npm install -g bee-network-monitor

Or run without installing:

npx bee-network-monitor <mode> [args]

Usage

bee-network-monitor metrics [metrics_url] [interval_sec] [output_csv]
bee-network-monitor syns    [interface]   [interval_sec] [output_csv]

metrics mode

# All defaults: http://localhost:1633/metrics, every 15 s, bee_metrics.csv
bee-network-monitor metrics

# Custom endpoint, 30-second interval
bee-network-monitor metrics http://node-1:1633/metrics 30 node1_metrics.csv

Polls the Prometheus endpoint every interval_sec seconds and appends one row. The CSV header is written once when the file does not yet exist.

Output columns

| Column | Type | Description | |---|---|---| | timestamp | string | UTC timestamp (ISO 8601) | | bee_kademlia_total_outbound_connection_attempts | counter | Every dial kademlia has initiated — the primary port-scan signal | | bee_kademlia_total_outbound_connection_failed_attempts | counter | Dials that returned a hard error | | bee_kademlia_total_outbound_connections | counter | Successful outbound connections | | bee_kademlia_currently_known_peers | gauge | Peer pool size driving dial activity | | bee_kademlia_currently_connected_peers | gauge | Currently connected peer count | | bee_kademlia_total_inbound_disconnections | counter | Inbound connections that have dropped; high churn forces re-dialing | | bee_libp2p_created_connection_count | counter | Outbound connections opened by libp2p | | bee_libp2p_handled_connection_count | counter | Inbound connections accepted | | bee_libp2p_connect_breaker_count | counter | Circuit breaker trips (each = 100 consecutive failures to one peer) | | bee_libp2p_blocklisted_peer_count | counter | Peers blocked for protocol violations | | bee_libp2p_disconnect_count | counter | Locally initiated disconnections | | bee_libp2p_stream_reset_count | counter | Stream resets (RST) | | bee_libp2p_unexpected_protocol_request_count | counter | Requests for unsupported protocols | | bee_handshake_syn_rx_failed | counter | Failed incoming handshake SYN reads | | bee_handshake_ack_rx_failed | counter | Connections opened but ACK never completed | | bee_reacher_ping_attempt_count | counter | Pings sent to currently-connected peers | | bee_reacher_ping_error_count | counter | Failed reacher pings | | bee_reacher_peers | gauge | Reacher queue depth (should equal connected peers) | | bee_process_network_receive_bytes_total | counter | Cumulative bytes received | | bee_process_network_transmit_bytes_total | counter | Cumulative bytes sent | | bee_process_open_fds | gauge | Open file descriptors (each TCP socket = 1 FD) |

Derived rates (compute from successive rows)

kademlia_dial_rate          = Δ outbound_connection_attempts / Δt
kademlia_dial_success_ratio = Δ outbound_connections        / Δ outbound_connection_attempts
reacher_ping_failure_ratio  = Δ ping_error_count            / Δ ping_attempt_count
rx_bytes_per_sec            = Δ network_receive_bytes_total / Δt
tx_bytes_per_sec            = Δ network_transmit_bytes_total / Δt

syns mode

# All defaults: eth0, every 10 s, syn_bursts.csv
sudo bee-network-monitor syns

# Specific interface and interval
sudo bee-network-monitor syns ens3 10 node1_syns.csv

Spawns tcpdump each interval with a BPF filter that passes only outbound TCP SYN (SYN=1, ACK=0) packets sourced from the interface's IPv4 address. Each packet line is parsed and discarded immediately; only counters and two Sets (unique IPs, unique ports) are kept in memory.

Output columns

| Column | Description | |---|---| | timestamp | UTC timestamp (ISO 8601) | | interval_sec | Capture window length in seconds | | syn_out_count | Total outbound SYN packets in the interval | | unique_dst_ips | Distinct destination IP addresses reached | | unique_dst_ports | Distinct destination ports reached | | syns_per_sec | syn_out_count / interval_sec | | unique_ips_per_sec | unique_dst_ips / interval_sec — closest analogue to what hosting providers observe | | kernel_drops | Packets dropped by the kernel ring buffer; non-zero means counts are understated |

Interpreting the output

unique_ips_per_sec is the metric to watch. Hosting providers do not publish detection thresholds, so compare against your own baseline:

  1. Record a baseline with WSS disabled.
  2. Enable WSS, record again.
  3. The delta is concrete evidence of exactly how much additional connection spread WSS introduces.

A brief spike after node startup or a wave of peer disconnections is expected — kademlia refilling its bins. A value that never returns to baseline is worth investigating.

If kernel_drops is non-zero, increase the ring buffer size:

sudo bee-network-monitor syns eth0 10 out.csv   # default ring buffer
sudo tcpdump -B 4096 ...                         # increase to 4 MB if drops persist

Correlating both modes

Both CSVs include a UTC timestamp column but are written by independent processes, so timestamps will not align exactly. Round to the nearest interval boundary to correlate them:

kademlia_dial_rate (from metrics) ≈ unique_ips_per_sec (from syns)

If syns reads significantly higher than metrics implies, the excess comes from outside Bee — AutoTLS certificate renewal, DNS resolution for peer addresses, or other system processes.


Development

npm install
npm start -- metrics       # run from TypeScript source
npm start -- syns eth0
npm run typecheck
npm run build              # emits dist/index.js