Consistent CPU benchmarks in Linux provide a repeatable way to compare hardware, place virtual machines, and detect performance regressions after kernel, firmware, or configuration changes. Measurements based on real workloads and stable tools reveal whether available compute resources align with tasks such as compilation, database queries, and parallel build pipelines.

On Linux, benchmarking utilities generate controlled CPU load and collect metrics such as execution time, events per second, and latency. Sysbench focuses on synthetic tests, including a cpu mode that performs intensive prime-number calculations, making it straightforward to stress either a single core or all available threads while capturing reproducible results.

CPU benchmarks place sustained load on the processor, increase power draw, and can raise system temperature, especially on laptops or compact servers. Running benchmarks on production hosts can affect other workloads, so scheduling tests during maintenance windows and monitoring thermal sensors and fan behavior reduces risk. Typical Linux distributions provide the required tools via the terminal and expect basic familiarity with `sudo` and package managers.

Steps to benchmark CPU performance in Linux:

  1. Open a terminal on a Linux system with a user account suitable for running benchmarks.
  2. Install the sysbench package from the distribution package manager if it is not already present.
    $ sudo apt update
    Hit:1 http://ports.ubuntu.com/ubuntu-ports noble InRelease
    Hit:2 http://ports.ubuntu.com/ubuntu-ports noble-updates InRelease
    Hit:3 http://ports.ubuntu.com/ubuntu-ports noble-backports InRelease
    Hit:4 http://ports.ubuntu.com/ubuntu-ports noble-security InRelease
    Reading package lists...
    Building dependency tree...
    Reading state information...
    5 packages can be upgraded. Run 'apt list --upgradable' to see them.
    $ sudo apt install --assume-yes sysbench
    Reading package lists...
    Building dependency tree...
    Reading state information...
    The following additional packages will be installed:
      libaio1t64 libldap-common libldap2 libluajit2-5.1-2 libluajit2-5.1-common
      libmysqlclient21 libpq5 libsasl2-2 libsasl2-modules libsasl2-modules-db
      mysql-common
    Suggested packages:
      libsasl2-modules-gssapi-mit | libsasl2-modules-gssapi-heimdal
      libsasl2-modules-ldap libsasl2-modules-otp libsasl2-modules-sql
    The following NEW packages will be installed:
      libaio1t64 libldap-common libldap2 libluajit2-5.1-2 libluajit2-5.1-common
      libmysqlclient21 libpq5 libsasl2-2 libsasl2-modules libsasl2-modules-db
      mysql-common sysbench
    0 upgraded, 12 newly installed, 0 to remove and 5 not upgraded.
    Need to get 2214 kB of archives.
    After this operation, 10.2 MB of additional disk space will be used.
    Get:1 http://ports.ubuntu.com/ubuntu-ports noble-updates/main arm64 libaio1t64 arm64 0.3.113-6build1.1 [7192 B]
    Get:2 http://ports.ubuntu.com/ubuntu-ports noble-updates/main arm64 libldap-common all 2.6.7+dfsg-1~exp1ubuntu8.2 [31.7 kB]
    Get:3 http://ports.ubuntu.com/ubuntu-ports noble-updates/main arm64 libsasl2-modules-db arm64 2.1.28+dfsg1-5ubuntu3.1 [21.6 kB]
    Get:4 http://ports.ubuntu.com/ubuntu-ports noble-updates/main arm64 libsasl2-2 arm64 2.1.28+dfsg1-5ubuntu3.1 [54.7 kB]
    Get:5 http://ports.ubuntu.com/ubuntu-ports noble-updates/main arm64 libldap2 arm64 2.6.7+dfsg-1~exp1ubuntu8.2 [194 kB]
    Get:6 http://ports.ubuntu.com/ubuntu-ports noble/universe arm64 libluajit2-5.1-common all 2.1-20230410-1build1 [48.6 kB]
    Get:7 http://ports.ubuntu.com/ubuntu-ports noble/universe arm64 libluajit2-5.1-2 arm64 2.1-20230410-1build1 [275 kB]
    Get:8 http://ports.ubuntu.com/ubuntu-ports noble/main arm64 mysql-common all 5.8+1.1.0build1 [6746 B]
    Get:9 http://ports.ubuntu.com/ubuntu-ports noble-updates/main arm64 libmysqlclient21 arm64 8.0.44-0ubuntu0.24.04.2 [1245 kB]
    Get:10 http://ports.ubuntu.com/ubuntu-ports noble-updates/main arm64 libpq5 arm64 16.11-0ubuntu0.24.04.1 [143 kB]
    Get:11 http://ports.ubuntu.com/ubuntu-ports noble-updates/main arm64 libsasl2-modules arm64 2.1.28+dfsg1-5ubuntu3.1 [69.6 kB]
    Get:12 http://ports.ubuntu.com/ubuntu-ports noble/universe arm64 sysbench arm64 1.0.20+ds-6build2 [117 kB]
    Fetched 2214 kB in 3s (800 kB/s)
    Selecting previously unselected package libaio1t64:arm64.
    (Reading database ... (Reading database ... 5%(Reading database ... 10%(Reading database ... 15%(Reading database ... 20%(Reading database ... 25%(Reading database ... 30%(Reading database ... 35%(Reading database ... 40%(Reading database ... 45%(Reading database ... 50%(Reading database ... 55%(Reading database ... 60%(Reading database ... 65%(Reading database ... 70%(Reading database ... 75%(Reading database ... 80%(Reading database ... 85%(Reading database ... 90%(Reading database ... 95%(Reading database ... 100%(Reading database ... 17764 files and directories currently installed.)
    Preparing to unpack .../00-libaio1t64_0.3.113-6build1.1_arm64.deb ...
    Unpacking libaio1t64:arm64 (0.3.113-6build1.1) ...
    Selecting previously unselected package libldap-common.
    Preparing to unpack .../01-libldap-common_2.6.7+dfsg-1~exp1ubuntu8.2_all.deb ...
    Unpacking libldap-common (2.6.7+dfsg-1~exp1ubuntu8.2) ...
    Selecting previously unselected package libsasl2-modules-db:arm64.
    Preparing to unpack .../02-libsasl2-modules-db_2.1.28+dfsg1-5ubuntu3.1_arm64.deb ...
    Unpacking libsasl2-modules-db:arm64 (2.1.28+dfsg1-5ubuntu3.1) ...
    Selecting previously unselected package libsasl2-2:arm64.
    Preparing to unpack .../03-libsasl2-2_2.1.28+dfsg1-5ubuntu3.1_arm64.deb ...
    Unpacking libsasl2-2:arm64 (2.1.28+dfsg1-5ubuntu3.1) ...
    Selecting previously unselected package libldap2:arm64.
    Preparing to unpack .../04-libldap2_2.6.7+dfsg-1~exp1ubuntu8.2_arm64.deb ...
    Unpacking libldap2:arm64 (2.6.7+dfsg-1~exp1ubuntu8.2) ...
    Selecting previously unselected package libluajit2-5.1-common.
    Preparing to unpack .../05-libluajit2-5.1-common_2.1-20230410-1build1_all.deb ...
    Unpacking libluajit2-5.1-common (2.1-20230410-1build1) ...
    Selecting previously unselected package libluajit2-5.1-2:arm64.
    Preparing to unpack .../06-libluajit2-5.1-2_2.1-20230410-1build1_arm64.deb ...
    Unpacking libluajit2-5.1-2:arm64 (2.1-20230410-1build1) ...
    Selecting previously unselected package mysql-common.
    Preparing to unpack .../07-mysql-common_5.8+1.1.0build1_all.deb ...
    Unpacking mysql-common (5.8+1.1.0build1) ...
    Selecting previously unselected package libmysqlclient21:arm64.
    Preparing to unpack .../08-libmysqlclient21_8.0.44-0ubuntu0.24.04.2_arm64.deb ...
    Unpacking libmysqlclient21:arm64 (8.0.44-0ubuntu0.24.04.2) ...
    Selecting previously unselected package libpq5:arm64.
    Preparing to unpack .../09-libpq5_16.11-0ubuntu0.24.04.1_arm64.deb ...
    Unpacking libpq5:arm64 (16.11-0ubuntu0.24.04.1) ...
    Selecting previously unselected package libsasl2-modules:arm64.
    Preparing to unpack .../10-libsasl2-modules_2.1.28+dfsg1-5ubuntu3.1_arm64.deb ...
    Unpacking libsasl2-modules:arm64 (2.1.28+dfsg1-5ubuntu3.1) ...
    Selecting previously unselected package sysbench.
    Preparing to unpack .../11-sysbench_1.0.20+ds-6build2_arm64.deb ...
    Unpacking sysbench (1.0.20+ds-6build2) ...
    Setting up mysql-common (5.8+1.1.0build1) ...
    update-alternatives: using /etc/mysql/my.cnf.fallback to provide /etc/mysql/my.cnf (my.cnf) in auto mode
    Setting up libmysqlclient21:arm64 (8.0.44-0ubuntu0.24.04.2) ...
    Setting up libsasl2-modules:arm64 (2.1.28+dfsg1-5ubuntu3.1) ...
    Setting up libluajit2-5.1-common (2.1-20230410-1build1) ...
    Setting up libldap-common (2.6.7+dfsg-1~exp1ubuntu8.2) ...
    Setting up libsasl2-modules-db:arm64 (2.1.28+dfsg1-5ubuntu3.1) ...
    Setting up libsasl2-2:arm64 (2.1.28+dfsg1-5ubuntu3.1) ...
    Setting up libaio1t64:arm64 (0.3.113-6build1.1) ...
    Setting up libluajit2-5.1-2:arm64 (2.1-20230410-1build1) ...
    Setting up libldap2:arm64 (2.6.7+dfsg-1~exp1ubuntu8.2) ...
    Setting up libpq5:arm64 (16.11-0ubuntu0.24.04.1) ...
    Setting up sysbench (1.0.20+ds-6build2) ...
    Processing triggers for libc-bin (2.39-0ubuntu8.6) ...

    On Fedora use sudo dnf install sysbench, and on openSUSE use sudo zypper install --skip-interactive sysbench.

  3. Identify the number of CPU cores and threads in the system using the lscpu command.
    $ lscpu | grep "^CPU.s\|^Thread.s"
    CPU(s):                                  10
    Thread(s) per core:                      1
  4. Run a test to measure the performance of a single CPU core.
    $ sysbench cpu run
    sysbench 1.0.20 (using system LuaJIT 2.1.0-beta3)
    
    Running the test with following options:
    Number of threads: 1
    Initializing random number generator from current time
    
    
    Prime numbers limit: 10000
    
    Initializing worker threads...
    
    Threads started!
    
    CPU speed:
        events per second:  8490.33
    
    General statistics:
        total time:                          10.0001s
        total number of events:              84911
    
    Latency (ms):
             min:                                    0.11
             avg:                                    0.11
             max:                                    1.19
             95th percentile:                        0.12
             sum:                                 9976.45
    
    Threads fairness:
        events (avg/stddev):           84911.0000/0.00
        execution time (avg/stddev):   9.9765/0.00

    The command tests the speed of a single CPU core by calculating prime numbers up to the configured limit.

  5. Run a test to measure the performance of multiple CPU cores using a thread count derived from the lscpu output.
    $ sysbench cpu --threads=10 run
    sysbench 1.0.20 (using system LuaJIT 2.1.0-beta3)
    
    Running the test with following options:
    Number of threads: 10
    Initializing random number generator from current time
    
    
    Prime numbers limit: 10000
    
    Initializing worker threads...
    
    Threads started!
    
    CPU speed:
        events per second: 62113.52
    
    General statistics:
        total time:                          10.0005s
        total number of events:              621208
    
    Latency (ms):
             min:                                    0.11
             avg:                                    0.16
             max:                                   52.56
             95th percentile:                        0.15
             sum:                                99664.31
    
    Threads fairness:
        events (avg/stddev):           62120.8000/1050.63
        execution time (avg/stddev):   9.9664/0.01

    Replace 10 with the desired number of threads based on the available hardware threads reported by lscpu.

  6. Conduct a prolonged benchmark to simulate sustained CPU load over time with multiple threads.
    $ sysbench cpu --threads=10 --time=60 run
    sysbench 1.0.20 (using system LuaJIT 2.1.0-beta3)
    
    Running the test with following options:
    Number of threads: 10
    Initializing random number generator from current time
    
    
    Prime numbers limit: 10000
    
    Initializing worker threads...
    
    Threads started!
    
    CPU speed:
        events per second: 65284.42
    
    General statistics:
        total time:                          60.0003s
        total number of events:              3917120
    
    Latency (ms):
             min:                                    0.11
             avg:                                    0.15
             max:                                   68.15
             95th percentile:                        0.16
             sum:                               598117.93
    
    Threads fairness:
        events (avg/stddev):           391712.0000/2551.52
        execution time (avg/stddev):   59.8118/0.02

    Longer benchmarks can cause the CPU to reach thermal and power limits, which may trigger frequency scaling and throttling.

  7. Adjust sysbench options to refine benchmark tests for different scenarios, such as varying runtime, thread counts, or reporting detail.
    $ sysbench --help
    Usage:
      sysbench [options]... [testname] [command]
    
    Commands implemented by most tests: prepare run cleanup help
    
    General options:
      --threads=N                     number of threads to use [1]
      --events=N                      limit for total number of events [0]
      --time=N                        limit for total execution time in seconds [10]
      --forced-shutdown=STRING        number of seconds to wait after the --time limit before forcing shutdown, or 'off' to disable [off]
      --thread-stack-size=SIZE        size of stack per thread [64K]
      --rate=N                        average transactions rate. 0 for unlimited rate [0]
      --report-interval=N             periodically report intermediate statistics with a specified interval in seconds. 0 disables intermediate reports [0]
      --report-checkpoints=[LIST,...] dump full statistics and reset all counters at specified points in time. The argument is a list of comma-separated values representing the amount of time in seconds elapsed from start of test when report checkpoint(s) must be performed. Report checkpoints are off by default. []
      --debug[=on|off]                print more debugging info [off]
      --validate[=on|off]             perform validation checks where possible [off]
      --help[=on|off]                 print help and exit [off]
      --version[=on|off]              print version and exit [off]
      --config-file=FILENAME          File containing command line options
      --tx-rate=N                     deprecated alias for --rate [0]
      --max-requests=N                deprecated alias for --events [0]
      --max-time=N                    deprecated alias for --time [0]
      --num-threads=N                 deprecated alias for --threads [1]
    
    Pseudo-Random Numbers Generator options:
      --rand-type=STRING random numbers distribution {uniform,gaussian,special,pareto} [special]
      --rand-spec-iter=N number of iterations used for numbers generation [12]
      --rand-spec-pct=N  percentage of values to be treated as 'special' (for special distribution) [1]
      --rand-spec-res=N  percentage of 'special' values to use (for special distribution) [75]
      --rand-seed=N      seed for random number generator. When 0, the current time is used as a RNG seed. [0]
      --rand-pareto-h=N  parameter h for pareto distribution [0.2]
    
    Pseudo-Random Numbers Generator options:
      --rand-type=STRING random numbers distribution {uniform,gaussian,special,pareto} [special]
      --rand-spec-iter=N number of iterations used for numbers generation [12]
      --rand-spec-pct=N  percentage of values to be treated as 'special' (for special distribution) [1]
      --rand-spec-res=N  percentage of 'special' values to use (for special distribution) [75]
    ##### snipped #####
  8. Review the reported events per second, total number of events, and latency statistics from each run to compare CPU performance across different thread counts and durations.