Safeguard
Supply Chain Security•

sFlow Explained: Packet Sampling, Counter Polling vs NetFlow and IPFIX

sFlow samples 1 in N packet headers and polls interface counters, sending both over UDP 6343. How it works, its accuracy and how it differs from IPFIX.

Safeguard Security Team
43 min read

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

DateEventSource
1991Network wide monitoring using packet sampling demonstrated at Telecom 91 (University of Geneva and CERN)sFlow.org, History of Packet Sampling
1993Networking products with embedded packet sampling (an extended RMON implementation) introducedsFlow.org, History of Packet Sampling
2001Switches and routers with embedded sFlow sampling availablesFlow.org, History of Packet Sampling
September 2001RFC 3176 publishes sFlow version 4 as an informational RFCRFC 3176
July 2004sFlow version 5 published by sFlow.org; it replaces version 4sFlow version 5 specification
October 2004NetFlow version 9 published as informational RFC 3954RFC 3954
May 2006XDR, the encoding sFlow uses, republished as RFC 4506 (STD 67)RFC 4506
March 2009RFC 5475 standardises packet selection (sampling and filtering) techniques for the IETF's PSAMP workRFC 5475
July 2010sFlow Host Structures published; Host sFlow agent 1.0 released on 23 July 2010sFlow Host Structures; sflow.net
September 2013IPFIX protocol published as RFC 7011, Internet Standard STD 77RFC 7011
June 2014Host sFlow agent adds Docker supportsflow.net news
April 2019Host sFlow agent adds Linux netlink psample supportsflow.net news
October 2020sFlow Dropped Packet Notification Structures publishedsFlow.org specification
July 2025Host sFlow agent adds eBPF TCX supportsflow.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:

  1. A counter is set to a random number whose long run average equals the sampling rate N.
  2. Each packet decrements the counter. A second counter, Total_Packets, counts every packet that could have been sampled, whether it was or not.
  3. When the skip counter reaches zero, the device takes a sample and increments Total_Samples.
  4. 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 sampling column, 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 sampling value 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:

PartFieldsBytes
Sample record wrappersample type and length8
flow_sample fixed fieldssequence number, source ID, sampling rate, sample pool, drops, input, output, record count32
sampled_header recordformat, length, protocol, frame length, stripped, header length, 128 header bytes152
extended_switch recordformat, length, source VLAN and priority, destination VLAN and priority24
Total216

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

StructureFormat numberWhat it carries
Generic interface counters (if_counters)1ifIndex, 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 counters2Alignment 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 counters3Token Ring error statistics
100BaseVG counters4100BaseVG interface statistics
VLAN counters5Per VLAN octets, unicast, multicast and broadcast packets, and discards
Processor information10015 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:

StructureFormat numberWhat it carries
host_descr2000Host name, UUID, machine type, OS name and release
host_adapters2001The NICs or virtual NICs and their MAC addresses
host_parent2002Containment, for example which hypervisor a VM belongs to
host_cpu2003Load averages, process counts, CPU count and speed, uptime, CPU time by state, interrupts, context switches
host_memory2004Total and free memory, shared, buffers, cache, swap, page and swap activity
host_disk_io2005Disk capacity and free space, reads and writes, bytes and time
host_net_io2006Host level network bytes, packets, errors and drops
virt_node, virt_cpu, virt_memory, virt_disk_io, virt_net_io2100 to 2104The 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

FieldSizeMeaning
version4 bytes5
agent address type4 bytes1 for IPv4, 2 for IPv6, 0 for unknown
agent address4 or 16 bytesThe IP address that identifies the agent, not necessarily the UDP source address
sub agent ID4 bytesDistinguishes datagram streams from separate parts of a distributed device, such as line cards
sequence number4 bytesIncremented with each datagram from that sub agent
uptime4 bytesMilliseconds since the device booted
samplesvariableAn 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:

RecordFormat numberWhat it adds
Extended switch1001Source and destination 802.1Q VLAN and 802.1p priority
Extended router1002Next hop, source and destination prefix lengths
Extended gateway1003BGP next hop, AS numbers, AS path, communities, local preference
Extended user1004User IDs associated with the packet's source and destination, with their character sets
Extended URL1005The HTTP request line and Host header
Extended MPLS1006MPLS next hop and label stacks
Extended NAT1007Translated source and destination addresses
Extended MPLS tunnel, VC, FTN, LDP FEC1008 to 1011MPLS tunnel and virtual circuit context
Extended VLAN tunnel1012Stacked 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.

PropertysFlow v5NetFlow v9IPFIX
Published bysFlow.org (version 4 as informational RFC 3176)Informational RFC 3954, October 2004IETF Standards Track RFC 7011, STD 77, September 2013
What the exporter sendsIndividual packet samples (header bytes plus path data) and periodic countersFlow records built in a cacheFlow records described by templates
State on the exporterNone per flowFlow cache with active and inactive timeoutsFlow cache with timeouts, templates per session
SamplingMandatory, random 1 in N, rate carried in every sampleOptional, implementation specificOptional; selection techniques standardised in RFC 5475 and RFC 7014
Payload visibilityFirst bytes of the packet, default 128None in the record itselfNone by default
Export timingWithin 1 second of the sampleWhen a flow ends or times outWhen a flow ends or times out
EncodingXDR, fixed structures with enterprise and format numbersTemplates and data recordsTemplates, IANA information element registry, enterprise elements
TransportUDPUDP, and designed to run over SCTP tooSCTP required for compliance, TCP and UDP optional
Default port6343Not fixed by the RFC; varies by device4739, and 4740 for TLS or DTLS
Built in securityNone; relies on deploymentNoneTLS and DTLS defined
Interface countersBuilt in (counter samples)Separate, usually SNMPSeparate, usually SNMP
Exporter CPU and memory costVery low, implementable in switch siliconGrows with the number of active flowsGrows with the number of active flows
Best atHigh speed links, big picture traffic matrices, quick detection of large flows, layer 2 visibilityPer flow accounting on routersPer flow accounting with a standard, extensible format
Weak atRare and short flows, exact per flow byte countsVery high flow counts and flood traffic, which fill the cacheSame 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 toPrefer
Watch every port on a large switch fabric with minimal device loadsFlow
See floods, microbursts in traffic mix and top talkers within secondssFlow
Get interface counters and traffic samples from the same feedsFlow
Keep a complete record of every connection for investigationsUnsampled IPFIX or NetFlow at the points that matter
Bill or account per flow with exact byte countsUnsampled IPFIX or NetFlow
Encrypt and authenticate the exportIPFIX over TLS or DTLS, or any protocol inside a tunnel
Avoid exporting payload bytesIPFIX 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_parent linking 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.

CategoryWhat it doesExamples from project docs
Decoder and forwarderDecodes datagrams to text, JSON or CSV, converts to NetFlow, replicates the feed to other collectorssflowtool: "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 pipelineReceives sFlow, NetFlow and IPFIX, normalises them and hands them to a message queue or storage you chooseGoFlow2: "a NetFlow/IPFIX/sFlow collector in Go"; its docs say storage, enrichment and alerting are not provided
Accounting daemonAggregates samples into tables in SQL, files, Kafka or AMQPpmacct's sfacctd (sFlow) alongside nfacctd (NetFlow and IPFIX); official Docker images exist for each
Host agentGenerates sFlow from servers, VMs and containersHost sFlow hsflowd
Virtual switch exporterGenerates sFlow from virtual bridgesOpen vSwitch sFlow table
General packet toolsDecode sFlow datagrams for debuggingtcpdump 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

ControlWhat to do
Isolate the pathCarry sFlow on a management VLAN, VRF or encrypted tunnel; never across the internet in clear
Allowlist agentsFirewall UDP 6343 on the collector to known agent addresses or subnets; drop everything else
Filter spoofing at the edgeIngress filtering so addresses from your agent ranges cannot arrive from outside
Check sequence numbersAlert on gaps, resets and duplicates per agent and sub agent; they show loss, restarts or injection
Cross check agent addressCompare the agent address inside the datagram with the UDP source address
Minimise collectionSet header size to the smallest value that meets your needs; disable extended user and URL records you do not use
Limit retentionExpire raw samples quickly and keep only aggregates for long periods
Restrict accessRole based access to the collector and its database; log queries
Patch the pipelineKeep collector, decoder, database and dashboard software current; track the open source components inside them
Do not expose itNo 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 situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingSafeguard policies and gates in CI
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch
You want to start clean on new projectsPull 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

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.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.