> ## Documentation Index
> Fetch the complete documentation index at: https://filetrace.eorlov.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Understand egress cost and capacity

> Attribute outbound traffic to processes, destinations and protocols, find what drives egress cost, and track it with Prometheus and the flows command.

**The question:** which processes and destinations drive outbound traffic, and how does that change over time?

Filetrace separates two kinds of egress that byte counters usually merge: **bytes a socket sent** and **bytes that came from a file**. For cost and capacity, both matter, and the difference tells you whether the traffic is user-facing content or application traffic.

## Rank destinations

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
sudo filetrace top destinations --since 1h --limit 20
```

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
TOP DESTINATIONS BY OUTBOUND TRAFFIC

DESTINATION    SENT      RECEIVED  PROCESSES
203.0.113.25   84.2 GB   1.10 GB   2
198.51.100.7   12.4 GB   640 MB    1
2001:db8::/32  8.90 GB   220 MB    4
```

`--protocol tcp` narrows it to one transport. The `PROCESSES` column shows how concentrated each destination is: one process is easy to explain, many processes means shared infrastructure.

## Merge flows by a key

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
sudo filetrace flows --group-by remote --since 24h --sort bytes
sudo filetrace flows --group-by process --since 24h
sudo filetrace flows --group-by port --since 24h
sudo filetrace flows --group-by protocol --since 24h
```

`--group-by` answers "by whom", "to where", "on which port" and "over which protocol" without changing the underlying records. `--direction inbound|outbound|both` chooses which side ranks the groups.

## Separate content from application traffic

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
sudo filetrace top files --since 24h --limit 20
sudo filetrace transfers --since 24h --sort bytes --limit 20
```

`top files` ranks what you actually serve or upload. `transfers` also lists `FILE unknown` rows: bytes sent with no file behind them, such as generated responses, proxied traffic or database results. If cost is driven by `unknown` rows, the lever is in the application, not in storage.

## Track it in Prometheus

The counters are cumulative, so `rate` and `increase` answer cost questions over any window:

```promql theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Bytes per second sent by each process
sum by (process_executable_name) (
  rate(filetrace_network_io_bytes_total{network_io_direction="transmit"}[5m])
)

# Egress per destination requires the log records or the API: metrics have no address label.
# Total bytes sent in a day, for a monthly projection
sum(increase(filetrace_network_io_bytes_total{network_io_direction="transmit"}[24h]))
```

> [!NOTE]
>
> No metric carries an address or a port, by design: those labels would grow without bound. For per-destination accounting, aggregate the `file_transfer` log records in your collector, where the address is an attribute.

A monthly projection from the daily total:

```promql theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Projected bytes for 30 days, from the last 24 hours
sum(increase(filetrace_network_io_bytes_total{network_io_direction="transmit"}[24h])) * 30
```

## Split by protocol and direction

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
sudo filetrace flows --group-by protocol --since 24h
sudo filetrace connections --state established --active
```

```promql theme={"theme":{"light":"github-light","dark":"github-dark"}}
sum by (network_transport, network_io_direction) (
  rate(filetrace_network_io_bytes_total[5m])
)
```

UDP egress is often DNS, metrics or logs; if it is large, the cause is usually a misconfigured exporter or a retry storm.

## Capacity planning

* **Sustained rate.** `FiletraceEgressSpike` in the [recipes](https://filetrace.eorlov.org/integrations/observability-recipes.md) alerts above a chosen threshold; set it from your link capacity, not a round number.
* **Peak versus average.** `max_over_time(sum(rate(filetrace_network_io_bytes_total{network_io_direction="transmit"}[5m]))[1h:1m])` shows the peak the link must absorb.
* **Files sent, not bytes.** `rate(filetrace_transfers_started_total[5m])` is operation rate, which matters when the bottleneck is connections rather than bandwidth.
* **Inbound.** The same counters with `network_io_direction="receive"` show what the host pulls in.

## Where the answer can mislead

* **Bytes are counted at the local socket**, before the network. They include protocol overhead the kernel adds later and exclude retransmissions, so they are close to, but not the same as, bytes billed by a provider.
* **Loopback traffic is counted.** An agent, a proxy or a service talking to itself over `127.0.0.1` adds to the totals. `--remote 127.0.0.0/8` isolates it.
* **A file can be sent more than once**, so `file.sent` totals are not storage totals.
* **The agent's own traffic** to a collector counts too; exclude it with `[filters] exclude_processes = ["filetrace-agent"]`.

## Related pages

* [`filetrace flows`](https://filetrace.eorlov.org/cli/flows) — grouping and direction.
* [`filetrace top`](https://filetrace.eorlov.org/cli/top) — the four subjects.
* [Prometheus](https://filetrace.eorlov.org/integrations/prometheus.md) — every metric and PromQL example.
* [Observability recipes](https://filetrace.eorlov.org/integrations/observability-recipes.md) — dashboards and alerts.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.