sFlow is a traffic monitoring protocol in which a switch, router or host randomly copies the header of 1 in every N packets and periodically sends its interface counters to a collector over UDP port 6343, keeping no flow table. NetFlow v9 and IPFIX instead build flow records in a cache on the exporter and send summaries when flows end.
That one design choice explains most of sFlow's character: it is cheap enough to run in switch silicon, its numbers are statistical estimates with known error bars, it shows you the first bytes of real packets (and so real personal data), and the collector does the hard work. This guide covers the specification history, sampling and its accuracy with worked examples, counter polling, the datagram structure, the differences from NetFlow and IPFIX, host agents, collectors, security and privacy, and a two machine Linux lab.
Key takeaways
- sFlow version 5 was published by sFlow.org in July 2004 and replaced version 4, which was documented as the informational RFC 3176 in September 2001. RFC 3176 says plainly that it "does not specify an Internet standard of any kind". The current specification lives at sFlow.org, an industry forum, not at the IETF.
- An sFlow agent does two things only: packet flow sampling (a random 1 in N choice of packets, copying the header, by default up to 128 bytes) and counter sampling (periodic export of interface and other counters, with the polling interval as a maximum, not a schedule).
- Each flow sample carries the sampling rate and sample pool, so the collector can scale up to totals. Accuracy depends on the number of samples for what you measure, not link speed: sFlow.org's 95 percent error bound is about 196 times the square root of 1 over the sample count, in percent.
- Datagrams are encoded in XDR (RFC 4506), sent over UDP, unauthenticated and unencrypted. The specification itself says the collector "is vulnerable to attacks involving spoofed sFlow Datagrams" and that traffic information "can reveal confidential information about individual network users".
- NetFlow v9 (RFC 3954, October 2004) and IPFIX (RFC 7011, September 2013, STD 77) keep per flow state and use templates. sFlow keeps no flow state and uses fixed structures extended by enterprise numbers.
- Protect the collector: management network or tunnel, UDP 6343 only from known agents, sequence number checks, minimal header size, short retention and a patched collector.
What is sFlow, when was it published and who maintains it?
sFlow is a sampling based technology for monitoring traffic in switched and routed networks. The version 5 specification describes a system with two parts: an sFlow agent embedded in a switch, router or standalone probe, and a central sFlow collector. The stated design goals are accurate monitoring at gigabit speeds and higher, scaling to tens of thousands of agents from a single collector, and an extremely low cost agent implementation.
The specification timeline
| Date | Event | Source |
|---|---|---|
| 1991 | Network wide monitoring using packet sampling demonstrated at Telecom 91 (University of Geneva and CERN) | sFlow.org, History of Packet Sampling |
| 1993 | Networking products with embedded packet sampling (an extended RMON implementation) introduced | sFlow.org, History of Packet Sampling |
| 2001 | Switches and routers with embedded sFlow sampling available | sFlow.org, History of Packet Sampling |
| September 2001 | RFC 3176 publishes sFlow version 4 as an informational RFC | RFC 3176 |
| July 2004 | sFlow version 5 published by sFlow.org; it replaces version 4 | sFlow version 5 specification |
| October 2004 | NetFlow version 9 published as informational RFC 3954 | RFC 3954 |
| May 2006 | XDR, the encoding sFlow uses, republished as RFC 4506 (STD 67) | RFC 4506 |
| March 2009 | RFC 5475 standardises packet selection (sampling and filtering) techniques for the IETF's PSAMP work | RFC 5475 |
| July 2010 | sFlow Host Structures published; Host sFlow agent 1.0 released on 23 July 2010 | sFlow Host Structures; sflow.net |
| September 2013 | IPFIX protocol published as RFC 7011, Internet Standard STD 77 | RFC 7011 |
| June 2014 | Host sFlow agent adds Docker support | sflow.net news |
| April 2019 | Host sFlow agent adds Linux netlink psample support | sflow.net news |
| October 2020 | sFlow Dropped Packet Notification Structures published | sFlow.org specification |
| July 2025 | Host sFlow agent adds eBPF TCX support | sflow.net news |
Who maintains it now?
sFlow.org describes itself as "an international, multi-vendor, and end-user forum" and states that its web site is "the authoritative source for information on sFlow". Its developer page lists sFlow version 5 as the current specification, with three parts: the SFLOW-MIB (the SNMP management interface), the SFLOW-DATAGRAM (packet formats) and SFLOW-STRUCTS (data structures). It also says versions 4 and 2 are deprecated and that new implementations should use version 5.
Since 2004 the protocol has grown by adding structures, not by changing the version number. The developer page lists extensions for dropped packets, transit delay, 802.11, optical modules, link aggregation, tunnels, switch ASIC tables, OpenFlow, hosts, Java virtual machines, HTTP, applications and GPUs. There is no new RFC for each addition, just a published structure with a number. And note that RFC 3176 describes version 4: a decoder built only from it will not read the version 5 datagrams current devices send.
How does packet sampling work?
The version 5 specification describes packet flow sampling in a few precise steps. When a packet arrives, the device first decides whether to drop it (filtering). If it is not dropped, the switching or routing function assigns an output interface. Only then is the sampling decision made, so the sample can record where the packet was going.
The mechanism is a skip counter:
- A counter is set to a random number whose long run average equals the sampling rate N.
- Each packet decrements the counter. A second counter, Total_Packets, counts every packet that could have been sampled, whether it was or not.
- When the skip counter reaches zero, the device takes a sample and increments Total_Samples.
- The skip counter is reloaded with a fresh random number.
The rule the random numbers must satisfy is that Total_Packets divided by Total_Samples equals the sampling rate over time. The specification allows an alternative: draw a random number for every packet and sample whenever it falls under a threshold, provided the resulting stream still meets that ratio.
Appendix B of the specification adds three requirements for the random number generator. The mean must converge to the sampling rate. Every value between the minimum and maximum must be possible (a generator that only produces even numbers, or numbers with a common divisor, is unsuitable). And even small random perturbations are enough to stop the sampler synchronising with periodic patterns in the traffic. That is why sFlow avoids deterministic "every Nth packet" sampling, which can line up with periodic traffic and always or never see it.
What a sample contains
Taking a sample means either copying the packet's header or extracting features from it. The most common form is the raw packet header record (sampled_header), which carries:
- the header protocol (Ethernet, IPv4, IPv6, MPLS, PPP and others are enumerated),
- the original frame length before any truncation,
- the number of bytes stripped (for example the frame check sequence),
- the header bytes themselves, up to the configured maximum header size.
The SFLOW-MIB object sFlowFsMaximumHeaderSize sets that maximum, default 128 bytes, the same default Open vSwitch documents. Decoded alternatives (sampled_ethernet, sampled_ipv4, sampled_ipv6) carry addresses, ports and flags as fields instead. The agent then adds path information, such as interfaces, VLANs, next hop and AS path, in extended records described below.
Choosing a sampling rate
There is no single correct rate; you trade samples per second against the cost of sending and storing them. Two documented defaults:
- Open vSwitch defaults to sampling 1 in 400 packets if you do not set the
samplingcolumn, and polls counters every 30 seconds. - The Host sFlow agent's Linux configuration sets the default rate for ports with a known link speed as N equals the link speed divided by 1,000,000. Its documentation spells out the result: a 40G interface is sampled at 1 in 40,000 and a 100M interface at 1 in 100. For data sources with no link speed, it falls back to a default
samplingvalue such as 400.
The speed based rule means every port at full line rate produces roughly the same number of samples per second, whatever its speed.
What accuracy can sampled data give?
sFlow.org's "Packet Sampling Basics" paper models packet sampling with the binomial distribution and gives a simple estimate for the percentage error at 95 percent confidence:
percentage error is at most 196 times the square root of (1 divided by c)
where c is the number of samples that belong to the class of traffic you are measuring (a host, a port, a protocol, an application).
So accuracy depends on the number of samples in the class, not on link speed: the paper notes that a 400 frames per second switch at 0.25 percent sampling and a 40,000 frames per second switch at 0.0025 percent give the same accuracy. Small classes over short intervals are noisy; sample more often or measure longer.
The paper's figures match the formula: 1,000 samples gives about 6 percent; a one packet per second voice stream sampled at 0.25 percent for an hour gives about 9 samples and 65 percent; the same stream over a month gives about 6,700 samples and 2.4 percent.
Worked example 1: a busy 10G uplink
Take a 10 Gbit/s uplink at 50 percent utilisation, with an average packet size of 800 bytes, sampled at 1 in 10,000 (the Host sFlow speed rule for 10G).
- Bits per second: 5,000,000,000.
- Bits per packet: 800 times 8 equals 6,400.
- Packets per second: 5,000,000,000 divided by 6,400 equals 781,250.
- Samples per second: 781,250 divided by 10,000 equals about 78.
- Samples per minute: about 4,690.
Now ask how much of that traffic belongs to one server that carries 1 percent of the bytes on the link. Assume its packets are average sized, so it also accounts for about 1 percent of samples:
- In one minute: about 47 samples, so the error is 196 divided by the square root of 47, about 29 percent.
- In ten minutes: about 469 samples, error about 9 percent.
- In one hour: about 2,814 samples, error about 3.7 percent.
So this server's per minute graph will jump around by plus or minus a quarter, while the hourly figure is good enough for capacity planning. Large talkers are accurate within a few percent even per minute; small ones need longer windows.
Worked example 2: the 1G access port with a copied 10G rate
A common mistake is to push one sampling rate to every port. Take a 1 Gbit/s access port at 10 percent utilisation with 1,000 byte packets, sampled at 1 in 10,000 because that rate was copied from the core.
- Bits per second: 100,000,000.
- Packets per second: 100,000,000 divided by 8,000 equals 12,500.
- Samples per second: 1.25. Samples per minute: 75.
A host that carries 2 percent of that port's traffic contributes about 1.5 samples a minute. The error bound is 196 divided by the square root of 1.5, about 160 percent, which means the per minute number is essentially meaningless. Even over an hour it has about 90 samples and an error near 21 percent.
With the speed based rule instead (1 in 1,000 for 1G), the same host gets about 15 samples a minute (error about 51 percent) and about 900 an hour (error about 6.5 percent).
Worked example 3: how big is one flow sample on the wire?
Counting XDR fields from the version 5 structures gives the size of a typical compact format flow sample with a 128 byte header and a switch record:
| Part | Fields | Bytes |
|---|---|---|
| Sample record wrapper | sample type and length | 8 |
flow_sample fixed fields | sequence number, source ID, sampling rate, sample pool, drops, input, output, record count | 32 |
sampled_header record | format, length, protocol, frame length, stripped, header length, 128 header bytes | 152 |
extended_switch record | format, length, source VLAN and priority, destination VLAN and priority | 24 |
| Total | 216 |
A version 5 datagram header from an IPv4 agent takes 28 bytes (version, address type, agent address, sub agent ID, sequence number, uptime, sample count). The SFLOW-MIB default maximum datagram size, sFlowRcvrMaximumDatagramSize, is 1,400 bytes, chosen to avoid fragmentation. So one datagram can hold six such flow samples: 28 plus 6 times 216 is 1,324 bytes, and a seventh would exceed 1,400.
A counter sample with generic interface counters (88 bytes) and Ethernet counters (13 counters, 52 bytes) is 8 plus 12 plus 96 plus 60, or 176 bytes. That is why the agent can usually tuck counter samples into spare space in a datagram that is already going out with flow samples.
What is counter polling, and what do the counter structures carry?
Counter sampling exists, in the specification's words, to "efficiently, periodically export counters associated with Data Sources". Each interface typically gets a maximum interval, sFlowCpInterval, in seconds; 0 disables it.
The interval is a maximum, not a timetable. The specification's suggested strategy is to top up each outgoing flow sample datagram with counters from sources close to (say within 5 seconds of) missing their interval, and every second or so send any that would otherwise be late. Agents that poll on a timer should stagger start times randomly so exports are not synchronised.
Counter samples also make sFlow resilient to loss. The specification uses 64 bit octet counters, and with typical polling intervals of 20 to 120 seconds, it notes the chance of losing enough datagrams in a row to hide a counter wrap is very small. A lost counter sample is simply replaced by the next one.
The standard counter structures
| Structure | Format number | What it carries |
|---|---|---|
Generic interface counters (if_counters) | 1 | ifIndex, type, speed, direction, admin and operational status, in and out octets (64 bit), unicast, multicast and broadcast packets, discards, errors, unknown protocols, promiscuous mode |
| Ethernet counters | 2 | Alignment errors, FCS errors, collisions, deferred transmissions, late and excessive collisions, MAC transmit and receive errors, carrier sense errors, frames too long, symbol errors |
| Token Ring counters | 3 | Token Ring error statistics |
| 100BaseVG counters | 4 | 100BaseVG interface statistics |
| VLAN counters | 5 | Per VLAN octets, unicast, multicast and broadcast packets, and discards |
| Processor information | 1001 | 5 second, 1 minute and 5 minute CPU averages, total and free memory |
The generic interface counters mirror the SNMP IF-MIB. The difference is direction: SNMP is a pull by a poller, sFlow a staggered push from the agent. Our SNMP guide covers the polling side.
Host and application counters
The sFlow Host Structures document (July 2010) adds counter structures for physical and virtual servers:
| Structure | Format number | What it carries |
|---|---|---|
host_descr | 2000 | Host name, UUID, machine type, OS name and release |
host_adapters | 2001 | The NICs or virtual NICs and their MAC addresses |
host_parent | 2002 | Containment, for example which hypervisor a VM belongs to |
host_cpu | 2003 | Load averages, process counts, CPU count and speed, uptime, CPU time by state, interrupts, context switches |
host_memory | 2004 | Total and free memory, shared, buffers, cache, swap, page and swap activity |
host_disk_io | 2005 | Disk capacity and free space, reads and writes, bytes and time |
host_net_io | 2006 | Host level network bytes, packets, errors and drops |
virt_node, virt_cpu, virt_memory, virt_disk_io, virt_net_io | 2100 to 2104 | The same views for a hypervisor and each virtual domain, modelled on libvirt statistics |
Further sFlow.org documents add application structures that sample transactions instead of packets: a web server module can sample 1 in N HTTP requests and report them with the same arithmetic.
How is an sFlow datagram structured, and why is the agent stateless?
The specification writes the datagram format in XDR, the External Data Representation standard now published as RFC 4506. It explains the choice briefly: XDR is more compact than ASN.1 and simpler for the agent to encode and the collector to decode. XDR is big endian and aligns every item to 4 bytes, which is why so many sFlow fields are 32 bit integers even when the values are small.
The datagram header
| Field | Size | Meaning |
|---|---|---|
| version | 4 bytes | 5 |
| agent address type | 4 bytes | 1 for IPv4, 2 for IPv6, 0 for unknown |
| agent address | 4 or 16 bytes | The IP address that identifies the agent, not necessarily the UDP source address |
| sub agent ID | 4 bytes | Distinguishes datagram streams from separate parts of a distributed device, such as line cards |
| sequence number | 4 bytes | Incremented with each datagram from that sub agent |
| uptime | 4 bytes | Milliseconds since the device booted |
| samples | variable | An array of sample records, each with a type, a length and opaque data |
Sample records
Each sample record has a data_format that packs two values into 32 bits: the top 20 bits are an SMI Private Enterprise Number (0 for standard sFlow.org structures) and the bottom 12 bits are a structure number chosen by that enterprise. The four standard sample types are:
- 1: flow sample (compact)
- 2: counter sample (compact)
- 3: flow sample (expanded)
- 4: counter sample (expanded)
The dropped packet notification extension adds type 5, a discarded_packet sample.
Compact and expanded formats differ only in how they encode the data source and interfaces. Compact formats pack the source type into the top byte and the index into 24 bits. If an agent may ever use ifIndex values of 2 to the power 24 or more, it must use the expanded formats for everything; it may not mix them.
A flow sample carries:
- a sequence number per source,
- the source ID (type and index; type 0 is an ifIndex, 1 a VLAN data source, 2 a physical entity),
- the sampling rate,
- the sample pool, the total number of packets that could have been sampled,
- drops, the number of times the agent had to drop a sample for lack of resources,
- the input and output interface,
- a list of flow records.
In the interface fields, the top two bits select a format: 0 is a single ifIndex, 1 is a discarded packet with a reason code (for example 257 for TTL exceeded and 258 for an ACL drop), and 2 is a packet sent to several interfaces.
Extended flow records
After the packet header, the agent adds whatever path information it has. Version 5 defines these standard extended records:
| Record | Format number | What it adds |
|---|---|---|
| Extended switch | 1001 | Source and destination 802.1Q VLAN and 802.1p priority |
| Extended router | 1002 | Next hop, source and destination prefix lengths |
| Extended gateway | 1003 | BGP next hop, AS numbers, AS path, communities, local preference |
| Extended user | 1004 | User IDs associated with the packet's source and destination, with their character sets |
| Extended URL | 1005 | The HTTP request line and Host header |
| Extended MPLS | 1006 | MPLS next hop and label stacks |
| Extended NAT | 1007 | Translated source and destination addresses |
| Extended MPLS tunnel, VC, FTN, LDP FEC | 1008 to 1011 | MPLS tunnel and virtual circuit context |
| Extended VLAN tunnel | 1012 | Stacked VLAN tags |
The host structures add socket records (2100 and 2101) that tie a sampled packet to a local socket. Read the user and URL records twice: they are why an sFlow store can hold identifiers and browsing data, not just addresses.
Extensibility rules that keep old collectors working
An enterprise may append fields to the end of a structure it defined without changing its number; any other change needs a new number. A receiver must always use the opaque length field when decoding, so an old collector simply skips what it does not know.
The same rule is a security point for collector authors. The length fields come from the network and must be checked against the remaining buffer before any copy. A collector that trusts a length field is a collector that can be crashed, or worse, by one crafted datagram.
Why the agent can be stateless
The agent keeps no flow table, no per flow timers, no templates and no session with the collector. Each sample is complete in itself; the agent holds a few counters per data source and a small datagram buffer.
The specification makes two decisions that depend on this. First, transport is UDP, and it argues that UDP loss only slightly reduces the effective sampling rate for flow samples and is repaired at the next poll for counters. It goes further: under overload, an unreliable transport only adds a little delay and loss, while a reliable one would force the agent to buffer large amounts of data. Second, the agent must not wait for a buffer to fill. It may delay a sample by at most 1 second before sending.
Statelessness is why sampling can be built into switch ASICs: the hardware picks packets at random and passes their first bytes to the management CPU, which encodes and sends them.
How does sFlow differ from NetFlow v9 and IPFIX?
NetFlow v9 and IPFIX are flow export protocols. The exporter watches packets, looks each one up in a flow cache keyed on fields such as the 5-tuple, updates counters for that flow, and exports a record when the flow ends or a timeout expires. Both describe their records with templates sent ahead of the data, so the collector learns the layout from the exporter. IPFIX, RFC 7011, is the IETF standard version of that model: it uses message version number 10 (0x000a), requires every compliant implementation to support SCTP with the partial reliability extension, allows TCP and UDP, listens by default on port 4739 and on 4740 for TLS or DTLS, and defines TLS and DTLS for securing the transport. Our NetFlow and IPFIX guide goes through templates, information elements and collectors in depth.
sFlow inverts the workload. The agent sends raw samples and counters immediately, and the collector builds flows, top talker lists and matrices from them.
| Property | sFlow v5 | NetFlow v9 | IPFIX |
|---|---|---|---|
| Published by | sFlow.org (version 4 as informational RFC 3176) | Informational RFC 3954, October 2004 | IETF Standards Track RFC 7011, STD 77, September 2013 |
| What the exporter sends | Individual packet samples (header bytes plus path data) and periodic counters | Flow records built in a cache | Flow records described by templates |
| State on the exporter | None per flow | Flow cache with active and inactive timeouts | Flow cache with timeouts, templates per session |
| Sampling | Mandatory, random 1 in N, rate carried in every sample | Optional, implementation specific | Optional; selection techniques standardised in RFC 5475 and RFC 7014 |
| Payload visibility | First bytes of the packet, default 128 | None in the record itself | None by default |
| Export timing | Within 1 second of the sample | When a flow ends or times out | When a flow ends or times out |
| Encoding | XDR, fixed structures with enterprise and format numbers | Templates and data records | Templates, IANA information element registry, enterprise elements |
| Transport | UDP | UDP, and designed to run over SCTP too | SCTP required for compliance, TCP and UDP optional |
| Default port | 6343 | Not fixed by the RFC; varies by device | 4739, and 4740 for TLS or DTLS |
| Built in security | None; relies on deployment | None | TLS and DTLS defined |
| Interface counters | Built in (counter samples) | Separate, usually SNMP | Separate, usually SNMP |
| Exporter CPU and memory cost | Very low, implementable in switch silicon | Grows with the number of active flows | Grows with the number of active flows |
| Best at | High speed links, big picture traffic matrices, quick detection of large flows, layer 2 visibility | Per flow accounting on routers | Per flow accounting with a standard, extensible format |
| Weak at | Rare and short flows, exact per flow byte counts | Very high flow counts and flood traffic, which fill the cache | Same as NetFlow v9 |
Where the difference shows up in practice
A flood of small packets from random source addresses fills a flow cache with new flows. An sFlow agent samples those packets like any others, so samples keep flowing and the collector sees the flood within seconds. The reverse case is a device that checks in once a minute with a few packets: a flow cache records every check in, while 1 in 1,000 sampling will usually miss it. For a complete record of who talked to whom, use unsampled flow export.
Because sFlow copies the frame header, a layer 2 switch can also report MAC addresses, VLANs and non IP traffic. The protocols are not exclusive: Open vSwitch supports sFlow, NetFlow and IPFIX, and its IPFIX implementation itself samples packets before optionally caching flows.
Decision guide
| You want to | Prefer |
|---|---|
| Watch every port on a large switch fabric with minimal device load | sFlow |
| See floods, microbursts in traffic mix and top talkers within seconds | sFlow |
| Get interface counters and traffic samples from the same feed | sFlow |
| Keep a complete record of every connection for investigations | Unsampled IPFIX or NetFlow at the points that matter |
| Bill or account per flow with exact byte counts | Unsampled IPFIX or NetFlow |
| Encrypt and authenticate the export | IPFIX over TLS or DTLS, or any protocol inside a tunnel |
| Avoid exporting payload bytes | IPFIX or NetFlow, or sFlow with a minimal header size |
What do host sFlow agents add?
The Host sFlow agent (hsflowd) is an open source daemon that, in its project's words, "exports physical and virtual server performance metrics using the sFlow protocol". It runs on Linux, FreeBSD, Solaris, AIX and Windows, according to the install files in its repository, and its news page tracks support for KVM and libvirt (2010), Hyper-V (2012), Docker (2014), Linux network operating systems, and kernel sampling through NFLOG, PCAP with BPF, netlink psample (2019) and eBPF TCX (2025).
What a host agent adds:
- Server counters. The host structures above: CPU, memory, disk and network, sent at the same polling interval as switch counters, so servers and switches show up on the same dashboard.
- Virtual machine and container counters. Per VM and per container metrics, with
host_parentlinking each virtual entity to its host. - Packet sampling on hosts. On NICs, Linux bridges such as
docker0, or through Open vSwitch; on Linux 3.19 or later its PCAP sampling uses kernel BPF, so overhead is low.
The Linux kernel has its own building block: the tc sample action (tc-sample(8)) picks packets at random, optionally truncates them, and delivers them over the psample netlink channel with interfaces, original size, a sequence number and the rate, which is exactly what an sFlow flow sample needs.
What open source collectors exist?
Collectors fall into a few categories. The projects below are described only from their own documentation.
| Category | What it does | Examples from project docs |
|---|---|---|
| Decoder and forwarder | Decodes datagrams to text, JSON or CSV, converts to NetFlow, replicates the feed to other collectors | sflowtool: "Print binary sFlow feed to ASCII, or forward it to other collectors"; outputs ASCII, JSON, CSV, tcpdump format or NetFlow v5 and v9 |
| Multi protocol collector to a pipeline | Receives sFlow, NetFlow and IPFIX, normalises them and hands them to a message queue or storage you choose | GoFlow2: "a NetFlow/IPFIX/sFlow collector in Go"; its docs say storage, enrichment and alerting are not provided |
| Accounting daemon | Aggregates samples into tables in SQL, files, Kafka or AMQP | pmacct's sfacctd (sFlow) alongside nfacctd (NetFlow and IPFIX); official Docker images exist for each |
| Host agent | Generates sFlow from servers, VMs and containers | Host sFlow hsflowd |
| Virtual switch exporter | Generates sFlow from virtual bridges | Open vSwitch sFlow table |
| General packet tools | Decode sFlow datagrams for debugging | tcpdump and Wireshark dissectors |
A small deployment often chains them: agents send to one receiver, which replicates the feed to real time analytics and a long term store.
What are the security and privacy risks?
Section 6 of the sFlow version 5 specification is short and honest. It says sFlow "does not provide specific security mechanisms, relying instead on proper deployment and configuration". Each risk follows directly from the design.
Unauthenticated, unencrypted UDP export
Datagrams cross the network in clear text on UDP 6343, the port registered with IANA for "sFlow traffic monitoring". Anyone on the path can read them. The specification's answer is a secure measurement network, for example VLANs or VPN tunnels that carry only sFlow.
Spoofed datagrams
There is no signature, no key and no session. The specification says the collector "should check sequence numbers and verify source addresses", and that on a secure measurement network only datagrams from that network should be processed. In practice, spoofed datagrams can do three kinds of harm:
- Poisoned analytics. Fake samples can invent traffic that never existed or hide a real spike under noise. If your sFlow feed drives automatic responses such as blackholing or traffic engineering, a forged feed becomes a way to trigger those responses.
- Resource exhaustion and parser attacks. Every datagram is untrusted binary input with nested length fields that the collector must parse, so floods cost CPU and disk, and decoder bugs can crash it. Collector software deserves the same patch discipline as any exposed service.
Packet headers carry personal data
The default 128 byte header is more than the protocol headers. Ethernet (14 bytes), IPv4 (20 bytes) and TCP (20 to 32 bytes with options) leave roughly 60 to 75 bytes of application data in every sample. For UDP the headers take 42 bytes, so a DNS query sample includes about 86 bytes of the DNS message: usually the full query name, which says which site a device was about to visit. Cleartext HTTP samples can include the request line and Host header. The first packet of a TLS connection includes the server name in the ClientHello.
Then there are the extended records. The extended user record carries user identities for the source and destination; the extended URL record carries the HTTP request line and Host. Host agents can associate packets with processes and services. An sFlow store can hold IP addresses, MAC addresses, user names, hostnames and partial URLs, all with timestamps.
The specification's mitigations are fewer header bytes and sampling itself, which makes reconstructing a transaction "virtually impossible". But one sample is enough to record that an address resolved a name at a given time, so treat the store as personal data.
Management plane exposure
Agents can be configured through the SFLOW-MIB over SNMP, and the specification notes that on sensitive devices SNMP configuration may be disabled in favour of the command line. Anyone with SNMP write access could point the agent at their own collector and receive your packet headers, so keep SNMP read only or SNMPv3 with authentication and privacy.
How to protect a collector
| Control | What to do |
|---|---|
| Isolate the path | Carry sFlow on a management VLAN, VRF or encrypted tunnel; never across the internet in clear |
| Allowlist agents | Firewall UDP 6343 on the collector to known agent addresses or subnets; drop everything else |
| Filter spoofing at the edge | Ingress filtering so addresses from your agent ranges cannot arrive from outside |
| Check sequence numbers | Alert on gaps, resets and duplicates per agent and sub agent; they show loss, restarts or injection |
| Cross check agent address | Compare the agent address inside the datagram with the UDP source address |
| Minimise collection | Set header size to the smallest value that meets your needs; disable extended user and URL records you do not use |
| Limit retention | Expire raw samples quickly and keep only aggregates for long periods |
| Restrict access | Role based access to the collector and its database; log queries |
| Patch the pipeline | Keep collector, decoder, database and dashboard software current; track the open source components inside them |
| Do not expose it | No public IP on the collector; no listening on all interfaces when one will do |
Step by step: enable sFlow on a Linux host or Open vSwitch and confirm it arrives
This lab uses two Linux machines on the same private network: a collector at 10.0.0.10 and an agent at 10.0.0.20 with interface eth0. Replace those addresses with your own. Run it on a lab network you control; sFlow samples contain packet headers from whatever traffic passes the agent.
1. Start a collector with sflowtool
On the collector, run sflowtool from its published container image and publish UDP 6343:
docker run --rm -p 6343:6343/udp sflow/sflowtool
Or build it from source as its README describes:
git clone https://github.com/sflow/sflowtool.git
cd sflowtool
./boot.sh
./configure
make
sudo make install
sflowtool -p 6343
Leave it running. It prints nothing until datagrams arrive.
2. Allow only the agent to send
On the collector, restrict UDP 6343 to the agent's address. With nftables:
sudo nft add table inet sflow
sudo nft add chain inet sflow input '{ type filter hook input priority 0; policy accept; }'
sudo nft add rule inet sflow input ip saddr 10.0.0.20 udp dport 6343 accept
sudo nft add rule inet sflow input udp dport 6343 drop
sudo nft list table inet sflow
Docker publishes ports through its own rules, so if you use the container, also bind it to the management address only, for example -p 10.0.0.10:6343:6343/udp, and test the drop rule.
3a. Option A: enable sFlow on Open vSwitch
If the agent runs Open vSwitch, the ovs-vsctl(8) manual gives the exact form. Create a bridge for the lab, then attach an sFlow record:
sudo ovs-vsctl add-br br0
sudo ovs-vsctl -- --id=@s create sFlow agent=eth0 \
target=\"10.0.0.10:6343\" header=128 sampling=64 polling=10 \
-- set Bridge br0 sflow=@s
sudo ovs-vsctl list sFlow
The fields map one to one onto the specification: agent is the address reported to the collector, target is the collector, header is the maximum header size in bytes, sampling is N in 1 in N, and polling is the counter interval in seconds. Sampling 1 in 64 is deliberately dense for a lab so samples appear quickly; production rates are much sparser. To remove it later:
sudo ovs-vsctl -- clear Bridge br0 sflow
3b. Option B: run the Host sFlow agent
To export host counters and sample traffic on a plain Linux server, build hsflowd from its repository, as its INSTALL.Linux file describes. The PCAP module needs libpcap-dev (or libpcap-devel):
git clone https://github.com/sflow/host-sflow.git
cd host-sflow
make FEATURES="HOST PCAP"
sudo make install
sudo make schedule
Then write /etc/hsflowd.conf. This follows the documented manual configuration format, with a dense lab sampling rate on one NIC:
sflow {
agent = eth0
polling = 10
sampling.bps_ratio = 0
sampling = 64
collector { ip = 10.0.0.10 UDPPort = 6343 }
pcap { dev = eth0 }
}
Start it and check which agent address it chose:
sudo systemctl start hsflowd
grep agentIP /etc/hsflowd.auto
On systems without systemd, the project's instructions use sudo service hsflowd start. Check the system log for errors if nothing arrives.
4. Generate some traffic on the agent
Any traffic through the bridge or NIC will do. For example, from the agent:
for i in $(seq 1 200); do curl -s -o /dev/null http://example.com/; done
ping -c 500 -i 0.01 10.0.0.10
Intervals below 0.2 seconds for ping need root on most systems; drop -i 0.01 if you are not running as root.
5. Confirm datagrams arrive with tcpdump
On the collector, watch UDP 6343 and let tcpdump decode the sFlow version 5 headers:
sudo tcpdump -ni any -vv udp port 6343 -c 5
You should see datagrams from 10.0.0.20 to 10.0.0.10 port 6343. tcpdump's sFlow decoder prints a line such as sFlowv5, IPv4 agent 10.0.0.20, agent-id ..., seqnum ..., uptime ..., samples ... for each datagram, and with -vv it adds a line per sample with its sequence number, type, rate, pool and drops for flow samples. Check that the agent address matches the UDP source, that sequence numbers rise by one (gaps mean loss), and that datagrams keep arriving when test traffic stops, because counters have their own schedule.
6. Confirm sampled headers and counters in sflowtool
Back in the sflowtool terminal, look for blocks like these (trimmed; your values will differ):
sampleType FLOWSAMPLE
meanSkipCount 64
samplePool 12864
dropEvents 0
headerProtocol 1
sampledPacketSize 98
headerLen 98
srcIP 10.0.0.20
dstIP 10.0.0.10
IPProtocol 1
and:
sampleType COUNTERSSAMPLE
ifIndex 2
ifInOctets 18176791
ifInUcastPkts 92270
ifInErrors 0
meanSkipCount is the sampling rate and samplePool the number of packets that could have been sampled. Divide the pool by the number of samples you have seen from that source and you should land close to 64. For one line per sample, run sflowtool -p 6343 -l; for JSON, -J.
To decode the sampled headers themselves, pipe them into tcpdump:
sflowtool -p 6343 -t | tcpdump -r - -n
This is where the privacy section stops being abstract: you will see real addresses, ports and the first bytes of each sampled packet.
7. Tidy up
Stop hsflowd or clear the OVS sFlow record, stop the collector, and delete the lab firewall table with sudo nft delete table inet sflow. Delete any capture files you saved: they contain packet headers.
Common mistakes
- Sampling too sparsely on low rate links. One sampling rate copied to every port leaves slow links with a handful of samples per minute, as worked example 2 shows. Scale the rate with link speed, and judge small classes over longer windows.
- Reading per minute numbers for small hosts as facts. Under about 100 samples, the error bound is 20 percent or worse.
- Exposing the collector to the internet. UDP 6343 open to the world invites spoofed data, floods and parser attacks. Allowlist agents and keep the collector on a management network.
- Forgetting that headers contain payload bytes. 128 bytes includes DNS names, HTTP request lines and TLS server names. Size the header to what you need and treat the store as personal data.
- Leaving extended user and URL records on by default. If you do not use user IDs or URLs, turn those records off on the agent.
- Assuming sFlow catches every connection. Rare, short or low volume flows can be missed entirely. Use unsampled flow export or capture where completeness matters.
- Letting SNMP write access reconfigure agents. Anyone who can set the receiver address can redirect your sample stream.
- Not patching the pipeline. Collectors, decoders, databases and dashboards are software with dependencies, and they parse untrusted input continuously.
FAQ
What is sFlow used for?
Continuous traffic monitoring across switches, routers and hosts. sFlow.org lists troubleshooting, real time congestion management, application mix, usage accounting, tracing denial of service sources, route profiling and capacity planning among its uses.
What port does sFlow use?
UDP 6343. The version 5 specification says all agents and applications should default to it, and it is registered with IANA for sFlow traffic monitoring. IPFIX uses 4739 (and 4740 for TLS or DTLS).
Is sFlow the same as NetFlow?
No. sFlow sends random packet samples and interface counters with no flow state on the device. NetFlow and IPFIX build flow records in a cache on the exporter and send summaries when flows end. Collectors often accept both and normalise them.
Is sFlow an IETF standard?
No. Version 4 was published as RFC 3176, an informational RFC that does not specify an Internet standard. Version 5, published in July 2004, is maintained by sFlow.org. IPFIX is the IETF standards track flow export protocol.
How accurate is sFlow sampling?
The 95 percent error bound is about 196 times the square root of 1 over the number of samples in the class you are measuring, in percent. 100 samples gives about 20 percent, 1,000 samples about 6 percent and 10,000 samples about 2 percent, whatever the link speed.
What sampling rate should I use for sFlow?
Start from link speed: the Host sFlow agent defaults to speed divided by 1,000,000 (1 in 1,000 for 1G, 1 in 10,000 for 10G); Open vSwitch defaults to 1 in 400. Then check the classes you care about get enough samples in your reporting window.
Does sFlow capture packet payloads?
It captures the first bytes of each sampled packet, 128 by default. That includes some application data after the headers, such as DNS query names or HTTP request lines. It does not capture full packets or sessions.
Can sFlow monitor servers and containers?
Yes. Host sFlow agents export CPU, memory, disk and network counters for physical servers, hypervisors, virtual machines and containers, and can sample packets on host interfaces and bridges.
What is the difference between sFlow counter polling and SNMP polling?
Both report IF-MIB style interface counters. SNMP is a pull by a poller; sFlow is a push by the agent at a maximum interval, often riding in datagrams that already carry packet samples.
Fix it without waiting for upstream
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation categories include dependencies, licenses, security posture and findings, and each one is set separately. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.
3. Gold Registry: start from components that are already fixed
Gold Registry provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. Ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | Safeguard policies and gates in CI |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
Safeguard does not collect, decode or analyse sFlow, monitor networks or detect attacks in traffic. Switch and router firmware that implements sFlow agents is outside its scope; those fixes come from the device vendor. Where it fits is the software you build and run around the protocol: the repositories and container images for collectors, decoders, enrichment services and dashboards, scanned with safeguard scan --dir . or safeguard scan --image <name>, matched against vulnerability databases, with reachability analysis and policy gates in the platform.
The first demo is a real Safeguard CLI session. You ask it to fix a vulnerable dependency; it reads the finding and the advisory, asks before each command, edits the manifest, runs the install and the tests with your approval, and pushes nothing on its own. The same flow applies to an sFlow enrichment service or a reporting script that pins an outdated library.
Click through it at your own pace, or open it full screen.
The second demo sets up the local runner on your own machine, approves it with a device code and scans from the terminal. sFlow collectors usually sit on management networks without inbound internet access, so running the scan locally lets you check a collector's source tree or image where it already lives.
Click through it at your own pace, or open it full screen.
The third demo connects Claude to the Safeguard MCP server with OAuth and lets you choose which tools Claude can use. A network team could then ask which projects in its monitoring stack contain a given component and version, from the same assistant it uses to review collector configuration.
Click through it at your own pace, or open it full screen.
To try it on your own monitoring repositories and images, download Safeguard and follow the CLI documentation.
Quick check
A host's traffic produces 25 sFlow samples in a five minute window. Roughly how far off could its estimated byte count be?
Using sFlow.org's rule, the 95 percent error bound is 196 times the square root of 1 over 25, which is 196 divided by 5, about 39 percent. Either sample more densely or report that host over a longer window.
Why can an sFlow agent keep working during a flood that overwhelms a flow cache?
The agent keeps no per flow state. It samples 1 in N packets whatever flow they belong to, sends each sample within a second over UDP and lets the collector build flows, so a flood of new flows only raises the packet count, not the agent's memory use.
Sources
- sFlow Version 5 specification, sFlow.org (July 2004)
- sFlow specifications for developers, sFlow.org
- Packet Sampling Basics, sFlow.org
- History of Packet Sampling, sFlow.org
- About sFlow, sFlow.org
- About sFlow.org
- sFlow Host Structures, sFlow.org (July 2010)
- sFlow Dropped Packet Notification Structures, sFlow.org (October 2020)
- RFC 3176, sFlow version 4 (informational)
- RFC 7011, Specification of the IP Flow Information Export (IPFIX) Protocol
- RFC 3954, NetFlow Services Export Version 9
- RFC 5475, Sampling and Filtering Techniques for IP Packet Selection
- RFC 7014, Flow Selection Techniques
- RFC 4506, XDR: External Data Representation Standard
- IANA Service Name and Transport Protocol Port Number Registry
- Host sFlow project home, sflow.net
- Configuring Host sFlow for Linux via /etc/hsflowd.conf, sflow.net
- host-sflow repository and INSTALL.Linux, GitHub
- sflowtool README, GitHub
- Open vSwitch FAQ: General
- ovs-vsctl(8) manual, Open vSwitch
- ovs-vswitchd.conf.db(5), sFlow table, Open vSwitch
- print-sflow.c, tcpdump source, GitHub
- tc-sample(8), Linux manual page
- GoFlow2 README, GitHub
- pmacct README, GitHub
Last reviewed: 24 October 2026. sFlow.org adds structures over time and agent defaults change between releases; check the specification and your installed tool's documentation before relying on a specific structure number, default or flag.