IRTT-CLIENT(1)
π IRTT-CLIENT(1) π
okay so bestie, this is a page straight out of the IRTT Manual, and it's literally the client half of the whole irtt situation. grab a strawberry drink π, we're going in.
β¨ NAME β¨
irtt-client β Isochronous Round-Trip Time Client π¦
π SYNOPSIS π
irtt client [args]
πΈ DESCRIPTION πΈ
irtt client is the client for irtt(1). that's it, that's the sentence, she's the one who calls up the server and starts the whole vibe. π
π OPTIONS π
-dduration β total time to send (default1m0s, see Duration units down below bestie)-iinterval β send interval (default1s, see Duration units below)-llength β length of packet (default0, and it gets increased as necessary for required headers). the common values, the ones you'll actually see in the wild:1472β max unfragmented size of IPv4 datagram for 1500 byte MTU1452β max unfragmented size of IPv6 datagram for 1500 byte MTU
-ofile β write JSON output to file (use-for stdout, and note that output to stdout is not gzipped). the extension you pick for the file controls the gzip behavior like this:- no extension β extension
.json.gzis added, output is gzipped .json.gzβ output is gzipped.gzβ output is gzipped, extension changed to.json.gz.jsonβ output is not gzipped
- no extension β extension
-qβ quiet mode, suppress per-packet output π€«-Qβ really quiet, suppress all output except errors to stderr πΆ-nβ no test: connect to the server and validate test parameters but don't actually run the test. it's giving "rehearsal, not the show" π--stats=statsβ server stats on received packets (defaultboth). possible values:noneβ no server stats on received packetscountβ total count of received packetswindowβ receipt status of last 64 packets with each replybothβ both count and window
--tstamp=modeβ server timestamp mode (defaultboth). possible values:noneβ request no timestampssendβ request timestamp at server sendreceiveβ request timestamp at server receivebothβ request both send and receive timestampsmidpointβ request midpoint timestamp (send/receive avg)
--clock=clockβ clock/s used for server timestamps (defaultboth). possible values:wallβ wall clock onlymonotonicβ monotonic clock onlybothβ both clocks
--dscp=dscpβ DSCP (ToS) value (default0, and0xprefix means hex). common values:0β Best effort8β CS1- Bulk40β CS5- Video46β EF- Expedited forwarding
DSCP & ToS reference: https://www.tucny.com/Home/dscp-tos π
--df=DFβ setting for do not fragment (DF) bit in all packets. possible values:defaultβ OS defaultfalseβ DF bit not settrueβ DF bit set
--wait=waitβ wait time at end of test for unreceived replies (default3x4s). possible values:#xdurationβ # times max RTT, or duration if no response#rdurationβ # times RTT, or duration if no responsedurationβ fixed duration (see Duration units below)
examples, because examples slay:
3x4sβ 3 times max RTT, or 4 seconds if no response1500msβ fixed 1500 milliseconds
--timer=timerβ timer for waiting to send packets (defaultcomp). possible values:simpleβ Go's standardtime.Timercompβ simple timer with error compensation (see-tcomp)hybrid:#β hybrid comp/busy timer with sleep factor (default0.95)busyβ busy wait loop (high precision and CPU, blasphemy π)
--tcomp=algβ comp timer averaging algorithm (defaultexp:0.10). possible values:avgβ cumulative average errorwin:#β moving average error with window # (default5)exp:#β exponential average with alpha # (default0.10)
--fill=fillβ fill payload with given data (defaultnone). possible values:noneβ leave payload as all zeroesrandβ use random bytes from Go'smath.randpattern:XXβ use repeating pattern of hex (default69727474)
--fill-oneβ fill only once and repeat for all packets π--sfill=fillβ request server fill (default not specified). see the values for--fill. the server must support and allow this fill with--allow-fills.--local=addrβ local address (default from OS). possible values::portβ unspecified address (all IPv4/IPv6 addresses) with porthostβ host with dynamic port, see Host formats belowhost:portβ host with specified port, see Host formats below
--hmac=keyβ add HMAC with key (0xfor hex) to all packets. it provides:- dropping of all packets without a correct HMAC
- protection for the server against unauthorized discovery and use π
-4β IPv4 only-6β IPv6 only--timeouts=durationsβ timeouts used when connecting to server (default1s,2s,4s,8s). it's a comma separated list of durations (see Duration units below). total wait time will be up to the sum of these durations. max packets sent is up to the number of durations. minimum timeout duration is200ms.--ttl=ttlβ time to live (default0, meaning use OS default)--looseβ accept and use any server restricted test parameters instead of exiting with nonzero status. chill vibes only π§--threadβ lock sending and receiving goroutines to OS threads-hβ show help-vβ show version
π¦ Host formats π¦
hosts may be either hostnames (for IPv4 or IPv6) or IP addresses. IPv6 addresses must be surrounded by brackets and may include a zone after the % character. examples, bestie:
- IPv4 IP β
192.168.1.10 - IPv6 IP β
[2001:db8:8f::2/32] - IPv4/6 hostname β
localhost
note: IPv6 addresses must be quoted in most shells. no cap, your shell will simply not get it otherwise. π
β³ Duration units β³
durations are a sequence of decimal numbers, each with optional fraction, and unit suffix, like "300ms", "1m30s" or "2.5m". sanity not enforced π.
hβ hoursmβ minutessβ secondsmsβ millisecondsnsβ nanoseconds
π OUTPUT π
IRTT's JSON output format consists of five top-level objects:
versionsystem_infoconfigstatsround_trips
these are documented through the examples below. all attributes are present unless otherwise noted. π
β version β
version information:
"version": {
"irtt": "0.9.0",
"protocol": 1,
"json_format": 1
},
irttβ the IRTT version numberprotocolβ the protocol version number (increments mean incompatible changes)json_formatβ the JSON format number (increments mean incompatible changes)
β system_info β
a few basic pieces of system information:
"system_info": {
"os": "darwin",
"cpus": 8,
"go_version": "go1.9.2",
"hostname": "tron.local"
},
osβ the Operating System from Go'sruntime.GOOScpusβ the number of CPUs reported by Go'sruntime.NumCPU(), which reflects the number of logical rather than physical CPUs. in the example below, the number8is reported for a Core i7 (quad core) with hyperthreading (2 threads per core).go_versionβ the version of Go the executable was built withhostnameβ the local hostname
β config β
the configuration used for the test
okay so the config object in the JSON output is giving full detail realness, and it looks like this:
"config": {
"local_address": "127.0.0.1:51203",
"remote_address": "127.0.0.1:2112",
"open_timeouts": "1s,2s,4s,8s",
"params": {
"proto_version": 1,
"duration": 600000000,
"interval": 200000000,
"length": 48,
"received_stats": "both",
"stamp_at": "both",
"clock": "both",
"dscp": 0,
"server_fill": ""
},
"loose": false,
"ip_version": "IPv4",
"df": 0,
"ttl": 0,
"timer": "comp",
"waiter": "3x4s",
"filler": "none",
"fill_one": false,
"thread_lock": false,
"supplied": {
"local_address": ":0",
"remote_address": "localhost",
"open_timeouts": "1s,2s,4s,8s",
"params": {
"proto_version": 1,
"duration": 600000000,
"interval": 200000000,
"length": 0,
"received_stats": "both",
"stamp_at": "both",
"clock": "both",
"dscp": 0,
"server_fill": ""
},
"loose": false,
"ip_version": "IPv4+6",
"df": 0,
"ttl": 0,
"timer": "comp",
"waiter": "3x4s",
"filler": "none",
"fill_one": false,
"thread_lock": false
}
},
local_addressβ the local address (IP:port) for the client πremote_addressβ the remote address (IP:port) for the server πopen_timeoutsβ a list of timeout durations used after an open packet is sent β³paramsβ the parameters that were negotiated with the server, including:proto_versionβ protocol version number π’durationβ duration of the test, in nanoseconds β±οΈintervalβ send interval, in nanoseconds β²οΈlengthβ packet length πreceived_statsβ statistics for packets received by server (none,count,windoworboth,--statsflag for irtt client) πstamp_atβ timestamp selection parameter (none,send,receive,bothormidpoint,--tstampflag for irtt client) π°οΈclockβ clock selection parameter (wallormonotonic,--clockflag for irtt client) π°οΈdscpβ the DSCP (https://en.wikipedia.org/wiki/Differentiated_services) value ποΈserver_fillβ the requested server fill (--sfillflag for irtt client) π§Ί
looseβ if true, client accepts and uses restricted server parameters, with a warning β οΈip_versionβ the IP version used (IPv4orIPv6) πdfβ the do-not-fragment setting (0== OS default,1== false,2== true) π§©ttlβ the IP time-to-live (https://en.wikipedia.org/wiki/Time_to_live) value β³timerβ the timer used:simple,comp,hybridorbusy(irtt client--timerflag) β±οΈtime_sourceβ the time source used:goorwindowsπ₯οΈwaiterβ the waiter used: fixed duration, multiple of RTT or multiple of max RTT (irtt client--waitflag) β³fillerβ the packet filler used:none,randorpattern(irtt client--fillflag) π¨fill_oneβ whether to fill only once and repeat for all packets (irtt client--fill-oneflag) 1οΈβ£thread_lockβ whether to lock packet handling goroutines to OS threads πsuppliedβ a nested config object with the configuration as originally supplied to the API or irtt command. The supplied configuration can differ from the final configuration in the following ways:local_addressandremote_addressmay have hostnames or named ports before being resolved to an IP and numbered port π·οΈip_versionmay beIPv4+6before it is determined after address resolution πparamsmay be different before the server applies restrictions based on its configuration π οΈ
stats π
and the stats object is where the receipts live. It's literally statistics for the results:
"stats": {
"start_time": {
"wall": 1528621979787034330,
"monotonic": 5136247
},
"send_call": {
"total": 79547,
"n": 3,
"min": 17790,
"max": 33926,
"mean": 26515,
"stddev": 8148,
"variance": 66390200
},
"timer_error": {
"total": 227261,
"n": 2,
"min": 59003,
"max": 168258,
"mean": 113630,
"stddev": 77254,
"variance": 5968327512
},
"rtt": {
"total": 233915,
"n": 2,
"min": 99455,
"max": 134460,
"mean": 116957,
"median": 116957,
"stddev": 24752,
"variance": 612675012
},
"send_delay": {
"total": 143470,
"n": 2,
"min": 54187,
"max": 89283,
"mean": 71735,
"median": 71735,
"stddev": 24816,
"variance": 615864608
},
"receive_delay": {
"total": 90445,
"n": 2,
"min": 45177,
"max": 45268,
"mean": 45222,
"median": 45222,
"stddev": 64,
"variance": 4140
},
"server_packets_received": 2,
"bytes_sent": 144,
"bytes_received": 96,
"duplicates": 0,
"late_packets": 0,
"wait": 403380,
"duration": 400964028,
"packets_sent": 3,
"packets_received": 2,
"packet_loss_percent": 33.333333333333336,
"upstream_loss_percent": 33.333333333333336,
"downstream_loss_percent": 0,
"duplicate_percent": 0,
"late_packets_percent": 0,
"ipdv_send": {
"total": 35096,
"n": 1,
"min": 35096,
"max": 35096,
"mean": 35096,
"median": 35096,
"stddev": 0,
"variance": 0
},
"ipdv_receive": {
"total": 91,
"n": 1,
"min": 91,
"max": 91,
"mean": 91,
"median": 91,
"stddev": 0,
"variance": 0
},
"ipdv_round_trip": {
"total": 35005,
"n": 1,
"min": 35005,
"max": 35005,
"mean": 35005,
"median": 35005,
"stddev": 0,
"variance": 0
},
"server_processing_time": {
"total": 20931,
"n": 2,
"min": 9979,
"max": 10952,
"mean": 10465,
"stddev": 688,
"variance": 473364
},
"timer_err_percent": 0.056815,
"timer_misses": 0,
"timer_miss_percent": 0,
"send_rate": {
"bps": 2878,
"string": "2.9 Kbps"
},
"receive_rate": {
"bps": 3839,
"string": "3.8 Kbps"
}
},
Note: In the stats object, a duration stats class of object repeats and will not be repeated in the individual descriptions. It contains statistics about nanosecond duration values and has the following attributes:
totalβ the total of the duration valuesnβ the number of duration valuesminβ the minimum duration valuemaxβ the maximum duration valuemeanβ the mean duration valuestddevβ the standard deviationvarianceβ the variance
The regular attributes in stats are as follows:
start_timeβ the start time of the test (see round_trips Notes for descriptions ofwallandmonotonicvalues)send_callβ a duration stats object for the call time when sending packetstimer_errorβ a duration stats object for the observed sleep time errorrttβ a duration stats object for the round-trip timesend_delayβ a duration stats object for the one-way send delay (only available if server timestamps are enabled)receive_delayβ a duration stats object for the one-way receive delay (only available if server timestamps are enabled)server_packets_receivedβ the number of packets received by the server, including duplicates (always present, but only valid if theReceivedStatsparameter includesReceivedStatsCount, or the--statsflag to the irtt client iscountorboth)bytes_sentβ the number of UDP payload bytes sent during the testbytes_receivedβ the number of UDP payload bytes received during the testduplicatesβ the number of packets received with the same sequence numberlate_packetsβ the number of packets received with a sequence number lower than the previously received sequence number (one simple metric for out-of-order packets)waitβ the actual time spent waiting for final packets, in nanosecondsdurationβ the actual duration of the test, in nanoseconds, from the time just before the first packet was sent to the time after the last packet was received and results are starting to be calculatedpackets_sentβ the number of packets sent to the serverpackets_receivedβ the number of packets received from the serverpacket_loss_percentβ100 * (packets_sent - packets_received) / packets_sentupstream_loss_percentβ100 * (packets_sent - server_packets_received / packets_sent)(always present, but only valid ifserver_packets_receivedis valid)downstream_loss_percentβ100 * (server_packets_received - packets_received / server_packets_received)(always present, but only valid ifserver_packets_receivedis valid)duplicate_percentβ100 * duplicates / packets_receivedlate_packets_percentβ100 * late_packets / packets_receivedipdv_sendβ a duration stats object for the send IPDV (https://en.wikipedia.org/wiki/Packet_delay_variation). Only shows up if server timestamps are on, bestie. β¨ipdv_receiveβ a duration stats object for the receive IPDV (https://en.wikipedia.org/wiki/Packet_delay_variation). Same deal, server timestamps must be enabled.ipdv_round_tripβ a duration stats object for the round-trip IPDV (https://en.wikipedia.org/wiki/Packet_delay_variation). This one's available no matter what β server timestamps on or off, she's there. πserver_processing_timeβ a duration stats object for the time the server took after it received the packet to when it sent the response. Only available when both send and receive timestamps are enabled.timer_err_percentβ the mean of the absolute values of the timer error, as a percentage of the interval. Math! β¨timer_missesβ the number of times the timer missed the interval (was at least 50% over the scheduled time). ooftimer_miss_percentβ100 * timer_misses / expected packets sentsend_rateβ the send bitrate (bits-per-second and a corresponding string), calculated using the number of UDP payload bytes sent between the time right before the first send call and the time right after the last send call. πreceive_rateβ the receive bitrate (bits-per-second and a corresponding string), calculated using the number of UDP payload bytes received between the time right after the first receive call and the time right after the last receive call. π¬
π¦ round_trips π¦
okay so each round-trip is a single request to / reply from the server. like, one little conversation. here's what it looks like:
"round_trips": [
{
"seqno": 0,
"lost": false,
"timestamps": {
"client": {
"receive": {
"wall": 1508180723502871779,
"monotonic": 2921143
},
"send": {
"wall": 1508180723502727340,
"monotonic": 2776704
}
},
"server": {
"receive": {
"wall": 1508180723502816623,
"monotonic": 32644353327
},
"send": {
"wall": 1508180723502826602,
"monotonic": 32644363306
}
}
},
"delay": {
"receive": 45177,
"rtt": 134460,
"send": 89283
},
"ipdv": {}
},
{
"seqno": 1,
"lost": false,
"timestamps": {
"client": {
"receive": {
"wall": 1508180723702917735,
"monotonic": 202967099
},
"send": {
"wall": 1508180723702807328,
"monotonic": 202856692
}
},
"server": {
"receive": {
"wall": 1508180723702861515,
"monotonic": 32844398219
},
"send": {
"wall": 1508180723702872467,
"monotonic": 32844409171
}
}
},
"delay": {
"receive": 45268,
"rtt": 99455,
"send": 54187
},
"ipdv": {
"receive": 91,
"rtt": -35005,
"send": -35096
}
},
{
"seqno": 2,
"lost": true,
"timestamps": {
"client": {
"receive": {},
"send": {
"wall": 1508180723902925971,
"monotonic": 402975335
}
},
"server": {
"receive": {},
"send": {}
}
},
"delay": {},
"ipdv": {}
}
]
Note:wallvalues are from Go'stime.Time.UnixNano(), the number of nanoseconds elapsed since January 1, 1970 UTC. π°οΈ
Note: monotonic values are the number of nanoseconds since some arbitrary point in time, so can only be relied on to measure duration. no cap, don't use them as a clock fr fr.
seqnoβ the sequence number. π’lostβ the lost status of the packet, which can be one offalse,true,true_downortrue_up. Thetrue_downandtrue_upvalues are only possible if theReceivedStatsparameter includesReceivedStatsWindow(irtt client --statsflag). Even then, if it could not be determined whether the packet was lost upstream or downstream, the valuetrueis used. πtimestampsβ the client and server timestamps.clientβ the client send and receive wall and monotonic timestamps (receive values only present iflostisfalse).serverβ the server send and receive wall and monotonic timestamps (both send and receive values not present iflostistrue), and additionally:sendvalues are not present if theStampAt(irtt client --tstampflag) does not include send timestamps.receivevalues are not present if theStampAt(irtt client --tstampflag) does not include receive timestamps.wallvalues are not present if theClock(irtt client --clockflag) does not include wall values or server timestamps are not enabled.monotonicvalues are not present if theClock(irtt client --clockflag) does not include monotonic values or server timestamps are not enabled.
delayβ an object containing the delay values.receiveβ the one-way receive delay, in nanoseconds (present only if server timestamps are enabled and at least one wall clock value is available).rttβ the round-trip time, in nanoseconds, always present. πsendβ the one-way send delay, in nanoseconds (present only if server timestamps are enabled and at least one wall clock value is available).
ipdvβ an object containing the IPDV (https://en.wikipedia.org/wiki/Packet_delay_variation) values (attributes present only forseqno > 0, and iflostisfalsefor both the current and previousround_trip).receiveβ the difference in receive delay relative to the previous packet (present only if at least one server timestamp is available).rttβ the difference in round-trip time relative to the previous packet (always present forseqno > 0).sendβ the difference in send delay relative to the previous packet (present only if at least one server timestamp is available).
β¨ EXIT STATUS β¨
irtt client exits with one of the following status codes, bestie β memorize these, they're your vibe check:
0β Success π1β Runtime error π2β Command line error π3β Two interrupt signals received π
π¨ WARNINGS π¨
okay so listen. it is possible with the irtt client to dramatically harm network performance by using intervals that are too low, particularly in combination with large packet lengths. Careful consideration should be given before using sub-millisecond intervals, not only because of the impact on the network, but also because:
- Timer accuracy at sub-millisecond intervals may begin to suffer without the use of a custom kernel or the busy timer (which pins the CPU). π³
- Memory consumption for results storage and system CPU time both rise rapidly. π
- The granularity of the results reported may very well not be required. like, maybe you don't need it?? just saying.
fr fr be careful with this one. sub-millisecond intervals are not a casual decision. π
π EXAMPLES π
$ irtt client localhost
Sends requests once per second for one minute to localhost. easy peasy. β¨
$ irtt client -i 200ms -d 10s -o - localhost
Sends requests every 0.2 sec for 10 seconds to localhost. Writes JSON output to stdout. π
$ irtt client -i 20ms -d 1m -l 172 --fill=rand --sfill=rand 192.168.100.10
Sends requests every 20ms for one minute to 192.168.100.10. Fills both the client and server payload with random data. This simulates a G.711 VoIP conversation, one of the most commonly used codecs for VoIP as of this writing. βοΈ iconic honestly.
$ irtt client -i 0.1s -d 5s -6 --dscp=46 irtt.example.org
Sends requests with IPv6 every 100ms for 5 seconds to irtt.example.org. Sets the DSCP value (ToS field) of requests and responses to 46 (Expedited Forwarding). π¦
$ irtt client --hmac=secret -d 10s "[2001:db8:8f::2/32]:64381"
Sends requests to the specified IPv6 IP on port 64381 every second for 10 seconds. Adds an HMAC to each packet with the key secret. π
π«Ά SEE ALSO π«Ά
irtt(1),irtt-server(1)- IRTT GitHub repository (
https://github.com/heistp/irtt/)
and that's the whole page, bestie!! π this is v0.9.0, dated February 11, 2018, and the man page itself is IRTT-CLIENT(1). go forth and measure your packets, you absolute icon. ππΈ
π¦ where this page comes from
- fedora 43: golang-github-heistp-irtt 0.9.1-15.fc43 Β· GPL-2.0-only
- fedora 43: irtt 0.9.1-1.fc43 Β· BSD-2-Clause AND BSD-3-Clause AND GPL-2.0-only
- fedora 44: golang-github-heistp-irtt 0.9.1-16.fc44 Β· GPL-2.0-only
- fedora 44: irtt 0.9.1-1.fc44 Β· BSD-2-Clause AND BSD-3-Clause AND GPL-2.0-only
- ubuntu resolute: irtt 0.9.1-1 Β· GPL-3.0-only
- ubuntu stonking: irtt 0.9.1-1 Β· GPL-3.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms