First of all, your test case of using sleep and page-faults is not an ideal test case. There should be no page fault events during the sleep duration, you you can't really expect anything interesting. For the sake of easier reasoning I suggest to use the ref-cycles (hardware) event and a busy workload such as awk 'BEGIN { while(1){} }'.

Question 1: It is my understanding that perf stat gets a "summary" of counts but when used with the -I option gets the counts at the specified millisecond interval. With this option does it sum up the counts over the interval or get the average over the interval, or something else entirely? I assume it is summed up.

Yes. The values are just summed up. You can confirm that by testing:

$ perf stat -e ref-cycles -I 1000 timeout 10s awk 'BEGIN { while(1){} }'
#           time             counts unit events
 1.000105072      2,563,666,664      ref-cycles                                                  
 2.000267991      2,577,462,550      ref-cycles                                                  
 3.000415395      2,577,211,936      ref-cycles                                                  
 4.000543311      2,577,240,458      ref-cycles                                                  
 5.000702131      2,577,525,002      ref-cycles                                                  
 6.000857663      2,577,156,088      ref-cycles                                                  

[ ... snip ... ]
[ Note that it may not be as nicely consistent on all systems due dynamic frequency scaling ]

$ perf stat -e ref-cycles -I 3000 timeout 10s awk 'BEGIN { while(1){} }' 
#           time             counts unit events
 3.000107921      7,736,108,718      ref-cycles                                                  
 6.000265186      7,732,065,900      ref-cycles                                                  
 9.000372029      7,728,302,192      ref-cycles     

Question 2: Why doesn't perf stat -e <event1> -I 1000 sleep 5 give about the same counts as if I summed up the counts over each second for the following command perf record -e <event1> -F 1000 sleep 5?

perf stat -I is in milliseconds, whereas perf record -F is in HZ (1/s), so the corresponding command to perf stat -I 1000 is perf record -F 1. In fact with our more stable event/workload, this looks better:

$ perf stat -e ref-cycles -I 1000 timeout 10s awk 'BEGIN { while(1){} }'
#           time             counts unit events
 1.000089518      2,578,694,534      ref-cycles                                                  
 2.000203872      2,579,866,250      ref-cycles                                                  
 3.000294300      2,579,857,852      ref-cycles                                                  
 4.000390273      2,579,964,842      ref-cycles                                                  
 5.000488375      2,577,955,536      ref-cycles                                                  
 6.000587028      2,577,176,316      ref-cycles                                                  
 7.000688250      2,577,334,786      ref-cycles                                                  
 8.000785388      2,577,581,500      ref-cycles                                                  
 9.000876466      2,577,511,326      ref-cycles                                                  
10.000977965      2,577,344,692      ref-cycles                                                  
10.001195845            466,674      ref-cycles    

$ perf record -e ref-cycles -F 1 timeout 10s awk 'BEGIN { while(1){} }'
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.008 MB perf.data (17 samples) ]

$ perf script -F time,period        
3369070.273722:          1 
3369070.273755:          1 
3369070.273911:       3757 
3369070.273916:    3015133 
3369070.274486:          1 
3369070.274556:          1 
3369070.274657:       1778 
3369070.274662:    2196921 
3369070.275523: 47192985748 
3369072.663696: 2578692405 
3369073.663547: 2579122382 
3369074.663609: 2580015300 
3369075.664085: 2579873741 
3369076.664433: 2578638211 
3369077.664379: 2578378119 
3369078.664175: 2578166440 
3369079.663896: 2579238122 

So you see, eventually the results are stable also for perf record -F. Unfortunately the documentation of perf record is very poor. You can learn what the settings -c and -F mean by looking at the documentation of the underlying system call man perf_event_open:

sample_period, sample_freq A "sampling" event is one that generates an overflow notification every N events, where N is given by sample_period. A sampling event has sample_period > 0. When an overflow occurs, requested data is recorded in the mmap buffer. The sample_type field controls what data is recorded on each overflow.

sample_freq can be used if you wish to use frequency rather than period. In this case, you set the freq flag. The kernel will adjust the sampling period to try and achieve the desired rate. The rate of adjustment is a timer tick.

So while perf stat uses an internal timer to read the value of the counter every -i milliseconds, perf record sets an event overflow counter to take a sample every -c events. That means it takes a sample every N events (e.g. every N page-fault or cycles). With -F, it it tries to regulate this overflow value to achieve the desired frequency. It tries different values and tunes it up/down accordingly. This eventually works for counters with a stable rate, but will get erratic results for dynamic events.

Answer from Zulan on Stack Overflow
Top answer
1 of 1
12

First of all, your test case of using sleep and page-faults is not an ideal test case. There should be no page fault events during the sleep duration, you you can't really expect anything interesting. For the sake of easier reasoning I suggest to use the ref-cycles (hardware) event and a busy workload such as awk 'BEGIN { while(1){} }'.

Question 1: It is my understanding that perf stat gets a "summary" of counts but when used with the -I option gets the counts at the specified millisecond interval. With this option does it sum up the counts over the interval or get the average over the interval, or something else entirely? I assume it is summed up.

Yes. The values are just summed up. You can confirm that by testing:

$ perf stat -e ref-cycles -I 1000 timeout 10s awk 'BEGIN { while(1){} }'
#           time             counts unit events
 1.000105072      2,563,666,664      ref-cycles                                                  
 2.000267991      2,577,462,550      ref-cycles                                                  
 3.000415395      2,577,211,936      ref-cycles                                                  
 4.000543311      2,577,240,458      ref-cycles                                                  
 5.000702131      2,577,525,002      ref-cycles                                                  
 6.000857663      2,577,156,088      ref-cycles                                                  

[ ... snip ... ]
[ Note that it may not be as nicely consistent on all systems due dynamic frequency scaling ]

$ perf stat -e ref-cycles -I 3000 timeout 10s awk 'BEGIN { while(1){} }' 
#           time             counts unit events
 3.000107921      7,736,108,718      ref-cycles                                                  
 6.000265186      7,732,065,900      ref-cycles                                                  
 9.000372029      7,728,302,192      ref-cycles     

Question 2: Why doesn't perf stat -e <event1> -I 1000 sleep 5 give about the same counts as if I summed up the counts over each second for the following command perf record -e <event1> -F 1000 sleep 5?

perf stat -I is in milliseconds, whereas perf record -F is in HZ (1/s), so the corresponding command to perf stat -I 1000 is perf record -F 1. In fact with our more stable event/workload, this looks better:

$ perf stat -e ref-cycles -I 1000 timeout 10s awk 'BEGIN { while(1){} }'
#           time             counts unit events
 1.000089518      2,578,694,534      ref-cycles                                                  
 2.000203872      2,579,866,250      ref-cycles                                                  
 3.000294300      2,579,857,852      ref-cycles                                                  
 4.000390273      2,579,964,842      ref-cycles                                                  
 5.000488375      2,577,955,536      ref-cycles                                                  
 6.000587028      2,577,176,316      ref-cycles                                                  
 7.000688250      2,577,334,786      ref-cycles                                                  
 8.000785388      2,577,581,500      ref-cycles                                                  
 9.000876466      2,577,511,326      ref-cycles                                                  
10.000977965      2,577,344,692      ref-cycles                                                  
10.001195845            466,674      ref-cycles    

$ perf record -e ref-cycles -F 1 timeout 10s awk 'BEGIN { while(1){} }'
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.008 MB perf.data (17 samples) ]

$ perf script -F time,period        
3369070.273722:          1 
3369070.273755:          1 
3369070.273911:       3757 
3369070.273916:    3015133 
3369070.274486:          1 
3369070.274556:          1 
3369070.274657:       1778 
3369070.274662:    2196921 
3369070.275523: 47192985748 
3369072.663696: 2578692405 
3369073.663547: 2579122382 
3369074.663609: 2580015300 
3369075.664085: 2579873741 
3369076.664433: 2578638211 
3369077.664379: 2578378119 
3369078.664175: 2578166440 
3369079.663896: 2579238122 

So you see, eventually the results are stable also for perf record -F. Unfortunately the documentation of perf record is very poor. You can learn what the settings -c and -F mean by looking at the documentation of the underlying system call man perf_event_open:

sample_period, sample_freq A "sampling" event is one that generates an overflow notification every N events, where N is given by sample_period. A sampling event has sample_period > 0. When an overflow occurs, requested data is recorded in the mmap buffer. The sample_type field controls what data is recorded on each overflow.

sample_freq can be used if you wish to use frequency rather than period. In this case, you set the freq flag. The kernel will adjust the sampling period to try and achieve the desired rate. The rate of adjustment is a timer tick.

So while perf stat uses an internal timer to read the value of the counter every -i milliseconds, perf record sets an event overflow counter to take a sample every -c events. That means it takes a sample every N events (e.g. every N page-fault or cycles). With -F, it it tries to regulate this overflow value to achieve the desired frequency. It tries different values and tunes it up/down accordingly. This eventually works for counters with a stable rate, but will get erratic results for dynamic events.

🌐
Brendan Gregg
brendangregg.com › perf.html
Linux perf Examples
Try starting by counting events using the perf stat command, to see if this is sufficient. This subcommand costs the least overhead. When using the sampling mode with perf record, you'll need to be a little careful about the overheads, as the capture files can quickly become hundreds of Mbytes.
🌐
Linux Man Pages
man7.org › linux › man-pages › man1 › perf-stat.1.html
perf-stat(1) - Linux manual page
.ft C perf_event_attr: size 120 ... 604,097,080 cpu_atom/cycles/ (99.57%) perf-record: If there is no -e specified in perf record, on hybrid platform, it creates two default cycles and adds them to event list....
🌐
OneUptime
oneuptime.com › home › blog › how to analyze system performance with perf on ubuntu
How to Analyze System Performance with perf on Ubuntu
January 15, 2026 - While perf stat provides summary statistics, perf record captures detailed profiling data that can be analyzed with perf report.
🌐
Linux Man Pages
man7.org › linux › man-pages › man1 › perf-record.1.html
perf-record(1) - Linux manual page
One is for core, the other is for atom. perf-stat: If there is no -e specified in perf stat, on hybrid platform, besides of software events, following events are created and added to event list in order. cpu_core/cycles/, cpu_atom/cycles/, cpu_core/instructions/, cpu_atom/instructions/, ...
🌐
Easyperf
easyperf.net › blog › 2018 › 08 › 26 › Basics-of-profiling-with-perf
Basics of profiling with perf. | Easyperf
Now, remember that by default we sample on cycles (equivalent to perf record -e cycles). With latest run we collected 247 samples. For simplicity let’s assume average period for all samples is 32300000 events. Based on that, the number of cycles it took to execute this workload is: 247 * 32300000 = 7978100000 cycles. If we compare this number with the number of counted cycles: $ perf stat -e cycles ./a_out Performance counter stats for './a_out': 7805574851 cycles 2,398101184 seconds time elapsed
🌐
Arch Linux Man Pages
man.archlinux.org › man › perf-record.1.en
perf-record(1) — Arch manual pages
Performance counter stats for 'taskset -c 16 ./triad_loop': 233,066,666 cpu_core/cycles/ (0.43%) 604,097,080 cpu_atom/cycles/ (99.57%) ... If there is no -e specified in perf record, on hybrid platform, it creates two default cycles and adds them to event list.
Find elsewhere
🌐
Ubuntu
manpages.ubuntu.com › jammy › man(1)
Ubuntu Manpage: perf-stat - Run a command and gather performance counter statistics
Performance counter stats for 'taskset -c 16 ./triad_loop': 233,066,666 cpu_core/cycles/ (0.43%) 604,097,080 cpu_atom/cycles/ (99.57%) If there is no -e specified in perf record, on hybrid platform, it creates two default cycles and adds them to event list.
🌐
Perfwiki
perfwiki.github.io › main › tutorial
Introduction - perf: Linux profiling with performance counters
perf stat -B dd if=/dev/zero of=/dev/null count=1000000 1000000+0 records in 1000000+0 records out 512000000 bytes (512 MB, 488 MiB) copied, 2.14421 s, 239 MB/s Performance counter stats for 'dd if=/dev/zero of=/dev/null count=1000000': 621 context-switches # 304.3 cs/sec 7 cpu-migrations # 3.4 migrations/sec 72 page-faults # 35.3 faults/sec 2,040.80 msec task-clock # 0.9 CPUs utilized 6,169,665 cpu_core/branch-misses/ # 0.3 % branch_miss_rate (86.46%) 2,045,176,946 cpu_core/branches/ # 1002.1 M/sec (86.46%) 8,057,111,968 cpu_core/cpu-cycles/ # 3.9 GHz (86.46%) 9,568,892,085 cpu_core/instructi
Top answer
1 of 3
3

@Alina,

If you read the man page for perf record, you can see that perf record -P will be used to record the sample period, and not specify it.

If you want to record more/less samples and modify the period, you have to specify the command like perf record -c 2 (--count=) where 2 is the sampling period. This will mean that for every 2 occurrences of the event that you are measuring, you will have a sample for that. You can then modify the sampling period and test various values.

The other way around to express the sampling period, is to specify the average rate of samples per second (frequency) - which you can do using perf record -F. So perf record -F 1000 will record around 1000 samples per second and these samples will be generated when the hardware/PMU counter corresponding to the event overflows. This means that the kernel will dynamically adjust the sampling period.

2 of 3
1

The sampling period can be specified with the -c option, though there is also a -F option to specify the sampling frequency. The defaults are 1000 samples/sec or 1000Hz according to the perf wiki:

Period and rate

The perf_events interface allows two modes to express the sampling period:

  • the number of occurrences of the event (period)
  • the average rate of samples/sec (frequency)

The perf tool defaults to the average rate. It is set to 1000Hz, or 1000 samples/sec. That means that the kernel is dynamically adjusting the sampling period to achieve the target average rate. The adjustment in period is reported in the raw profile data. In contrast, with the other mode, the sampling period is set by the user and does not vary between samples. There is currently no support for sampling period randomization.

As for what the -P option is doing, the commit message for perf (and the related kernel patch) contains some background. If I interpret it correctly, the option means that for efficiency reasons many equal samples can be merged into a single event that also contains the sample period. The original intent is to reduce the number of generated samples to avoid hitting a "rate limit" that would result in lost samples.

🌐
Debian Manpages
manpages.debian.org › testing › linux-perf › perf-record.1.en.html
perf-record(1) — linux-perf — Debian testing — Debian Manpages
Performance counter stats for 'taskset -c 16 ./triad_loop': 233,066,666 cpu_core/cycles/ (0.43%) 604,097,080 cpu_atom/cycles/ (99.57%) ... If there is no -e specified in perf record, on hybrid platform, it creates two default cycles and adds them to event list.
🌐
Tu-dresden
doc.zih.tu-dresden.de › software › perf_tools
Produce Performance Overview with Perf - ZIH HPC Compendium
Administrators can run a system wide performance statistic, e.g., with perf stat -a sleep 1 which measures the performance counters for the whole computing node over one second. perf record provides the possibility to sample an application or a system. You can find performance issues and hot ...
🌐
Red Hat
docs.redhat.com › en › documentation › red_hat_enterprise_linux › 8 › html › monitoring_and_managing_system_status_and_performance › recording-and-analyzing-performance-profiles-with-perf_monitoring-and-managing-system-status-and-performance
Chapter 21. Recording and analyzing performance profiles with perf | Monitoring and managing system status and performance | Red Hat Enterprise Linux | 8 | Red Hat Documentation
Monitoring and managing system status and performance · Chapter 21. Recording and analyzing performance profiles with perf · The perf tool allows you to record performance data and analyze it at a later time. Prerequisites · You have the perf user space tool installed as described in Installing perf.
🌐
Softpanorama
softpanorama.org › HPC › Performance_issues › perf_stat.shtml
Perf stat
October 17, 2017 - It runs similarly to perf stat ... where subcommand is either list , stat top record , or report .
🌐
Stack Overflow
stackoverflow.com › questions › 79092292 › the-discrepancy-between-the-sample-count-in-perf-record-and-perf-stat
linux - The discrepancy between the sample count in perf record and perf stat? - Stack Overflow
October 16, 2024 - According to my understanding, perf stat reflects the true values of PMU events during the process's execution and can be considered as the ground truth. In contrast, perf record samples based on a specified sample_period, taking a sample when ...
🌐
Ubuntu
manpages.ubuntu.com › manpages › jammy › man1 › perf-record.1.html
Ubuntu Manpage: perf-record - Run a command and record its profile into perf.data
When "dwarf" recording is used, perf also records (user) stack dump when sampled. Default size of the stack dump is 8192 (bytes). User can change the size by passing the size after comma like "--call-graph dwarf,4096". -q, --quiet Don’t print any message, useful for scripting. -v, --verbose Be more verbose (show counter open errors, etc). -s, --stat Record per-thread event counts.
🌐
SUSE
documentation.suse.com › sles › 12-SP5 › html › SLES-all › cha-perf.html
Hardware-Based Performance Monitoring with Perf | System Analysis and Tuning Guide | SLES 12 SP5
April 8, 2026 - perf stat is used to count events. ... Start a program and create a report with performance counter information. The report is stored as perf.data in the current directory. perf record is used to sample events.
🌐
LWN.net
lwn.net › Articles › 668384
perf/core new feature: 'perf stat record/report' [LWN.net]
December 17, 2015 - Simple example: $ perf stat record -e cycles usleep 1 Performance counter stats for 'usleep 1': 1,134,996 cycles 0.000670644 seconds time elapsed $ perf stat report Performance counter stats for '/home/acme/bin/perf stat record -e cycles usleep 1': 1,134,996 cycles 0.000670644 seconds time ...