SSD Nodes Learn 8GB de RAM — $66/an
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-08-02

NVMe ou SSD SATA sur un VPS : quelle différence ?

Le NVMe réduit les latences et augmente les IOPS, mais l’hyperviseur et vos voisins limitent souvent le gain. Testez votre VPS avec fio.

Le NVMe est-il important sur un VPS ?

Le NVMe est important sur un VPS lorsque vos logiciels effectuent de nombreuses petites opérations de lecture et d’écriture et attendent la fin de chacune d’elles. Il change très peu les performances d’un site qui sert des pages mises en cache ou d’un programme qui passe son temps à attendre le réseau. Le support de stockage n’est qu’un facteur. L’hyperviseur placé devant le disque et les autres machines invitées qui partagent le même hôte déterminent la limite de performances que vous obtenez réellement.

Ce que NVMe change et ce qu’il ne change pas

NVMe (non-volatile memory express) n’est pas un type de mémoire flash. C’est le protocole et la connexion utilisés pour accéder à la mémoire flash. Un périphérique NVMe utilise des lignes PCIe (peripheral component interconnect express) et communique avec le protocole NVMe. Un SSD SATA (serial ATA) utilise une liaison SATA et communique avec AHCI (advanced host controller interface). Les puces mémoire qui stockent vos octets peuvent être identiques dans les deux cas.

Deux éléments diffèrent. Ils concernent tous les deux le chemin des commandes, et non le stockage lui-même.

Files d’attente. AHCI fournit au noyau une seule file de commandes contenant 32 commandes. NVMe autorise des milliers de files, en pratique une par cœur de CPU, chacune étant bien plus profonde que 32. Un processus qui lit un bloc à la fois ne voit pas cette différence. Une base de données avec 64 lectures en attente, oui : sur SATA, la 33e requête attend une place dans la file avant même que le périphérique ne la voie, tandis que le périphérique NVMe les accepte toutes et les traite simultanément.

Largeur de liaison. Une liaison SATA III fonctionne à 6 Gbit/s, soit environ 550 MB/s de données réelles après la surcharge du protocole. Cette limite est fixe, quelle que soit la mémoire flash située derrière. Quatre lignes PCIe transportent plusieurs gigaoctets par seconde. La liaison ne constitue donc plus la limite.

C’est sur la latence que les attentes sont généralement erronées. À une profondeur de file de 1, c’est-à-dire avec une seule requête en cours, un SSD SATA répond à une lecture de 4k en environ 100 à 150 microsecondes. NVMe répond en environ 80 à 100. Les deux sont rapides, et aucune application que vous exécutez ne remarquera la différence pour une seule requête. L’écart apparaît en cas de concurrence. La profondeur de file, c’est-à-dire le nombre de requêtes en cours simultanément, détermine si les deux supports semblent similaires ou très différents.

Le stockage bloc sur réseau constitue une troisième catégorie, avec une physique différente. Une écriture traverse un réseau jusqu’à un cluster de stockage et n’est acquittée qu’une fois que le cluster la contient. Sa latence se mesure donc en millisecondes plutôt qu’en microsecondes. En contrepartie, vous bénéficiez d’une meilleure durabilité : le volume survit à l’hôte auquel il est attaché, et vous pouvez en créer des snapshots et le redimensionner.

Chiffres typiques publiés : NVMe, SSD SATA et stockage réseau

ChartTypical published figures: 4k random read, queue depth 32
The data behind this chart
[
  {
    "disk": "Local NVMe SSD",
    "iops_4k_read": "184,000",
    "p99_latency_ms": 0.4,
    "seq_read_mbps": "3,400"
  },
  {
    "disk": "Local SATA SSD",
    "iops_4k_read": "90,000",
    "p99_latency_ms": 1.2,
    "seq_read_mbps": "550"
  },
  {
    "disk": "Network block storage",
    "iops_4k_read": "12,500",
    "p99_latency_ms": 6.5,
    "seq_read_mbps": "250"
  }
]

Un périphérique NVMe local est généralement annoncé à 184,000 IOPS de lecture aléatoire 4k (opérations d’entrée-sortie par seconde), avec une profondeur de file d’attente de 32. Le même test sur un SSD SATA est généralement annoncé autour de 90,000. Le résultat est limité par la file AHCI unique et par la liaison à 6 Gbit/s. Le stockage en mode bloc sur le réseau est généralement plafonné par le fournisseur plutôt que par le matériel, et 12,500 constitue une limite documentée courante.

La latence exprime le même écart dans l’unité que vos utilisateurs ressentent. La latence de lecture p99, c’est-à-dire celle des 1 % de requêtes les plus lentes, est d’environ 0.4 ms sur un NVMe local et de 1.2 ms sur SATA. Si le chemin inclut un réseau, elle atteint 6.5 ms, soit plus de dix fois la valeur du NVMe.

Les lectures séquentielles présentent l’écart le plus important, mais c’est aussi le moins utile : 3,400 Mo/s contre 550 Mo/s. Presque aucun processus sur un serveur ne lit un seul gros fichier du début à la fin à pleine vitesse. Les colonnes des accès aléatoires et de la latence décrivent ce que font réellement une base de données, une file d’attente de messagerie ou un gestionnaire de paquets.

Origine de ces chiffres et raisons pour lesquelles les vôtres seront différents

Les 3 lignes correspondent aux chiffres des fiches techniques des fournisseurs pour les périphériques locaux et aux limites documentées par volume pour le stockage réseau, à jour en juillet 2026 et arrondies. Elles supposent une taille de bloc de 4k, des lectures aléatoires, une profondeur de file d’attente de 32 et un seul job, ce qui correspond au type de test publié par un fournisseur. Votre VPS est une machine virtuelle invitée sur un hôte partagé. Le même test sur votre machine renvoie donc généralement une valeur inférieure, qui varie d’une exécution à l’autre. Considérez ces lignes comme une indication de l’écart entre les trois catégories, et non comme une valeur à atteindre.

Quelles charges de travail remarquent le disque

Une seule règle les explique toutes : une charge de travail ne remarque le disque que lorsqu’elle attend le disque. Linux conserve les données des fichiers récemment utilisées dans la RAM, dans le page cache. La deuxième lecture d’un fichier n’atteint donc jamais le stockage. Si le working set, c’est-à-dire les données réellement utilisées, tient dans la RAM, les lectures deviennent des lectures mémoire après le premier passage. Les écritures sont différentes. Toute écriture que l’application valide avec fsync() doit être présente sur un stockage stable avant que l’application puisse continuer.

Travail qui valide des transactions. PostgreSQL, MySQL et SQLite appellent fsync() ou fdatasync() lors de la validation, et chaque validation attend la réponse du périphérique. Le débit de validation d’une connexion dépend donc de la latence d’écriture, et non de la bande passante. Un périphérique qui effectue un flush en 0.2 ms autorise beaucoup plus de validations par seconde qu’un périphérique qui prend 5 ms. Aucun débit supplémentaire ne change cela. MySQL l’indique dans l’error log lorsque le flush ne suit pas le rythme :

[Note] InnoDB: page_cleaner: 1000ms intended loop took 4589ms. The settings might not be optimal.

PostgreSQL le signale dans ses lignes de checkpoint. Une valeur sync= élevée signifie que le flush lui-même était lent :

LOG:  checkpoint complete: wrote 8192 buffers (25.0%); write=27.694 s, sync=11.207 s, total=39.001 s

Travail qui manipule de nombreux petits fichiers. Chaque fichier implique des opérations sur les métadonnées, contrairement à une seule lecture séquentielle volumineuse. npm install, git clone d’un dépôt volumineux, la décompression d’images de conteneurs, un magasin de courriers Maildir et une sauvegarde qui parcourt une arborescence volumineuse passent tous leur temps sur des accès aléatoires de petite taille. Une tâche de sauvegarde restic sur un VPS lit et hache chaque fichier qu’elle n’a pas encore rencontré. La durée réelle d’une sauvegarde portant sur un million de fichiers suit donc étroitement la latence de lecture aléatoire. Il en va de même pour du -sh, qui ne lit que les métadonnées.

Les bases de données qui dépassent la capacité de la RAM appartiennent également à cette catégorie. Lorsque l’index ne tient plus dans le page cache, chaque recherche devient une lecture aléatoire et le disque revient dans le chemin critique.

Quelles charges de travail ne remarquent pas le disque

Un blog ou un petit site d’entreprise. Les pages sont petites. Le cache de pages les conserve toutes après la première requête. La limite vient du CPU pour le rendu ou de la bande passante pour les ressources. Une pile LAMP sur Ubuntu 24.04 qui sert un site à faible trafic génère presque aucune IO disque une fois le cache chaud.

Le streaming multimédia. Un flux 4K à 40 Mbit/s lit 5 MB/s. Dix flux lisent 50 MB/s. Même un stockage bloc sur le réseau fournit ce débit sans difficulté. Un serveur multimédia Jellyfin sur un VPS est limité par votre quota de trafic sortant et par le CPU lors du transcodage, pas par le support de stockage.

L’inférence locale de modèles. Exécuter Ollama sur un VPS pour auto-héberger un LLM lit le fichier du modèle une fois, puis fonctionne en RAM. Le NVMe réduit le temps de chargement d’un modèle de 20 GB, qui passe de quelques minutes à quelques secondes. Il ne modifie pas le nombre de tokens par seconde, qui dépend de la bande passante mémoire et du CPU.

Toute charge qui attend un service externe. Un worker qui consacre 800 ms par tâche à une requête HTTP ne sera pas plus rapide avec un meilleur disque.

Pourquoi l’hyperviseur compte autant que le support

Vous ne communiquez jamais directement avec le périphérique. Vous utilisez un disque virtuel présenté par l’hyperviseur, généralement via virtio. Plusieurs décisions prises à ce niveau ont plus d’importance que le choix entre NVMe et SATA.

Vous ne pouvez pas voir le support depuis le système invité. lsblk -d -o NAME,ROTA,SIZE,MODEL affiche vda avec un modèle vide, car virtio ne transmet pas l’identité du disque. cat /sys/block/vda/queue/rotational indique ce que l’hyperviseur annonce. Une valeur égale à 0 ne prouve donc pas qu’il s’agit de mémoire flash. nvme list, fourni par le paquet nvme-cli, ne liste généralement aucun périphérique sur les VPS, même lorsque l’hôte utilise entièrement des disques NVMe, car votre disque est un périphérique virtio et non un périphérique NVMe. Une offre qui mentionne NVMe décrit généralement le contenu de l’hôte. Votre volume peut malgré tout être raccordé au réseau.

Le mode de cache de l’hôte modifie davantage les résultats que le support. Avec la mise en cache writeback sur l’hôte, une opération fsync() du système invité peut être terminée dès que l’hôte a placé les données dans sa propre RAM. Le résultat du benchmark peut alors dépasser ce qu’aucun périphérique physique ne pourrait fournir. Un crash de l’hôte peut également entraîner la perte d’écritures que votre base de données considère comme sûres. Avec le mode de cache none, les résultats sont plus faibles et fiables.

Limites et crédits de burst. De nombreux fournisseurs limitent les IOPS par volume ou par offre. De nombreux volumes réseau utilisent également une capacité de burst. Cette capacité est un pool de crédits. Le volume fonctionne rapidement tant que les crédits ne sont pas épuisés, puis revient à un niveau de base beaucoup plus faible. Le symptôme est facile à reconnaître. Une importation ou une restauration s’exécute rapidement pendant plusieurs minutes, puis ralentit fortement et reste lente, sans modification de votre configuration. Vous avez consommé les crédits.

Voisins. Sur un hôte partagé, la latence de votre disque varie selon l’activité des autres systèmes invités. C’est pourquoi vous devez effectuer plusieurs mesures. Exécutez le même test le matin, puis le soir, et comparez la dispersion des résultats. Sur un hôte très sollicité, l’écart entre deux exécutions sur le même volume est souvent supérieur à la différence publiée entre deux supports.

Comment mesurer le disque réellement disponible sur votre VPS

Installez fio, le benchmark IO standard, puis effectuez les mesures. Commencez par trois précautions. Le test crée un fichier. Il utilise donc de l’espace disque et est comptabilisé dans toute limite d’IOPS qui vous est facturée. Effectuez des exécutions courtes. Ne l’exécutez pas avec une profondeur de file maximale sur un volume qui traite du trafic réel. Vous entreriez en concurrence avec votre propre application.

sudo apt update && sudo apt install -y fio ioping sysstat
cd /var/tmp

Lecture aléatoire avec une profondeur de file de 32, qui correspond à la profondeur indiquée par les fournisseurs :

fio --name=randread --filename=fio.test --size=1G --bs=4k --rw=randread \
  --ioengine=libaio --direct=1 --iodepth=32 --numjobs=1 \
  --runtime=30 --time_based --group_reporting

La ligne importante commence par read:

  read: IOPS=184k, BW=719MiB/s (754MB/s)(21.1GiB/30001msec)

--direct=1 contourne le cache de pages du système invité. Le résultat décrit donc le périphérique plutôt que votre RAM. Si vous omettez cette option, vous mesurez la mémoire, qui renvoie une valeur qu’aucun disque ne peut atteindre. Utilisez --size=4G ou une valeur supérieure si vous disposez de suffisamment d’espace. Un fichier de 1G peut tenir entièrement dans le cache de l’hôte et fausser le résultat à la hausse.

Une profondeur de file de 1 mesure la latence brute, c’est-à-dire celle ressentie par un processus monothread :

fio --name=lat --filename=fio.test --size=1G --bs=4k --rw=randread \
  --ioengine=libaio --direct=1 --iodepth=1 --runtime=30 --time_based

Le test de commit permet de prévoir le comportement d’une base de données. Il écrit 4k et appelle fdatasync() après chaque écriture. Le débit indiqué inclut donc le flush :

fio --name=commit --filename=fio.test --size=1G --bs=4k --rw=randwrite \
  --ioengine=psync --fdatasync=1 --runtime=30 --time_based
rm -f fio.test

La valeur d’IOPS obtenue lors de cette exécution est proche du nombre maximal de petites transactions par seconde qu’une connexion à une base de données peut valider. Un commit attend en effet le même flush.

Pour obtenir rapidement un échantillon sans fio :

ioping -c 20 .
--- . (ext4 /dev/vda1) ioping statistics ---
19 requests completed in 4.13 ms, 76 KiB read, 4.60 k iops, 17.9 MiB/s
min/avg/max/mdev = 174.2 us / 217.6 us / 386.1 us / 51.3 us

La valeur mdev, l’écart moyen, est aussi importante que la moyenne. Un écart élevé sur une machine inactive indique que le backend de stockage est partagé et sollicité.

Comment interpréter le résultat

En juillet 2026, ces valeurs sont cohérentes pour un petit VPS. Des dizaines de milliers d'IOPS en lecture aléatoire 4k avec une profondeur de file de 32, et une latence inférieure à environ 0.3 ms avec une profondeur de file de 1, correspondent à du flash local. Une latence de plusieurs millisecondes avec une profondeur de file de 1 indique un chemin réseau, quel que soit le nom de l'offre. Des lectures séquentielles qui s'arrêtent près de 550 MB/s caractérisent une liaison SATA. Une valeur largement supérieure aux capacités d'un périphérique unique indique la présence d'un cache sur le chemin, presque toujours sur l'hôte.

Pour voir l'effet de votre charge de travail actuelle sur le disque :

iostat -x 1 3
vmstat 1 5
cat /proc/pressure/io

Dans la sortie de iostat -x, examinez r_await et w_await, qui indiquent le nombre moyen de millisecondes pendant lesquelles une requête a attendu, ainsi que aqu-sz, qui indique la longueur moyenne de la file. Ignorez %util sur un disque virtuel. Cette valeur indique la proportion de temps pendant laquelle au moins une requête était en attente. Elle ne renseigne pas sur la saturation d'un périphérique capable de traiter de nombreuses requêtes simultanément. Ainsi, une valeur %util de 100 associée à une valeur r_await de 0.2 ms indique un disque actif dans un état normal. Dans vmstat, la colonne wa indique le pourcentage du temps CPU passé à attendre les opérations d'IO. Si /proc/pressure/io existe dans votre kernel, sa valeur some avg10= indique la proportion des 10 dernières secondes pendant laquelle au moins une tâche était bloquée par une opération d'IO. C'est l'indicateur le plus direct pour déterminer si le stockage constitue votre goulot d'étranglement.

À quoi ressemble un VPS limité par le disque

Une load average élevée avec un CPU inactif et un wa important dans vmstat signifie que les processus attendent derrière le disque. Le signal le plus clair du kernel est ce message dans dmesg -T :

INFO: task jbd2/vda1-8:194 blocked for more than 120 seconds.

Cette ligne apparaît parce qu’un thread du kernel a attendu plus de deux minutes une réponse du stockage. Le watchdog des tâches bloquées l’a donc journalisée. jbd2 est le thread du journal ext4. Cela signifie que tout le filesystem attendait, et non qu’un seul programme se comportait mal. Sur un VPS, cela indique généralement un problème au niveau du backend de stockage ou une allowance IOPS épuisée.

Les symptômes applicatifs suivent le même schéma. Le temps de réponse médian reste acceptable, tandis que les requêtes les plus lentes forment une longue traîne, car seules les requêtes qui accèdent au disque sont pénalisées. apt upgrade reste bloqué sur Unpacking pendant plusieurs minutes, car dpkg effectue des flush lors de ses écritures. git status prend plusieurs secondes dans un dépôt volumineux. Il s’agit de coûts liés aux métadonnées et aux flush. Une bande passante supérieure n’y changerait rien.

Que faire lorsque le disque est la limite

Achetez de la RAM avant d’acheter des IOPS. Si le working set tient dans le page cache, les lectures n’atteignent plus du tout le disque. Doubler la mémoire est souvent plus efficace que passer à une classe de stockage plus rapide, et cela coûte généralement moins cher.

Réduisez le nombre de flushes lorsque les données le permettent. Dans PostgreSQL, synchronous_commit = off permet à un commit de retourner avant l’écriture sur le disque. Vous pouvez perdre la dernière fraction de seconde de transactions si le serveur tombe en panne. La base de données n’est pas corrompue, car le write-ahead log est toujours écrit dans l’ordre. Ce compromis convient à une copie destinée à l’analytique, mais pas aux paiements. innodb_flush_log_at_trx_commit = 2 dans MySQL applique le même compromis.

Regroupez les petits fichiers. Le transfert ou la sauvegarde d’un million de petits fichiers est dominé par le coût par fichier. Il est donc plus rapide d’archiver d’abord les fichiers, puis de transférer un seul flux sur un stockage à latence élevée, plutôt que de copier l’arborescence fichier par fichier.

Maintenez le discard actif sur les volumes thin. Avec un stockage thin provisioned, le backend ne sait pas qu’un bloc est libre tant que le système de fichiers ne le lui indique pas. Un volume qui n’est jamais soumis à un trim perd progressivement en performances d’écriture. Ubuntu fournit un timer hebdomadaire pour cela :

systemctl status fstrim.timer
sudo fstrim -av

fstrim -av affiche le nombre d’octets soumis au trim pour chaque point de montage. Un message indiquant que l’opération discard n’est pas prise en charge signifie que le disque virtuel ne transmet pas le discard à l’hôte. Vous n’avez donc rien à corriger.

Ne vous occupez pas du réglage de l’IO scheduler. Sur un disque virtio, cat /sys/block/vda/queue/scheduler affiche généralement déjà none, et la planification réelle s’effectue sur l’hôte, auquel vous n’avez pas accès. Ignorez également noatime : Ubuntu monte les systèmes de fichiers avec relatime par défaut, ce qui évite déjà presque toutes les écritures liées à atime.

Choisir une offre

Payez pour du NVMe lorsqu’une base de données, un serveur de messagerie, un runner CI ou un build utilisant de nombreux packages s’exécute sur la machine. Ne payez pas plus cher pour un site web mis en cache ou pour une application dont le temps d’exécution est consacré aux appels externes. En cas de doute, le disque n’est probablement pas votre facteur limitant, car la plupart des petites charges de travail sur VPS manquent d’abord de RAM ou de bande passante.

Effectuez des mesures dès le premier jour, pendant que vous parcourez les dix premières minutes sur un nouveau VPS, et conservez le résultat dans un fichier. Une baseline vous permet ensuite de prouver que l’hôte est devenu plus lent, plutôt que votre code. Privilégiez les fournisseurs qui indiquent par écrit la classe de stockage et toute limite d’IOPS. Si une offre annonce du NVMe et qu’une lecture avec une queue depth de 1 prend 4 ms, vous utilisez un stockage réseau sur un hôte équipé de NVMe. C’est une offre légitime, mais ce n’est pas le même produit.

FAQ

NVMe est-il toujours plus rapide qu’un SSD SATA sur un VPS ?

Non. À une profondeur de file d’attente de 1, les deux sont proches, avec environ 80 à 150 microsecondes pour une lecture 4k. Un programme mono-thread ne peut pas les différencier. NVMe prend l’avantage lorsque de nombreuses requêtes sont simultanément en attente, car AHCI fournit une file de 32 commandes, tandis que NVMe fournit des milliers de files plus profondes. Sur un hôte partagé, la charge générée par les autres guests peut modifier votre latence davantage que le support lui-même. Mesurez donc votre propre volume avec fio au lieu de vous fier au nom de l’offre.

Comment vérifier si mon VPS utilise réellement NVMe ?

Vous ne pouvez pas le vérifier directement, car virtio masque le périphérique physique. lsblk affiche vda sans chaîne d’identification du modèle, nvme list ne renvoie rien et /sys/block/vda/queue/rotational indique uniquement ce que l’hyperviseur annonce. Mesurez plutôt le comportement. Une lecture aléatoire 4k à une profondeur de file d’attente de 1, avec une latence inférieure à environ 0.3 ms, indique un flash local. Plusieurs millisecondes indiquent qu’un saut réseau se trouve sur le chemin. Des lectures séquentielles qui plafonnent près de 550 MB/s indiquent une liaison SATA.

NVMe accélère-t-il le chargement de mon site web ?

Généralement, non. Après la première requête, Linux sert les fichiers depuis le page cache en RAM. Le disque reste donc inactif. Sur un petit VPS, la vitesse de chargement dépend normalement du temps CPU de l’application et de la bande passante. Le disque redevient critique si le site écrit à chaque requête. C’est par exemple le cas d’un panier géré par une base de données qui effectue fréquemment des commits, car chaque commit attend la fin d’un flush.

Quel résultat fio est-il bon pour un VPS ?

En juillet 2026, un petit VPS utilisant un flash local fournit généralement des dizaines de milliers d’IOPS en lecture aléatoire 4k à une profondeur de file d’attente de 32, avec une latence inférieure à 0.3 ms à une profondeur de file d’attente de 1. Le stockage bloc réseau fournit généralement quelques milliers d’IOPS, avec une latence de quelques millisecondes. Exécutez le test trois fois à des heures différentes. Un écart important entre les exécutions vous renseigne davantage que la moyenne, car il montre dans quelle mesure les autres guests de l’hôte vous affectent.

Dois-je placer ma base de données sur un stockage bloc réseau ?

Vous le pouvez, et de nombreux services managés le font, mais le chemin de commit en subit le coût. Chaque flush traverse le réseau. Une connexion unique effectue donc moins de petites transactions par seconde qu’avec un flash local. En contrepartie, vous bénéficiez d’une durabilité qui résiste à la défaillance de l’hôte. Si vous choisissez un stockage réseau pour une base de données fortement sollicitée en écriture, regroupez le travail en transactions plus importantes afin que moins de flushes prennent en charge davantage de lignes.

#nvme#ssd#stockage#performance#benchmarking