PERFDHCP(8)
โจ perfdhcp โ the DHCP benchmarking tool, but make it a group chat โจ
okay so bestie, you found the perfdhcp(8) page from the Kea manual and honestly? it's a whole vibe. it's section 8, it's a benchmarking tool, and it's about to make you the main character of network performance testing. let's get into it ๐
๐ NAME ๐
perfdhcp โ the DHCP benchmarking tool. that's it, that's the name, slay ๐
๐ธ SYNOPSIS ๐ธ
no cap, this synopsis is long, but every single flag matters so here it is, character for character:
perfdhcp [-1] [-4 | -6] [-A encapsulation-level] [-b base] [-B] [-c] [-C
separator] [-d drop-time] [-D max-drop] [-e lease-type] [-E time-offset]
[-f renew-rate] [-F release-rate] [-g thread-mode] [-h] [-i] [-I
ip-offset] [-J remote-address-list-file] [-l local-address|interface]
[-L local-port] [-M mac-list-file] [-n num-request] [-N remote-port] [-O
random-offset] [-o code,hexstring] [--or
encapsulation-level:code,hexstring] [-p test-period] [-P preload] [-r
rate] [-R num-clients] [-s seed] [-S srvid-offset] [--scenario name] [-t
report] [-T template-file] [-u] [-v] [-W exit-wait-time] [-w
script_name] [-x diagnostic-selector] [-X xid-offset] [server]
and yes there's a trailing [server] โ you can name the server, it's optional, we love a low-pressure invite ๐ซถ
๐ฆ DESCRIPTION ๐ฆ
so perfdhcp is a DHCP benchmarking tool. what does that even mean? it means it lets you measure how well a DHCP server performs by generating large amounts of traffic from multiple simulated clients. it's literally a fake client army. it can test both IPv4 and IPv6 servers, and it gives you stats about response times and the number of requests that get dropped. the receipts are built in, periodt ๐
the tool supports two different scenarios, each offering certain behaviors to be tested. by default โ that's the basic scenario โ tests run using the full four-packet exchange sequence: DORA for DHCPv4, SARR for DHCPv6 ๐. and there's an option that lets you run tests using the initial two-packet exchange (DO and SA) instead, if you're feeling minimal. you can also configure perfdhcp to send DHCPv6 RENEW and RELEASE messages at a specified rate, in parallel with the DHCPv6 four-way exchanges โ multitasking queen ๐. and by default, if there is no response received within one second, that response is considered lost and perfdhcp just moves on to other transactions. it does not wait around for anyone, and honestly, respect ๐
there's a second scenario, and it's called avalanche, selected via --scenario avalanche. the way it works: it first sends the number of Discovery or Solicit messages specified by the -R option, then a retransmission (with an exponential back-off mechanism) is used for each simulated client, until all requests are answered. it generates a report when all clients receive their addresses, or when it is manually stopped. this scenario is trying to replicate the case where the server is not able to handle the traffic swiftly enough โ because real clients will assume the packet or response was lost and will retransmit, which further increases DHCP traffic. it's a whole feedback loop, sometimes called an avalanche effect, hence the scenario name. iconic naming tbh ๐
heads up bestie: option -p is ignored in the avalanche scenario. don't fight it, it's just how she is ๐
when running a performance test, perfdhcp exchanges packets with the server under test as quickly as possible โ unless the -r parameter is used to limit the request rate. the length of the test can be limited by setting a threshold on any or all of these three things: the number of requests made by perfdhcp, the elapsed time, or the number of requests dropped by the server. three levers, one queen ๐ซถ
๐ TEMPLATES ๐
so to allow the contents of packets sent to the server to be customized, perfdhcp lets you specify template files that determine the contents of the packets. for example, the customized packet may contain a DHCPv6 ORO to request a set of options to be returned by the server, or it may contain the Client FQDN option to request that the server perform DNS updates. this is lowkey the move for discovering performance bottlenecks across different server configurations (e.g. DDNS enabled or disabled) โ vibe check your server setups ๐
up to two template files can be specified on the command line, with each file representing the contents of a particular type of packet, and the type being determined by the test being carried out. for example, if testing DHCPv6:
- with no template files specified on the command line,
perfdhcpgenerates both Solicit and Request packets. - with one template file specified, that file is used as the pattern for Solicit packets:
perfdhcpgenerates the Request packets. - with two template files given on the command line, the first is used as the pattern for Solicit packets, and the second as the pattern for Request packets.
(a similar determination applies to DHCPv4's DHCPDISCOVER and DHCPREQUEST packets.) see, consistent queen behavior across both protocols โจ
the template file holds the DHCP packet, represented as a stream of ASCII hexadecimal digits; it excludes any IP/UDP stack headers. and the file must not contain any characters other than hexadecimal digits and spaces. spaces are discarded when the template file is parsed โ so in the file, 12B4 is the same as 12 B4, which is the same as 1 2 B 4. spaces are decorative, the hex is the moment ๐
the template files should be used in conjunction with the command-line parameters which specify offsets of the data fields being modified in outbound packets. for example, the -E time-offset switch specifies the offset of the DHCPv6 Elapsed Time option in the packet template. if the offset is specified, perfdhcp injects the current elapsed-time value into this field before sending the packet to the server. it's giving โจprecisionโจ
in many scenarios, perfdhcp needs to simulate multiple clients, each having a unique client identifier. and since packets for each client are generated from the same template file, it's necessary to randomize the client identifier (or HW address in DHCPv4) in the packet created from it. the -O random-offset option lets you specify the offset in the template where randomization should be performed. and here's the important part bestie, do not skip this:
it's important to note that this offset points to the end (not the beginning) of the client identifier (or HW address field). ๐
the number of bytes being randomized depends on the number of simulated clients:
- if the number of simulated clients is between 1 and 255, only one byte (the one the randomization offset points to) is randomized.
- if the number of simulated clients is between 256 and 65535, two bytes are randomized. note that the last two bytes of the client identifier are randomized in this case: the byte which the randomization offset parameter points to, and the one which precedes it (
random-offset - 1). - if the number of simulated clients exceeds 65535, three bytes are randomized, and so on.
perfdhcp can also simulate traffic from multiple subnets by enabling option -J and passing a path to a file that contains v4 or v6 addresses to be used as relays in generated messages. that enables testing of vast numbers of Kea shared networks ๐. while testing DHCPv4, Kea should be started with the KEA_TEST_SEND_RESPONSES_TO_SOURCE environment variable, to force Kea to send generated messages to the source address of the incoming packet. write that one down, iykyk ๐ซถ
and one lil caveat to close this section: templates may currently be used to generate packets being sent to the server in 4-way exchanges, i.e. Solicit, Request (DHCPv6) and DHCPDISCOVER, DHCPREQUEST (DHCPv4). they cannot be used when Renew or DHCPRELEASE packets are being sent. that's just the rules, no cap ๐
โจ OPTIONS โจ
okay bestie, buckle up, because this is where the flags live and there are so many of them ๐ you're gonna eat this list up, i promise. every single one, no skipping, fr fr.
-1โ grabs the server-id option straight out of the first message you receive. like, first one in, that's the one we trust ๐ซถ-4โ turns on DHCPv4 mode, and ngl this one is the default. it is incompatible with-6, so don't even try to run them together ๐ โโ๏ธ-6โ turns on DHCPv6 mode. also incompatible with-4. pick a lane, bestie โจ-bbasetype=value โ this sets the base MAC or DUID used to simulate all your different clients. the basetype can bemacorduid(and btw the keywordetheris also allowed as a stand-in for MAC ๐). you can stack-bmultiple times, so go off. the MAC address has to be six octets separated by single (:) or double (::) colons, like:mac=00:0c:01:02:03:04. the DUID value is a hexadecimal string, and it must be at least six octets long, not longer than 64 bytes, and the length has to be less than 128 hexadecimal digits. for example:duid=0101010101010101010110111F14. got it? iconic ๐-ddrop-time โ the amount of time after which a request is treated as lost. value is in seconds and may have a fractional component, so yes you can be precise about it. the default is1.-elease-type โ tells the server what kind of lease you're asking for. it's giving picky (respectfully). it can be one of these:address-onlyโ only regular addresses (v4 or v6) get requested. simple, clean.prefix-onlyโ only IPv6 prefixes get requested.address-and-prefixโ both IPv6 addresses and prefixes get requested. greedy in a cute way.
heads up: the -e prefix-only and -e address-and-prefix forms may not be used with the -4 option. v4 doesn't do prefixes, babes ๐ญ
-Frelease-rate โ sets the rate at which DHCPv4 DHCPRELEASE or DHCPv6 Release requests get sent to a server. this value is only valid when you're also using the exchange rate (that's-r rate). and listen: the sum of this value plus the renew-rate (-f rate) must be equal to or less than the exchange rate. math is math ๐งฎ-frenew-rate โ sets the rate at which DHCPv4 DHCPREQUEST or DHCPv6 Renew requests get sent. same deal: only valid alongside the exchange rate (-r rate), and the sum of this plus the release-rate (-F rate) must be equal to or less than the exchange rate. periodt.-gthread-mode โ lets you pick the thread mode, which is eithersingleormulti. in multi-thread mode, packets get received in a separate thread, which uses your CPUs way better ๐ฅ. but on a single-CPU system, it's better to run in one thread so the threads don't block each other. if your system has more than one CPU, multi-thread is the default; otherwise single-thread is the default. no cap.-hโ prints help and exits. the "just tell me what to do" button ๐ซถ-iโ only does the initial part of the exchange: DISCOVER-OFFER if-4is selected, Solicit-Advertise if-6is chosen.
okay so-iis picky too: it is incompatible with the following options:-1,-d,-D,-E,-S,-Iand-F. on top of that, it cannot be used with multiple instances of-O,-T, and-X. don't fight it ๐
-Jremote-address-list-file โ points to a text file with a bunch of addresses in it, and it's designed to test shared networks. if you give it one, perfdhcp randomly picks one of those addresses for every exchange, generating traffic from multiple subnets ๐. when you're testing DHCPv4, you should start it with theKEA_TEST_SEND_RESPONSES_TO_SOURCE=ENABLEenvironment variable โ otherwise perfdhcp literally won't be able to receive responses. it's giving ghosted ๐-llocal-addr|interface โ for DHCPv4 operation, this specifies the local hostname/address to use when talking to the server. by default, the interface address that traffic would normally be routed through to reach the server gets used. for DHCPv6 operation, it specifies the name of the network interface through which exchanges are initiated. different vibe per protocol, iykyk.-Llocal-port โ the local port to use. must be zero or a positive integer up to65535. a value of0(the default) lets perfdhcp pick its own port. main character energy, it chooses for itself โจ-Mmac-list-file โ a text file with a list of MAC addresses, one per line. if you give it one, a MAC address gets chosen randomly from the list for every new exchange ๐ฒ. in DHCPv6, those MAC addresses are used to generate DUID-LLs. and bestie, this parameter must not be used together with the-bparameter. they do not coexist ๐ โโ๏ธ-Nremote-port โ the remote port to use. must be zero or a positive integer up to65535. a value of0(the default) lets perfdhcp choose the standard service port.-ocode,hexstring โ forces perfdhcp to insert the extra option (or options, if you use it multiple times) you specify into the packets being transmitted. the code is the option code, and the hexstring is a hexadecimal string that defines the content of the option. โ ๏ธ careful though, because perfdhcp offers no logic behind these options โ they just get inserted into packets and sent exactly as-is. and don't be out here duplicating options that are already inserted, that's messy. for example, to insert the client-class identifier (option code 60) with the string"docsis", you'd use-o 60,646f63736973.-omay be used multiple times. and psst: the protocol family (-4or-6) must be specified before using-o.-Ppreload โ kicks off preload exchanges back-to-back at startup. must be0(the default) or a positive integer.-rrate โ sets the rate of DORA/SARR exchanges per second (or, if-iis given, DO/SA). a periodic report gets generated showing how many exchanges were not completed, plus the average response latency ๐. the program keeps going until you interrupt it, and at that point a final report is generated. it's giving "i could do this all day" ๐-Rnum-clients โ how many different clients to use. with a value of1(the default), all requests appear to come from the same client. must be a positive number. clone army vibes when you raise it ๐-sseed โ the seed for randomization, which makes runs of perfdhcp repeatable. must be0or a positive integer. the value0means a seed is not used, and that's the default.--scenarioname โ the type of scenario, which can bebasic(the default) oravalanche. yes, avalanche, as dramatic as it sounds ๐จ๏ธ-Ttemplate-file โ a file containing the template to use, as a stream of hexadecimal digits. this may be specified up to two times, and it controls the contents of the packets sent (go read the "Templates" section above, bestie ๐).-uโ enables checks for address uniqueness. heads up: the lease valid-lifetime should not be shorter than the test duration, and clients should not request an address more than once without releasing it. be responsible with this one ๐-vโ displays the Kea version. quick lil flex.-Vโ displays the extended Kea version. extra details, extra slay ๐-Wexit-wait-time โ the exit-wait-time parameter, which makes perfdhcp wait a certain amount of time after an exit condition has been met, so it can receive all the packets without sending any new ones. expressed in microseconds. if you don't specify it,0is used โ meaning it exits immediately after the exit conditions are met. bye bestie ๐-wscript_name โ the name of the script to run before/after perfdhcp. when it's called, the script gets passed a single parameter, either"start"or"stop", telling it whether it's running before or after perfdhcp. cute lil handoff ๐-xdiagnostic-selector โ includes extended diagnostics in the output. it's a string of single keywords specifying which operations you want verbose output for. the selector key letters are:aโ prints the decoded command-line arguments.eโ prints the exit reason.iโ prints the rate-processing details.lโ prints the received leases.sโ prints the first server ID.tโ when finished, prints timers of all successful exchanges.Tโ when finished, prints templates.
-Yseconds โ the time in seconds after which perfdhcp starts simulating the client waiting longer for server responses. this increases the secs field in DHCPv4 and sends increased values in the Elapsed Time option in DHCPv6. must be used with-y. they're a package deal ๐ซ-yseconds โ the time in seconds during which perfdhcp simulates the client waiting longer for server responses. this increases the secs field in DHCPv4 and sends increased values in the Elapsed Time option in DHCPv6. must be used with-Y. same package, other half ๐
๐ DHCPV4-ONLY OPTIONS ๐
the following options only apply for DHCPv4 (i.e. when -4 is given). v4 girlies, this section is for you.
-Bโ forces broadcast handling. loud and proud, no cap ๐ข
๐ธ DHCPV6-ONLY OPTIONS ๐ธ
the following options only apply for DHCPv6 (i.e. when -6 is given). v6 besties, come get your food.
-cโ adds a rapid-commit option (and the exchanges are Solicit-Advertise). fast and efficient, we love her โก-Aencapsulation-level โ says that relayed traffic must be generated. the argument specifies the level of encapsulation, i.e. how many relay agents are being simulated. currently the only supported encapsulation-level value is1, which means the generated traffic is equivalent to the amount of traffic passing through a single relay agent. one relay, one vibe ๐ฆ--orencapsulation-level:code,hexstring โ forces perfdhcp to insert the extra option (or options, if used multiple times) you specify into a relayed DHCPv6 message at the given level of encapsulation; currently the only supported encapsulation-level value is1. this one is very similar to-o: the code is the option code, and the hexstring is a hexadecimal string defining the option's content. โ ๏ธ again, careful, because perfdhcp has no logic behind the options โ they're simply inserted into packets and sent as-is.encapsulation-level:is optional; if you leave it out, the default encapsulation-level value1gets used. for example, to insert the Subscriber identifier (option code 38) with a value1234at the first level of encapsulation, use--or 38,31323334or--or 1:38,31323334.--ormay be used multiple times, and it must be used in conjunction with-A. no-A, no--or, that's the rule ๐
โจ TEMPLATE-RELATED OPTIONS โจ
Okay bestie, these ones are the template glow-up squad โ they only work alongside -T, and they decide how perfdhcp remixes your template. And the way that you can pass them more than once on the command line? Each occurrence pokes the corresponding template file (peep the "Templates" section above, iykyk). ๐
-Etime-offset โ Sets the offset of thesecsfield (DHCPv4) or the Elapsed Time option (DHCPv6) inside the second template, aka the Request one. Gotta be0or a positive integer, and0just turns the whole thing off. ๐-Iip-offset โ Sets the offset of the IP address (DHCPv4, in the requested-ip option) or theIA_NAoption (DHCPv6), inside that same second (Request) template. ๐-Orandom-offset โ Sets the offset of the last octet to randomize in the template. Has to be an integer greater than 3, and fr fr you must also pass the-Tswitch to use this one. ๐ฒ-Ssrvid-offset โ Sets the offset of the server-id option in the second (Request) template. Must be a positive integer, and this switch only works when the template option (-T) is also given. ๐-Xxid-offset โ Sets the offset of the transaction ID (xid) in the template. Positive integer only, and again: this switch can only be used when the template option (-T) is also given. ๐
๐งช OPTIONS CONTROLLING A TEST ๐งช
These are the ones that actually drive the chaos. ๐ฅ
-Dmax-drop โ Aborts the test immediately ifmax-droprequests have been dropped. Want it to bail on even a single drop?-D 1, iconic.max-dropmust be a positive integer. But ifmax-drophas the%suffix, it means the max percentage of requests that may be dropped before aborting โ and in that case, testing of the threshold doesn't even start until 10 requests are expected to have been received. Math queen behavior. ๐-nnum-requests โ Kicks offnum-requesttransactions. No report until all the transactions have been initiated/waited-for, and then you get your report and the program peaces out. ๐-ptest-period โ Sends requests fortest-period, specified the exact same way as-d. This can be an alternative to-n, or you can give both โ in which case the testing wraps up as soon as either limit is hit. Two limits, one finish line. ๐-tinterval โ Sets the delay, in seconds, between two successive reports. โฑ๏ธ-Cseparator โ Suppresses the preliminary output and makes the interim data contain only the values delimited byseparator. Use it with-tto produce super easily parsable reports at-tintervals. Parser girlies, this one's for you. ๐ซถ
๐ฅ ARGUMENTS ๐ฅ
- server โ The server to test, given as an IP address. For the DHCPv6 case, the special name
allcan be used to refer toAll_DHCP_Relay_Agents_and_Servers(the multicast addressFF02::1:2), or the special nameserversto refer toAll_DHCP_Servers(the multicast addressFF05::1:3). The server is mandatory โ unless you gave-lto specify an interface, in which case it just defaults toall. ๐
๐ ERRORS ๐
perfdhcp can report these lil' errors during the packet exchange, and honestly? Not the vibe.
tooshortโ A message was received that was too short. smol. ๐orphansโ A message was received that doesn't match one sent to the server โ meaning it's a duplicate message, a message that showed up after an excessive delay, or one that's just straight up not recognized. No thoughts, no matching parent. ๐ญlocallimitโ Local system limits have been reached when sending a message. We hit the ceiling, bestie. ๐งฑ
๐ช EXIT STATUS ๐ช
perfdhcp dips out with one of these codes:
0โ Success. Slay. โจ1โ General error.2โ Error in command-line arguments. (typo era, we've all been there ๐)3โ No general failures in operation, but one or more exchanges were unsuccessful. So close, yet so far. ๐
๐ธ USAGE EXAMPLES ๐ธ
Okay here's the fun part. ๐
This one simulates regular DHCPv4 traffic from 100 DHCPv4 devices (-R 100), 10 packets per second (-r 10), shows the query/response rate details (-xi), shows a report every 2 seconds (-t 2), and sends the packets to the IP 192.0.2.1:
sudo perfdhcp -xi -t 2 -r 10 -R 100 192.0.2.1
Now a similar situation but for DHCPv6. Note that the DHCPv6 protocol uses link-local addresses, so you must specify the interface (eth0 in this example) to send the traffic on. And all is a convenience alias for All_DHCP_Relay_Agents_and_Servers (the multicast address FF02::1:2). You can also use the servers alias to refer to All_DHCP_Servers (the multicast address FF05::1:3). The default is all. ๐ฆ
sudo perfdhcp -6 -xi -t 1 -r 1 -R 10 -l eth0 all
The next two examples simulate normal DHCPv4 and DHCPv6 traffic that, after 3 seconds, starts pretending not to receive any responses from the server for 10 seconds. The DHCPv4 protocol signals this with an increased secs field, while DHCPv6 uses the Elapsed Time option. In real networks, this means clients aren't getting responses in a timely matter. It can be used to simulate some HA scenarios, since Kea uses the secs field and the Elapsed Time option value as one of the indicators that the HA partner is not responding. When you enable it with -y and -Y, the secs and Elapsed Time values increase steadily. ๐
sudo perfdhcp -xi -t 1 -r 1 -y 10 -Y 3 192.0.2.1
sudo perfdhcp -6 -xi -t 1 -r 1 -y 10 -Y 3 2001:db8::1
๐ DOCUMENTATION ๐
Kea comes with an extensive Kea Administrator Reference Manual that covers literally every aspect of running the Kea software โ compilation, installation, configuration, configuration examples, and so much more. Kea also features a Kea Messages Manual, which lists all possible messages Kea can print with a brief description for each of them. Both documents are available in various formats (.txt, .html, .pdf) with the Kea distribution. The Kea documentation lives at โ https://kea.readthedocs.io. ๐
Kea source code is documented in the Kea Developer's Guide, available at https://reports.kea.isc.org/dev_guide/. ๐ค
The Kea project website is available at https://kea.isc.org. ๐
๐ MAILING LISTS AND SUPPORT ๐
There are two public mailing lists for the Kea project. kea-users (kea-users at lists.isc.org) is for Kea users, while kea-dev (kea-dev at lists.isc.org) is for Kea developers, prospective contributors, and other advanced users. Both lists are available at https://lists.isc.org. The community provides best-effort support on both of those lists. ๐ซ
ISC provides professional support for Kea services. See โ https://www.isc.org/kea/ for details. ๐ผ
๐ฐ๏ธ HISTORY ๐ฐ๏ธ
The perfdhcp tool was initially coded in October 2011 by John DuBois, Francis Dupont, and Marcin Siodelski of ISC. Kea 1.0.0, which included perfdhcp, was released in December 2015. Vintage but still ate. ๐
๐ SEE ALSO ๐
kea-dhcp4(8)kea-dhcp6(8)kea-dhcp-ddns(8)kea-ctrl-agent(8)kea-admin(8)kea-netconf(8)keactrl(8)kea-lfc(8)- Kea Administrator Reference Manual.
โ๏ธ AUTHOR โ๏ธ
Internet Systems Consortium
ยฉ๏ธ COPYRIGHT ยฉ๏ธ
2019-2025, Internet Systems Consortium
And that's a wrap on the whole page, bestie!! ๐ This was Kea version 3.0.4, dated Oct 05, 2026 โ go forth, perfdhcp responsibly, and remember: no dropped packets, only dropped drama. ๐โจ๐ฆ
๐ฆ where this page comes from
- fedora 43: kea 3.0.4-1.fc43 ยท MPL-2.0 AND BSL-1.0
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms