tuned-adm on a VPS: Matching Kernel Profiles to Web, Database and Latency-Sensitive Workloads

  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • General web VPS: throughput-performance.
  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • General web VPS: throughput-performance.
  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • General web VPS: throughput-performance.
  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • General web VPS: throughput-performance.
  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • General web VPS: throughput-performance.
  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • General web VPS: throughput-performance.
  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • General web VPS: throughput-performance.
  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • General web VPS: throughput-performance.
  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • General web VPS: throughput-performance.
  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

  • General web VPS: throughput-performance.
  • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
  • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
  • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
  • Always run tuned-adm verify after provisioning and after any cloud-init run.
  • Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    tuned is one of the most useful and most misunderstood packages on a Linux VPS. It ships a set of named kernel and device profiles — curated bundles of CPU governor, scheduler, virtual memory, disk queue and power settings — and applies them atomically with tuned-adm profile <name>. The misunderstanding is treating profiles as magic performance buttons. They are not: a profile is a bundle of conservative tunings that must match your workload or it will actively hurt you. A database VPS running a web-optimised profile will have the wrong read-ahead and dirty-ratio settings; a web VPS running a throughput profile may hold dirty pages too long and spike latency on small writes.

    This article covers the profiles that matter on a VPS, what each one actually changes, how to verify it took effect, and how to build a custom profile that layers your own sysctl values on top. If you have not yet worked through generic kernel tuning, start with our guide to VPS kernel parameter and sysctl tuning, since a tuned profile is just a managed overlay on the same parameters.

    What tuned actually does

    Installed via apt install tuned (Debian/Ubuntu) or dnf install tuned (RHEL family), tuned runs as a daemon with a profile selected at /etc/tuned/active_profile. On activation it performs three kinds of changes:

    • sysctl writes — values like vm.swappiness, vm.dirty_ratio, vm.dirty_background_ratio, net.ipv4.tcp_*.
    • Device settings — I/O scheduler on each block device (/sys/block/*/queue/scheduler), read-ahead (read_ahead_kb), and sometimes queue depth.
    • Plugin actions — CPU governor and energy/performance preference via the cpu plugin, disk power management, and in some profiles, transparent hugepage behaviour.

    Profiles live in /usr/lib/tuned/<name>/tuned.conf, with local overrides in /etc/tuned/. That split matters: your custom profile in /etc/tuned/ survives package upgrades, edits to /usr/lib/ do not.

    Profile comparison for VPS workloads

    ProfileIntended workloadKey vm settingsI/O schedulerFit for a VPS
    throughput-performanceGeneric server, maximum I/O and CPUswappiness=10, dirty_ratio=40, dirty_background=10mq-deadline / noneGood default for web or general servers
    latency-performanceLatency-sensitive servicesswappiness=10, dirty_ratio=10, dirty_background=3none / mq-deadlineBest for databases on SSD/NVMe
    network-latencyNetwork-focused, low per-packet latencyswappiness=10, aggressive THP disabledunchangedUseful for proxy/firewall roles
    network-throughputHigh bandwidth bulk transferlarge TCP buffersunchangedNiche; large socket buffers cost RAM
    virtual-guestGeneric VM guestmoderate swappiness=30noneReasonable starting point, not optimal
    balancedDefault desktop/server mixswappiness=60, dirty_ratio=20mq-deadlineToo conservative for a busy VPS
    powersaveMinimise energyswappiness=60+unchangedNever on a server

    Two of those rows carry most of the value. throughput-performance is the right starting point for a general web VPS. latency-performance is the right choice when a database shares the box, because it forces dirty pages to disk far more eagerly (dirty_ratio=10 instead of 40), which keeps write latency predictable at the cost of a little raw throughput. On a small NVMe VPS with a 256 MB buffer pool, that trade is almost always correct.

    Applying and verifying a profile

    tuned-adm profile throughput-performance
    tuned-adm active
    tuned-adm verify

    tuned-adm verify re-reads every setting in the active profile and reports whether the live kernel state matches. If you (or a cloud-init script, or another tuning tool) changed a sysctl after tuned applied, verify will flag the drift. This is the main reason to run tuned rather than a hand-written sysctl file: it detects and can re-assert your configuration.

    To see what a profile will change before you apply it:

    tuned-adm profile_info latency-performance
    tuned-adm recommend

    tuned-adm recommend uses the recommend plugin to inspect the host (virt type, whether it is a guest, disk type) and suggest a profile. On a KVM VPS it usually suggests virtual-guest — a safe, unambitious choice you will generally want to override.

    Building a custom profile that survives upgrades

    The practical pattern is to inherit the closest stock profile and add your own overrides. Create /etc/tuned/vps-db/tuned.conf:

    [main]
    summary=Database-optimised profile for 2–4 GB VPS
    include=latency-performance

    [sysctl]
    vm.dirty_writeback_centisecs=500
    vm.dirty_expire_centisecs=1000
    vm.vfs_cache_pressure=50
    net.core.somaxconn=1024

    [disk]
    read_ahead_kb=1024
    scheduler=none

    Then tuned-adm profile vps-db. The include= line pulls in everything from latency-performance, and your sections override or extend it. Values you do not specify are left as the parent set them.

    Two cautions. First, do not set vm.swappiness=0 on a small VPS: with no swap headroom you convert memory pressure directly into OOM kills instead of slow paging. 10 is the practical floor. Second, scheduler=none (or mq-deadline) is correct for SSDs; on spinning disk you want bfq or mq-deadline with a larger read-ahead. You can confirm the device is SSD with cat /sys/block/vda/queue/rotational — 0 means SSD.

    Measuring whether it helped

    Changing a profile without measuring is guesswork. A minimal before/after check on the database VPS:

    sysbench fileio --file-total-size=2G --file-test-mode=rndrw prepare
    sysbench fileio --file-total-size=2G --file-test-mode=rndrw --time=60 run
    vmstat 1 60 > /tmp/vmstat.after

    Watch si/so (swap in/out) and the bo column in vmstat. A latency profile should reduce bursty bo at the cost of slightly higher steady bo. If si/so are non-zero in either run, your working set does not fit in RAM and no tunable profile will fix that — you need a bigger instance or a smaller buffer pool. Our guide to diagnosing VPS disk I/O latency spikes covers how to tell scheduler-caused latency from genuine device saturation.

    Practical recommendations

    • General web VPS: throughput-performance.
    • VPS running MySQL/MariaDB/PostgreSQL: latency-performance, or a custom profile derived from it.
    • Tiny 512 MB VPS: latency-performance plus vm.swappiness=10 and a small swap file — not zero swap.
    • Never leave the daemon on balanced if you chose tuned for performance; that is the distro default and you gain nothing.
    • Always run tuned-adm verify after provisioning and after any cloud-init run.

    Finally, remember that tuned does not size your applications. It cannot set an InnoDB buffer pool, an OPcache limit, or a PHP-FPM pool ceiling. Those decisions dominate performance on a small VPS long before kernel tunables do. Treat tuned as the last 5% of tuning, applied after the application layer is correctly sized — not as the first thing you reach for. For a full picture of what to size first, see our Nginx and caching tuning walkthrough.

    Leave a Reply