Network Flow Logs
Retrieves network flow logs from Tailscale, capturing per-node traffic counts across virtual, subnet, exit and physical paths. Each record describes the traffic one node observed during a short bucket — roughly five seconds — including the source and destination nodes and the packet and byte counts for each connection.
Sync Type: Incremental
Requirements
Before configuring this input, you need to:
-
Enable network flow logging — Network flow logs documentation
- Network flow logs are available on the Premium and Enterprise plans
- Go to the Network flow logs page in the Tailscale admin console and select Start logging
- Requires an Owner, Admin, Network admin, or IT admin role
- Nodes must be running Tailscale v1.34 or later to report telemetry; older nodes are silently absent, as are nodes started with
--no-logs-no-support
-
Create an OAuth Client — Tailscale OAuth documentation
- Go to the OAuth clients page in the Tailscale admin console
- Click "Generate OAuth client"
- Select the
logs:network:readscope - Click "Generate client"
- Copy both the Client ID and Client Secret (the secret will only be shown once)
- Click "Done"
-
Tailnet ID (optional):
- Leave blank to use the default tailnet of the OAuth credential, which is the right choice for most users
- To target a specific tailnet, find your Tailnet ID in the Tailscale admin console under Settings > General
- See Tailnet name documentation for more details
Details
Monad fetches network flow logs in time windows, tracking the logged timestamp of the last record processed and continuing from there on the next sync.
- Data Retention: Tailscale keeps network flow logs for at most 30 days. This is a fixed limit — it does not vary by plan and there is no setting to extend it
- Time Window: When there is a backlog to work through — a first sync, a backfill, or a pipeline that was paused — Monad requests up to a day of logs at a time. This applies only while catching up; once current, each sync asks for just the period since the last one, so records arrive promptly rather than a day later. Tailscale returns an entire window in a single response with no pagination, so Monad decodes the response incrementally rather than holding it in memory
- Backfill Support: You can optionally specify a start date. A date older than the 30-day retention limit is clamped to that limit rather than rejected, since no data exists before it
- Ordering: Position is tracked by
logged, the time Tailscale's logging service recorded the message, which is also the field the API filters and orders on. This differs from thestartandendfields on each record, which describe when the traffic actually occurred and can trailloggedby over half an hour when a node uploads a bucket late - Resuming: Because position advances per record, a sync interrupted part way through a window resumes after the last record it delivered rather than repeating the whole window
- Freshness: Monad queries right up to the present, so records are collected as soon as Tailscale makes them available. Nothing is held back — the position advances only to the newest record actually seen, so a record that Tailscale had not yet made queryable is picked up on the following sync rather than being skipped
Volume
Network flow logs are high volume — every node reports continuously, not just when something notable happens. A mid-sized tailnet produces roughly 90 MB per day, and responses are not compressed. Size your destination accordingly, and consider a drop_key transform to strip the traffic categories you don't need.
Push via Log Streaming
As an alternative to polling with this input, Tailscale can push network flow logs to Monad using log streaming to a Splunk destination. Create a Splunk HEC input on your pipeline, then add a Splunk log stream for network flow logs in the Tailscale admin console:
- URL:
https://<pipeline-id>.data.monad.com/services/collector/event - Token:
<pipeline-id>
Configuration
Settings
| Setting | Type | Required | Description |
|---|---|---|---|
| tailnet_id | string | No | Your Tailnet ID. Leave blank to use the default tailnet of the OAuth credential. |
| backfill_start_time | string | No | The date to start fetching data from, up to a maximum lookback of 30 days; older values are clamped. If not specified, no past records will be fetched. |
| API Rate Limit | object | No | Optional limit on the connector's outbound request rate to the source API. Leave blank to use the connector's default behavior. See API Rate Limiting for the field format, limits, and how to choose a value. |
Secrets
| Secret | Type | Required | Description |
|---|---|---|---|
| client_id | string | Yes | Your Tailscale OAuth Client ID. |
| client_secret | string | Yes | Your Tailscale OAuth Client Secret. |
Rate Limits
Tailscale does not publicly document rate limits for the Network Flow Logs API, and the endpoint returns no rate limit headers. The input uses a conservative approach:
| Scope | Limit | Window | Notes |
|---|---|---|---|
| API Requests | Not documented | - | One request at a time, covering up to a day of logs while catching up |
Source: Tailscale API Documentation
Limitations
- Plan requirement: Network flow logs require the Premium or Enterprise plan and must be explicitly enabled in the admin console. If either is missing, the API returns an authorization error rather than an empty result
- Gaps longer than retention cannot be recovered: The 30-day limit applies to resuming as well as backfilling. A pipeline that is paused or failing for more than 30 days restarts from the retention boundary when it comes back, and the traffic in between is gone from Tailscale — there is no way to retrieve it afterwards. Use log streaming to a store you control if you need a record that survives an extended outage
- Data Retention: Logs are retained for a maximum of 30 days, and that limit is fixed. To keep them longer, use Tailscale's log streaming to send them to your own store and set retention there
- Destination Logging: Exit node traffic is partially redacted unless the separate Destination Logging setting is enabled. For traffic from a node out to the internet, the source is the Tailscale IP address and the protocol, source port and destination are empty; for traffic inbound to a node, the destination is the Tailscale IP address and the protocol, destination port and source are empty
- Node reporting is unvalidated: The
start,end,srcNode,dstNodesand traffic fields are reported by individual nodes and recorded without verification. Tailscale notes that a malicious node can spoof them. ThenodeIdandloggedfields are assigned server side - Denied connections are not logged: Tailscale only records successful connections. A connection attempt refused by an ACL does not appear, so this is not a source for access-denied events
- No admin console viewer: Network flow logs are reachable only through the API and log streaming; there is no way to browse them in the Tailscale admin console
- No Official Rate Limits: Tailscale does not publish rate limit specifications; the input uses conservative defaults
Related Articles
Sample Record
Code
Record fields
| Field | Description |
|---|---|
logged | When Tailscale's logging service recorded the message. Generally a few seconds after end |
nodeId | The node that reported the message, verified server side |
start, end | The traffic bucket the counts cover, as reported by the node |
srcNode, dstNodes | The nodes involved. user is absent when a node is tagged, and tags is absent when it is user-owned |
virtualTraffic | Node-to-node traffic inside the tailnet |
subnetTraffic | Traffic routed via an advertised subnet router |
exitTraffic | Traffic routed via an exit node |
physicalTraffic | Underlying WireGuard traffic between physical endpoints |
Each traffic entry carries proto (the IANA protocol number — 6 for TCP, 17 for UDP), src, dst, and the txPkts, txBytes, rxPkts and rxBytes counters. All four traffic arrays are omitted entirely when empty.
Sync frequency
By default this input polls approximately every 10 seconds, with each sync beginning after the previous one completes. A cron schedule configured on the pipeline overrides this cadence. See Input Sync Frequency for details.
Polling frequency is therefore what governs freshness: each sync collects everything Tailscale has published since the previous one.
What to expect on a new connector
If you leave backfill_start_time empty, collection starts from the moment the connector is created and begins on the first sync. You will not see records for traffic that occurred before then — set backfill_start_time if you want history as well.