Skip to content

Watching your traffic

Every HTTPS request to an application is terminated by Caddy on the serving device that hosts it. That is the one place in the path that sees the whole request — method, path, status, latency, bytes, client address, TLS version, and who signed in — so that is where Edgible records it. The serving device folds those records into one summary per minute and a capped list of individual requests, and ships both to the platform over the same path as its other telemetry. You read them in two places:

  • the Metrics tab of an application in the console;
  • edgible application traffic and edgible application requests on the command line.

For any window you ask about, the summary is a sum over that window:

  • requests by outcome (2xx, 3xx, 4xx, 5xx), per bucket and in total;
  • latency percentiles (p50, p95, p99) for the whole request and for the time your workload took to answer;
  • bytes in and out;
  • the busiest paths and client addresses (twenty each), user agents, status codes, upstream errors and TLS versions (ten each) — every table says so when there was more than it holds;
  • sign-in outcomes on routes that require Edgible login or an API key: allowed, challenged (sent to the login page), denied;
  • upstream errors — the text of the dial failure when your workload could not be reached.

The Errors table lists individual requests: every 4xx and 5xx, and every request whose workload could not be reached, newest first, with the upstream error beside the request that hit it. Successful requests are sampled (one in fifty by default), so the table never lists all of them.

edgible application traffic <app> prints the summary; edgible application requests <app> lists the individual records behind it. Both accept --json and emit the platform’s own shape unchanged, so they drop straight into a script.

Terminal window
edgible application traffic web # the last 24 hours
edgible application traffic web --since 1h
edgible application traffic web --since 7d --json | jq '.totals'
edgible application requests web --status 5xx # the last hour, errors only
edgible application requests web --since 6h --path /api --json
FlagOnWhat it does
--since <duration>bothWindow ending now: 15m, 6h, 7d. Defaults to 24h for traffic and 1h for requests.
--granularity minute|hourtrafficBucket size. minute serves windows up to 6 hours, hour up to 31 days; leave it off and the window picks one.
--access <name>bothOne access only — primary, or the access’s name.
--route <path>trafficOne route path only, e.g. /api/*.
--status <filter>requestsA class (5xx), a code (404), or a range (400-499).
--path <prefix>requestsOnly paths starting with this prefix.
--client-ip <ip>requestsOnly this client address.
-n, --limit <n>requestsRecords per page. Default 50.
--cursor <cursor>requestsContinue from the previous page; the command prints the cursor when there is more.

requests reads a window of at most six hours and refuses a longer one rather than truncating it silently. traffic reads up to 31 days.

They are near-real-time, not live. Telemetry reaches the platform through a buffered delivery path and can be up to fifteen minutes behind. Every card and every CLI run says “as of” the newest minute that was delivered. A quiet last quarter-hour is the lag, not an outage.

A minute with no requests is reported as zero. A serving device that has the application routed sends a rollup every minute even when nothing happened, so “no traffic” and “no data” look different: zero requests is a measurement, “not reported” means no device reported.

Client addresses are real only when the gateway forwards them. Requests reach the serving device through the gateway over a WireGuard tunnel. The gateway prepends the original client address using the PROXY protocol, and Caddy reads it — but only once both sides of that hop have enabled it for the application. Until then the serving device sees the gateway’s own tunnel address on every request. Those requests are counted as tunnel-attributed and kept out of the client tables, and the console says “client addresses unavailable” rather than listing the gateway as your busiest client. Nothing is offered for the deny list in that state, so you cannot be led to block your own gateway.

Counts are lower bounds under load. A device folds at most twenty thousand log lines a minute. Beyond that it counts what it skipped (droppedLines) and says so, rather than falling further and further behind.

The record list is capped as well. A device keeps at most two hundred individual records per application per minute. Errors take precedence over sampled successes, and the number it had to drop is carried on that minute’s summary. The summary itself is unaffected — it counts every line the device folded, whether or not a record was kept beside it.

When the Top clients table names an address you want gone, it offers Deny beside it. That writes the address into the application’s ipRules.deny list, which the gateway enforces before the request ever crosses the tunnel. The same list is editable under the application’s Access tab and with edgible application update.

Client addresses and user agents are personal data. The organization page has three settings — they are organization-wide, not per application — and they are applied on the serving device before anything is written, so a stricter setting is never recoverable later:

SettingOptionsDefault
Client addressesfull address, masked to /24 and /48, or not collectedfull, kept 30 days
Raw request recordsevery error plus a sample of successes, errors only, or offerrors and sample
Success sample rate1 in N50

Setting Raw request records to off stops the individual records entirely and leaves the per-minute summaries; setting Client addresses to not collected removes them from the log line itself, and the client table then says so rather than coming back empty. A change reaches each serving device on its next poll and applies from that point on — nothing already recorded is rewritten.

Per-minute summaries without client addresses are kept for a year; the client and sign-in identity tables and the individual request records are kept for thirty days.

  • Diagnose a broken app — workload logs and certificate state when the request telemetry shows errors.
  • Why can’t I reach my app? — requests refused at the gateway, which never reach the serving device and so never appear here.
  • Access — the IP rules the Deny action writes.