Manage TuneD Performance Profiles in Linux

Tested on RHEL 10.2 (Coughlan)
Package tuned 2.27.0-2.el10_2
tuned-ppd 2.27.0-1.el10
virt-what 1.27-3.el10
Applies to RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora
Privilege sudo or root to change profiles; listing and verifying work as a normal user
Scope What TuneD changes on a host, listing and reading profiles, applying and reverting them, verifying applied settings, profile inheritance in tuned.conf, and a small custom profile. Does not cover benchmarking or hand tuning individual kernel subsystems.
Related guides Create a custom TuneD profile
nice and renice commands
Set vm.swappiness
Reload sysctl without reboot
Analyze performance with perf
IMPORTANT
TuneD applies a named set of system settings and can roll them back. It does not measure your application, and no profile is faster than another in the abstract. Treat a profile as a documented starting point that you then confirm with your own monitoring.

Most performance advice tells you to change one kernel parameter at a time and hope you remember the original value. TuneD inverts that: you pick a profile that describes the shape of your workload, the daemon applies the whole group of settings, and tuned-adm can tell you what is active and put it back. This guide walks through that cycle on a live host, including a verification failure that turned out to be the virtual hardware rather than a mistake.


What Is TuneD?

TuneD is a system tuning daemon. It reads a profile, which is a plain text description of settings, and pushes those settings into the running kernel and into sysfs. When you select a different profile, it works out which values to change and rolls back the ones the old profile owned.

A profile does not contain raw commands. It contains sections addressed to plug-ins, and each plug-in knows how to apply one class of setting:

  • [sysctl] writes kernel parameters, the same values you would set in /etc/sysctl.d
  • [cpu] handles the CPU frequency governor, energy performance bias, and boost
  • [disk] sets per-device values such as readahead and elevator
  • [vm] controls transparent huge pages and dirty page thresholds
  • [script] runs a helper script when the profile is applied or removed

Two properties make this worth using instead of a pile of hand-written config snippets. Profiles are named and discoverable, so tuned-adm active answers "what is this host tuned for" in one line. Profiles are also reversible, because TuneD tracks what it changed and restores the previous value when you switch away.

Two things TuneD is not. It is not a benchmark, so it will not tell you whether the change helped. It is also not a per-process tool, so if one application needs to yield CPU to another, that is a job for nice and renice and not for a profile that applies to the entire host.


TuneD Quick Reference

These are the commands used throughout this guide. Only the ones that change state need root.

Task Command Needs root
Check the service systemctl status tuned No
List profiles tuned-adm list No
Show active profile tuned-adm active No
Describe a profile tuned-adm profile_info NAME No
Show recommendation tuned-adm recommend No
Show selection mode tuned-adm profile_mode No
Verify applied settings tuned-adm verify No
Select a profile tuned-adm profile NAME Yes
Follow the recommendation tuned-adm auto_profile Yes
Turn tuning off tuned-adm off Yes

The read-only commands talk to the daemon over D-Bus, which is why an ordinary user can ask what is active without any elevation.


Install and Enable TuneD

On RHEL and its rebuilds the package is usually installed already, so check before you install anything.

bash
rpm -q tuned

Sample output:

output
tuned-2.27.0-2.el10_2.noarch

A NEVRA instead of a "not installed" line means the package is present and you can skip straight to the service check.

If the query reports that the package is missing, install it from the base repository.

bash
sudo dnf install tuned

On my host the package was already there, so dnf upgraded it to a newer build rather than installing it. The tail of that run looked like this:

output
Upgraded:
  tuned-2.27.0-2.el10_2.noarch

Complete!

Either way you end with the tuned package on disk, and the profile you had selected before the transaction stays selected afterwards.

Installing the package does not guarantee the daemon is running, so enable it for future boots and start it now in one command.

bash
sudo systemctl enable --now tuned

This prints nothing when the service is already enabled and running, which is the normal case on a stock RHEL install.

Now confirm the daemon is actually alive rather than trusting the exit code.

bash
systemctl status tuned

Trimmed to the parts that matter:

output
● tuned.service - Dynamic System Tuning Daemon
     Loaded: loaded (/usr/lib/systemd/system/tuned.service; enabled; preset: enabled)
     Active: active (running) since Sat 2026-08-08 15:00:39 IST; 26s ago
       Docs: man:tuned(8)
             man:tuned.conf(5)
             man:tuned-adm(8)
   Main PID: 81988 (tuned)
      Tasks: 4 (limit: 38445)
     Memory: 15.4M (peak: 16.1M)
     CGroup: /system.slice/tuned.service
             └─81988 /usr/bin/python3 -Es /usr/sbin/tuned -l -P

enabled on the Loaded line means the service starts at boot, and active (running) on the Active line means the daemon is running now. Neither of them tells you a profile is applied. Check tuned-adm active separately to see which profile is selected, and use tuned-adm verify when you need to confirm its settings match the running system. For more on reading that output, see the systemctl command guide.


List Available TuneD Profiles

tuned-adm list prints every profile the daemon can find, with a one-line summary from each profile's config file.

bash
tuned-adm list

Sample output:

output
Available profiles:
- accelerator-performance     - Throughput performance based tuning with disabled higher latency STOP states
- aws                         - Optimize for aws ec2 instances
- balanced                    - General non-specialized tuned profile
- balanced-battery            - Balanced profile biased towards power savings changes for battery
- desktop                     - Optimize for the desktop use-case
- hpc-compute                 - Optimize for HPC compute workloads
- intel-sst                   - Configure for Intel Speed Select Base Frequency
- latency-performance         - Optimize for deterministic performance at the cost of increased power consumption
- network-latency             - Optimize for deterministic performance at the cost of increased power consumption, focused on low latency network performance
- network-throughput          - Optimize for streaming network throughput, generally only necessary on older CPUs or 40G+ networks
- optimize-serial-console     - Optimize for serial console use.
- powersave                   - Optimize for low power consumption
- throughput-performance      - Broadly applicable tuning that provides excellent performance across a variety of common server workloads
- virtual-guest               - Optimize for running inside a virtual guest
- virtual-host                - Optimize for running KVM guests
Current active profile: balanced

The last line is a convenience: list also tells you which profile is active, so you rarely need a second command to orient yourself.

This list is not fixed. What you see depends on which packages are installed, so do not copy a profile name out of an article and assume it exists on your host. The real-time and CPU partitioning profiles, for example, arrive with separate packages and are absent from the fifteen profiles above.

When a summary line is too terse to decide on, ask for the full description of one profile.

bash
tuned-adm profile_info throughput-performance

The reply has three fields, and one of them is telling:

output
Profile name:
throughput-performance

Profile summary:
Broadly applicable tuning that provides excellent performance across a variety of common server workloads

Profile description:

The description field is empty for most shipped profiles, which is a fair warning that the summaries are the extent of the built-in documentation. When you need to know exactly what a profile does, read its config file, which is covered later in this guide.


Check the Active TuneD Profile

The shortest question TuneD answers is which profile is in force right now.

bash
tuned-adm active

The daemon answers with a single line:

output
Current active profile: balanced

tuned-adm active reports which profile TuneD currently considers active. It does not prove that every requested setting still matches, and tuned-adm verify is what performs that check later in this guide.

There is a second, quieter piece of state worth knowing: whether a human chose this profile or TuneD chose it automatically.

bash
tuned-adm profile_mode

Sample output:

output
Profile selection mode: manual

manual means someone selected balanced explicitly and TuneD will keep honouring that choice. In auto mode the daemon follows its own recommendation instead, which matters when hardware changes underneath a machine.

Both answers are also stored on disk, which is what makes the selection survive a reboot.

bash
cat /etc/tuned/active_profile

The file holds nothing but a profile name:

output
balanced

TuneD reads this file at startup and applies the named profile, so a profile change is persistent without any extra step from you.


TuneD can suggest a profile based on what kind of machine it thinks it is running on.

bash
tuned-adm recommend

The answer is a bare profile name, ready to paste into another command:

output
virtual-guest

Note the mismatch on this host: the recommendation is virtual-guest while the active profile is balanced. The recommendation is advice, and nothing applies it for you.

The suggestion comes from rule files rather than from any measurement. The shipped rules live in /usr/lib/tuned/recommend.d, and you can add your own under /etc/tuned/recommend.d to take precedence.

bash
grep -v '^#' /usr/lib/tuned/recommend.d/50-tuned.conf | grep -v '^$'

Sample output:

output
[atomic-host]
virt=
syspurpose_role=.*atomic.*
[atomic-guest]
virt=.+
syspurpose_role=.*atomic.*
[virtual-guest]
virt=.+
[balanced]
syspurpose_role=(.*(desktop|workstation).*)|^$
chassis_type=.*(Notebook|Laptop|Portable).*
[throughput-performance]

Read that as a first-match-wins list. Each stanza names a profile and the conditions that select it, tested against the virtualization type, the content of /etc/system-release-cpe, running processes, the chassis type from dmidecode, and the system purpose role.

The [virtual-guest] stanza matched on this host because its only condition is that some virtualization is detected.

bash
virt-what

On this VirtualBox guest it prints two lines:

output
virtualbox
kvm

Any non-empty answer here satisfies virt=.+, so a virtual machine gets virtual-guest before the rules ever reach the laptop check or the [throughput-performance] fallback at the end.

This is the honest limit of recommend: it classifies the hardware, not the workload. A virtual machine running a latency-sensitive service still gets virtual-guest, because no rule has any idea what you installed on it.

When you do want to follow the suggestion, auto_profile applies it and switches the selection mode at the same time.

bash
sudo tuned-adm auto_profile

It prints nothing on success, so ask which profile ended up active.

bash
tuned-adm active

The answer changed:

output
Current active profile: virtual-guest

The recommendation has been applied. Checking the mode shows the other half of what changed.

bash
tuned-adm profile_mode

The mode changed as well:

output
Profile selection mode: auto

In auto mode the daemon re-evaluates the recommendation at startup, so a machine that is later cloned onto different hardware follows the new rules instead of an old hard-coded name.


Apply a TuneD Profile

Before changing anything, record the active profile so your rollback target is explicit. TuneD also persists the selected profile in /etc/tuned/active_profile, but keeping your own before-change record avoids ambiguity while troubleshooting.

Selecting a profile is a single command, and throughput-performance is the usual choice for a general purpose server.

bash
sudo tuned-adm profile throughput-performance

Like most tuned-adm write operations it succeeds silently, and the switch took about a second and a half on my host. Confirm it landed rather than assuming.

bash
tuned-adm active

Sample output:

output
Current active profile: throughput-performance

The daemon now reports throughput-performance as the active profile. This confirms the profile selection changed; the next section uses tuned-adm verify to check whether its requested settings match the running system.

You can pass more than one profile name, and later names win on any setting the profiles share. That is how the overlay profiles are meant to be used, for example tuned-adm profile throughput-performance optimize-serial-console to keep the server tuning and calm a noisy serial console. For anything you intend to keep long term, a small custom profile is easier to audit than a two-name command in someone's shell history.


Verify TuneD Settings with tuned-adm verify

Verification re-reads every value the active profile asked for and compares it against what the system reports now. It answers "is the profile still in effect", which is a different question from "is the profile selected".

bash
tuned-adm verify

Instead of the success message the documentation shows, this host reported a failure:

output
Verification failed, current system settings differ from the preset profile.
You can mostly fix this by restarting the TuneD daemon, e.g.:
  systemctl restart tuned
or
  service tuned restart
Sometimes (if some plugins like bootloader are used) a reboot may be required.
See TuneD log file ('/var/log/tuned/tuned.log') for details.

That is a failure on a host where the profile was applied seconds earlier, and the suggested restart does not help. The message is deliberately vague because the detail lives in the log.

The log records one line per checked setting, so filter it down to the pass and fail verdicts.

bash
grep -E "verify: (passed|failed)" /var/log/tuned/tuned.log | tail -5

Sample output:

output
2026-08-08 15:01:10,148 ERROR    tuned.plugins.base: verify: failed: device cpu0: 'boost' = 'None', expected '1'
2026-08-08 15:01:10,149 ERROR    tuned.plugins.base: verify: failed: device cpu2: 'boost' = 'None', expected '1'
2026-08-08 15:01:10,149 ERROR    tuned.plugins.base: verify: failed: device cpu1: 'boost' = 'None', expected '1'
2026-08-08 15:01:10,150 INFO     tuned.plugins.base: verify: passed: 'vm.swappiness' = '10'

Now the failure is readable. The profile asked for CPU frequency boost on three CPUs, the value came back as None, and vm.swappiness passed.

That split is worth chasing down rather than accepting, and the CPU side takes one command. On a host with frequency scaling, each CPU has a cpufreq directory holding the governor and boost files.

bash
ls /sys/devices/system/cpu/cpu0/cpufreq

Sample output:

output
ls: cannot access '/sys/devices/system/cpu/cpu0/cpufreq': No such file or directory

The directory does not exist on this guest, because the hypervisor does not expose frequency control to the VM. The [cpu] plug-in therefore has nothing to write to, the boost check can never pass, and restarting the service will not create the file.

Once you know the failures are unsupported settings rather than drift, tuned-adm verify can be told to stop counting them as errors. The --ignore-missing option, also spelled -i, skips tuning the platform cannot expose while still checking everything it can.

bash
tuned-adm verify --ignore-missing

The same host that failed a moment ago now reports success:

output
Verification succeeded, current system settings match the preset profile.
See TuneD log file ('/var/log/tuned/tuned.log') for details.

The command also exits zero, which matters if you call it from a monitoring check or a configuration management run on virtual machines.

Nothing was quietly waved through, and the log proves it. The boost entries changed verdict while the sysctl was still compared.

bash
grep -E "verify: (passed|failed|skipped)" /var/log/tuned/tuned.log | tail -4

Sample output:

output
2026-08-08 15:47:53,630 INFO     tuned.plugins.base: verify: skipped, missing: device cpu0: 'boost'
2026-08-08 15:47:53,630 INFO     tuned.plugins.base: verify: skipped, missing: device cpu1: 'boost'
2026-08-08 15:47:53,630 INFO     tuned.plugins.base: verify: skipped, missing: device cpu2: 'boost'
2026-08-08 15:47:53,630 INFO     tuned.plugins.base: verify: passed: 'vm.swappiness' = '10'

The three CPU entries are now skipped, missing instead of failed, and vm.swappiness still shows passed. That is the distinction the option draws: absent knobs are ignored, present ones are still compared, so a drifted sysctl would fail this run exactly as before.

NOTE
A tuned-adm verify failure on a virtual machine can come from tuning controls the hypervisor does not expose, but it can also indicate real drift. Inspect /var/log/tuned/tuned.log first. If the only failures are settings unsupported by the platform, rerun with tuned-adm verify --ignore-missing.

Verification is still worth running, because it catches the case that actually bites in production: something else on the host overwrote a value TuneD owns. A sysctl.d file, a container runtime, or a configuration management run can all move vm.swappiness after TuneD set it, and verify is what turns that silent drift into a message. If you keep your own kernel parameters in /etc/sysctl.d, read how those two layers interact in the guide on reloading sysctl without a reboot.


Understand Common TuneD Profiles

The shipped profiles fall into a few families. The table below describes what each family optimizes for, not which one is fastest, because that depends entirely on the work your host is doing.

Profile Optimizes for Typical use
balanced Compromise between performance and power Desktops, laptops, general purpose hosts
powersave Lowest power consumption Battery-powered and thermally limited machines
throughput-performance Bulk throughput on disk and network Application, database, and file servers
latency-performance Predictable low latency, power saving disabled Trading, telemetry, and real-time adjacent workloads
network-latency Low network latency, based on latency-performance Latency-sensitive network services
network-throughput Large network transfers, based on throughput-performance Bulk transfer nodes and 40G or faster links
virtual-guest Running inside a virtual machine Guests on any hypervisor
virtual-host Hosting virtual machines Hypervisors running KVM guests
desktop Interactive responsiveness Workstations with a graphical session

Availability varies by installed package and platform, so treat the table as a map of the families rather than a list you can rely on being present. Always confirm with tuned-adm list on the host in front of you.

Note how the descriptions overlap. network-latency is built on latency-performance, and network-throughput and virtual-guest are both built on throughput-performance. That layering is real inheritance in the config files, and it is the fastest way to understand what a profile actually does.

On RHEL 10 there is one more moving part. The tuned-ppd package makes TuneD answer the power-profiles-daemon API that desktop environments use, and it maps the three desktop power settings onto TuneD profiles.

bash
cat /etc/tuned/ppd.conf

The interesting part is the [profiles] section:

output
[main]
# The default PPD profile
default=balanced
battery_detection=true
sysfs_acpi_monitor=true

[profiles]
# PPD = TuneD
power-saver=powersave
balanced=balanced
performance=throughput-performance

[battery]
# PPD = TuneD
balanced=balanced-battery

On a machine with a desktop session, choosing Performance in the power menu selects throughput-performance through this mapping. If a profile changes without anyone running tuned-adm, that menu is the first place to look.


Compare Two TuneD Profiles

The useful way to compare profiles is to read a specific setting before and after the switch. Two values are easy to observe on almost any host: the swap tendency and the per-device readahead.

Start from a known profile so the comparison means something.

bash
sudo tuned-adm profile balanced

With balanced applied, read the swap tendency the kernel is using.

bash
sysctl vm.swappiness

Sample output:

output
vm.swappiness = 60

That is the stock kernel default, which tells you balanced does not touch this parameter at all.

Readahead is the second value, and it is per block device rather than a global sysctl.

bash
cat /sys/block/sda/queue/read_ahead_kb

The number is in KiB:

output
128

128 was the pre-profile value on this VM's sda. Now switch to the server profile and read the same two values again.

bash
sudo tuned-adm profile throughput-performance

The command is silent, so go back to the swap tendency to see what the profile did.

bash
sysctl vm.swappiness

The swap tendency moved:

output
vm.swappiness = 10

The value dropped from 60 to 10, which biases the kernel toward reclaiming page cache instead of swapping anonymous memory. If you want the background on that number and when to change it yourself, see the guide on swap and vm.swappiness.

Readahead is the other half of the change, and it moved much further.

bash
cat /sys/block/sda/queue/read_ahead_kb

Sample output:

output
4096

From 128 KiB to 4096 KiB. Larger readahead helps sequential reads and wastes I/O on random access, which is exactly the tradeoff a throughput profile is supposed to make. There is more on that class of setting in the notes on disk I/O performance.

Setting balanced throughput-performance
vm.swappiness 60 (kernel default) 10
read_ahead_kb on sda 128 4096

Two observed values are not a benchmark, and nothing here proves the host is faster. What the comparison does prove is that the profile is a real, inspectable change you can point at during a review, rather than a vague promise of performance.


Inspect TuneD Profile Configuration

Every profile is a directory holding a tuned.conf file. There are two locations, and knowing which is which saves a lot of confusion later.

Directory Holds Precedence
/usr/lib/tuned/profiles/ Profiles shipped by packages Lower
/etc/tuned/profiles/ Profiles you create Higher

A profile you create in /etc/tuned/profiles with the same name as a shipped one wins, which is how you override distribution defaults without editing package-owned files.

Start by listing the shipped profile directories, which mirror the names from tuned-adm list.

bash
ls /usr/lib/tuned/profiles/

Sample output:

output
accelerator-performance  hpc-compute	      optimize-serial-console
aws			 intel-sst	      powersave
balanced		 latency-performance  throughput-performance
balanced-battery	 network-latency      virtual-guest
desktop			 network-throughput   virtual-host

One directory per profile. Reading the config inside is the only reliable way to know what a profile changes on your kernel version.

virtual-guest is a good one to read first because it is short and shows inheritance clearly.

bash
cat /usr/lib/tuned/profiles/virtual-guest/tuned.conf

Trimmed to the lines that actually set something:

output
[main]
summary=Optimize for running inside a virtual guest
include=throughput-performance

[vm]
# The generator of dirty data starts writeback at this percentage (system default
# is 20%)
dirty_bytes = 30%

[sysctl]
# Filesystem I/O is usually much more efficient than swapping, so try to keep
# swapping low.  It's usually safe to go even lower than this on systems with
# server-grade storage.
vm.swappiness = 30

Three things to take from that file. The include=throughput-performance line in [main] pulls in the whole parent profile. The [sysctl] section then overrides one inherited value, setting vm.swappiness to 30 instead of the parent's 10. Everything the parent set and the child does not mention, such as readahead, is inherited unchanged.

You can watch that inheritance work rather than take it on trust. Switch to virtual-guest and read both values.

bash
sudo tuned-adm profile virtual-guest

The child profile overrides the swap tendency, so check that first.

bash
sysctl vm.swappiness

Sample output:

output
vm.swappiness = 30

That is the child's value, not the parent's 10, which confirms the override applied.

Readahead is the inherited half, and virtual-guest never mentions it.

bash
cat /sys/block/sda/queue/read_ahead_kb

The parent's value should still be in place:

output
4096

Still 4096, inherited straight from throughput-performance. Read the parent whenever a child profile looks too small to explain the behaviour you are seeing, because most of the settings usually live upstairs.


Create a Simple Custom TuneD Profile

Inheritance also makes custom profiles cheap. Instead of copying a whole shipped profile, include it and override only the values you care about. The example below keeps everything virtual-guest does and changes one harmless parameter, so the mechanics stay visible.

Create the directory under the local profiles path, using a name that will not collide with a shipped profile.

bash
sudo mkdir -p /etc/tuned/profiles/lab-web

The directory is empty until you add the config file, so create /etc/tuned/profiles/lab-web/tuned.conf with your editor and put this in it:

text
[main]
summary=Lab web server profile based on virtual-guest
include=virtual-guest

[sysctl]
vm.swappiness=25

The summary line is what tuned-adm list will print, include names the parent, and the single [sysctl] entry is the only thing this profile changes on its own.

TuneD picks up new directories without a service restart, so the profile should already be listed.

bash
tuned-adm list | grep lab-web

Sample output:

output
- lab-web                     - Lab web server profile based on virtual-guest

Your summary line appears next to the profile name, which confirms the file parsed and the daemon found it.

Selecting a custom profile uses exactly the same command as a shipped one.

bash
sudo tuned-adm profile lab-web

It succeeds silently, so read the parameter the profile overrode.

bash
sysctl vm.swappiness

Sample output:

output
vm.swappiness = 25

The custom value applied. Note that this is now two levels of inheritance, lab-web including virtual-guest which includes throughput-performance, and the readahead value from the top of that chain is still in place.

This is the smallest useful custom profile: one include and one override. For plug-in sections beyond [sysctl], helper scripts, variables, and the [bootloader] settings that need a reboot, work through the dedicated walkthrough on creating a custom TuneD profile.


Switch Back or Disable TuneD

There are two ways back, and they are not equivalent. Selecting another profile swaps one set of settings for another. Turning tuning off removes TuneD's settings without putting a different profile in their place.

Start with the off switch, since its behaviour surprises people.

bash
sudo tuned-adm off

It prints nothing, so ask what the daemon considers active now.

bash
tuned-adm active

The reply is unlike every other run in this guide:

output
No current active profile.

No profile is applied. The question that matters next is what happened to the values the old profile had set.

bash
sysctl vm.swappiness

Sample output:

output
vm.swappiness = 60

Back to 60 from the custom profile's 25, so off restores the pre-TuneD value rather than freezing whatever was set last.

The per-device setting rolled back too, which shows the revert is not limited to sysctl.

bash
cat /sys/block/sda/queue/read_ahead_kb

The disk value came back too:

output
128

Readahead returned to 128 KiB. Both values are back where they were before any profile was applied.

Despite the name, off does not stop the service, and that is the part worth remembering.

bash
systemctl is-active tuned

The answer is one word:

output
active

The daemon is still running and still listening, so you can select a profile again immediately. Because the stored profile is reapplied when the service starts, off lasts only until the next service restart or reboot. If you want tuning gone permanently, sudo systemctl disable --now tuned is the command, and then nothing is applied at boot either.

Returning to a named profile is the normal way out, and it is the same command as always.

bash
sudo tuned-adm profile balanced

Selecting a profile also flips the selection mode back to manual, so confirm both facts at once.

bash
tuned-adm active

The reply confirms the rollback:

output
Current active profile: balanced

The host is back on its original profile. A final check on the parameter you were watching closes the loop.

bash
sysctl vm.swappiness

Sample output:

output
vm.swappiness = 60

balanced leaves the kernel default in place, which is exactly the state this host started in.

Remove the practice profile when you are done, because a stale custom profile in /etc/tuned/profiles is easy to forget and will shadow a shipped profile if the names ever collide.

bash
sudo rm -rf /etc/tuned/profiles/lab-web

The removal is silent, and tuned-adm list no longer shows lab-web because the directory it read is gone.


Plan a Profile Change on a Live Host

The commands above are easy. Doing this on a machine other people depend on is mostly about order and evidence, so the change is reversible and someone else can tell what you did.

Record the current profile before anything else. This is the single fact you need to undo the change, and it is trivial to lose.

bash
tuned-adm active | tee ~/tuned-before.txt

It prints the line and writes the same text into the file:

output
Current active profile: balanced

Keeping it in a file means the rollback command is available even after your scroll buffer is gone.

Then work through the change in this order:

  1. Read tuned-adm recommend for context, remembering it classifies the hardware and not the workload
  2. Read the candidate profile's tuned.conf, including the parent it includes, so you know what will change
  3. Capture the specific settings you expect to move, such as vm.swappiness or the elevator on your data disk
  4. Apply with tuned-adm profile NAME and confirm with tuned-adm active
  5. Run tuned-adm verify and read /var/log/tuned/tuned.log for any failure, deciding whether it is a missing knob or real drift
  6. Watch the workload with your normal tools before drawing any conclusion about the effect
  7. Roll back with tuned-adm profile and the name in your notes if the change did not help

Step six is where profiles are most often oversold. TuneD reports what it applied, never what it achieved, so the evidence has to come from elsewhere: CPU utilization during your peak, and perf when you need to see where time is actually going. Any claim that a profile made a host faster should rest on those measurements rather than on the profile's name.


Troubleshoot TuneD

Symptom Likely cause Fix
Unable to switch profile: Requested profile 'x' doesn't exist. Typo, or the profile ships in a package you have not installed Check the name against tuned-adm list; find the owning package with dnf provides '/usr/lib/tuned/profiles/NAME/tuned.conf'
tuned-adm reports it cannot reach the daemon Service stopped or masked systemctl status tuned, then systemctl enable --now tuned
tuned-adm verify fails right after applying a profile Virtual or restricted hardware has no such knob, for example CPU boost or SATA link power Read /var/log/tuned/tuned.log; once the failures are only unsupported settings, rerun with tuned-adm verify --ignore-missing
verify fails on a sysctl the profile owns Another layer wrote the value later, such as a sysctl.d file or a container runtime Find the competing source and remove the duplicate, or move the value into your custom profile
Profile applied, but the setting you expected did not change The setting belongs to a plug-in with no hardware to act on, or the value was already correct Search the log for that plug-in, for example grep plugin_vm /var/log/tuned/tuned.log
Profile changed without anyone running tuned-adm A desktop power menu switched it through tuned-ppd Check the mapping in /etc/tuned/ppd.conf and set the profile explicitly
A bootloader setting in a custom profile has no effect [bootloader] changes the kernel command line and needs a restart Reboot, then confirm with cat /proc/cmdline
Profile reverts after reboot The change was made with tuned-adm off or the service is disabled Select the profile with tuned-adm profile NAME and confirm systemctl is-enabled tuned

The first row is worth practising, because the error message is the same for a typo and for a genuinely missing package.

bash
sudo tuned-adm profile throughput-perfomance

Sample output:

output
Unable to switch profile: Requested profile 'throughput-perfomance' doesn't exist.

That was a misspelling of throughput-performance, and TuneD refused rather than guessing, leaving the previous profile untouched.

The same message appears for a correctly spelled profile that is simply not installed, which is where the package query earns its place.

bash
dnf -q provides '/usr/lib/tuned/profiles/cpu-partitioning/tuned.conf'

Sample output:

output
tuned-profiles-cpu-partitioning-2.25.1-2.el10_0.noarch : Additional tuned profile(s) optimized for CPU partitioning
Repo        : rhel-10-for-x86_64-baseos-rpms
Matched from:
Filename    : /usr/lib/tuned/profiles/cpu-partitioning/tuned.conf

The profile is real, it just lives in tuned-profiles-cpu-partitioning. Install that package and the name appears in tuned-adm list.


References


Summary

TuneD gives you a named, reversible answer to "what is this host tuned for". You checked the service, listed the profiles the host actually has, read what was active and whether a human chose it, applied throughput-performance, and watched vm.swappiness drop from 60 to 10 while readahead on sda climbed from 128 KiB to 4096 KiB. Then you took it all back, first with tuned-adm off and then by selecting balanced again, and both values returned to this host's pre-profile values. That round trip is the whole value of the tool: the change is one command, and so is the rollback.

Two results are worth carrying forward. The recommendation from tuned-adm recommend classifies your hardware through the rules in recommend.d, which is why a virtual machine gets virtual-guest no matter what runs on it, and why it disagreed with the active profile on this host without anything being wrong. The tuned-adm verify failure was the other lesson: the log showed CPU boost coming back as None on all three CPUs, which is virtual hardware without a frequency control rather than a configuration mistake. Read /var/log/tuned/tuned.log before you act on a verify failure, because the same command also catches the case that does matter, where another layer such as a sysctl.d file overwrites a value TuneD owns. Once you have confirmed the failures are only unsupported knobs, tuned-adm verify --ignore-missing gives you a clean exit code without hiding genuine drift.

For your own systems, start by reading the tuned.conf of the profile you are considering along with the parent it includes, since inheritance means most settings live in the parent. When you need a lasting change, a small custom profile in /etc/tuned/profiles that includes a shipped parent and overrides two or three values is far easier to review a year later than an undocumented set of hand-edited files. Keep the original profile name in your notes, and remember that TuneD reports what it applied and never what it achieved, so the question of whether the profile helped still belongs to your monitoring.


Frequently Asked Questions

1. What does tuned-adm recommend actually base its recommendation on?

It matches your system against rule files in /usr/lib/tuned/recommend.d and /etc/tuned/recommend.d. Those rules test virtualization type as reported by virt-what, the content of /etc/system-release-cpe, running processes, chassis type from dmidecode, and the syspurpose role. The first rule that matches wins. It never measures your workload, so it is a sensible starting point rather than a measured answer.

2. Does tuned-adm profile survive a reboot?

Yes. The name you select is written to /etc/tuned/active_profile and TuneD reapplies it when the service starts at boot, so the change is persistent. Only tuned-adm off is temporary: it stops the tuning for the running system but the stored profile is applied again the next time the service starts.

3. Why does tuned-adm verify fail on a virtual machine?

Verify compares every value the profile asked for against what the system currently reports. Virtual hardware often has no knob at all for CPU frequency boost, SATA link power management, or energy performance bias, so those checks cannot pass no matter how many times you restart the service. A failure can also mean real drift, so read /var/log/tuned/tuned.log and look at which device and setting failed first. When the only failures are settings the platform does not expose, rerun with tuned-adm verify --ignore-missing, which skips those and still compares everything the platform does support.

4. Is tuned-adm off the same as stopping the tuned service?

No. tuned-adm off rolls TuneD-managed settings back to their pre-TuneD values but leaves the daemon running and listening, so you can select a profile again immediately. Stopping or disabling the service with systemctl also ends the daemon, which means no profile is applied and nothing is reapplied at the next boot until you enable it again.

5. Can I apply two TuneD profiles at once?

Yes, tuned-adm profile accepts more than one name and merges them in order, with later profiles overriding earlier ones for any setting they both touch. This is how overlay profiles such as optimize-serial-console and intel-sst are designed to be used. For anything you plan to keep, a small custom profile that includes a parent is easier to read and audit than a long command line.

6. Does TuneD change process priority like nice does?

No. TuneD works at the system level on kernel parameters, sysfs values, CPU frequency policy, and disk settings that apply to the whole host. Process priority for one command or one PID is a separate mechanism handled by nice and renice, and mixing the two ideas leads to the wrong tool being blamed when a single application is slow.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)