> ## Documentation Index
> Fetch the complete documentation index at: https://blog.onetsolutions.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Black Friday : 7 vérifications sur votre serveur avant le pic de trafic

> Cache, test de charge, snapshot, restauration, TTFB, TTL DNS et sécurité : sept vérifications à faire avant la vente, pas pendant.

*Publié le 18 octobre 2026*

Black Friday tombe le vendredi 27 novembre cette année. Un pic de trafic casse rarement un serveur sain. Il révèle ce qui était déjà fragile : un cache installé mais qui ne sert rien, une sauvegarde jamais restaurée, une extension mise à jour toute seule à 3 h du matin le jour J.

Les sept vérifications ci-dessous se font dans les semaines qui précèdent la vente, pas la veille. Chacune donne le pourquoi, le comment, et ce à quoi ressemble un bon résultat. Elles visent WordPress, WooCommerce, PrestaShop ou une petite application, sur VPS ou en hébergement mutualisé.

| # | Vérification | Concerne | Bon résultat |
| - | - | - | - |
| 1 | Cache de page et d'objets | VPS et mutualisé | Deuxième requête servie depuis le cache, panier jamais mis en cache |
| 2 | Test de charge | VPS surtout | Seuils tenus au niveau de trafic visé, sans swap ni erreur 5xx |
| 3 | Snapshot et gel des mises à jour | VPS et mutualisé | Un point de retour daté, aucune mise à jour automatique d'extension pendant la vente |
| 4 | Sauvegardes restaurées | VPS et mutualisé | Une restauration réelle réussie, et sa durée connue |
| 5 | Surveillance du TTFB | VPS et mutualisé | Une alerte sur la lenteur, pas seulement sur la panne |
| 6 | TTL DNS | Toute migration | TTL à 300 s au moins 48 h avant la bascule |
| 7 | Sécurité sous charge | VPS surtout | Règles posées et testées avant la vente |

## 1. Le cache : vérifier qu'il sert, pas qu'il est installé

Un pic de trafic, c'est surtout des visiteurs anonymes qui regardent les mêmes pages. Si chacune de ces vues exécute PHP et interroge la base, le serveur fait mille fois le même travail. Trois couches comptent :

* **le cache de page** : la page HTML complète, servie aux visiteurs non connectés sans toucher PHP ;
* **le cache d'objets** : les résultats de requêtes SQL gardés en mémoire, typiquement dans Redis, qui accélèrent ce que le cache de page ne peut pas servir ;
* **les exclusions** : ce qui ne doit **jamais** être mis en cache.

Commencez par les exclusions. La [documentation WooCommerce](https://developer.woocommerce.com/docs/best-practices/performance/configuring-caching-plugins) est formelle : les pages Panier, Mon compte et Commande restent hors cache, ainsi que les requêtes portant les cookies `woocommerce_cart_hash`, `woocommerce_items_in_cart` et `wp_woocommerce_session_`. Un panier mis en cache, c'est le panier d'un client affiché à un autre.

Puis vérifiez que le cache de page répond vraiment, en visiteur anonyme :

```bash theme={null}
# Trois requêtes de suite sur une page publique : la deuxième doit être plus rapide
for i in 1 2 3; do
  curl -s -o /dev/null -w "HTTP %{http_code}  TTFB %{time_starttransfer}s\n" https://example.com/
done

# En-têtes de cache renvoyés par le serveur
curl -s -o /dev/null -D - https://example.com/ | grep -iE "^x-.*cache|^cache-control|^age:"
```

Sur nos hébergements web, [LiteSpeed est inclus](/fr/litespeed). Avec l'extension LiteSpeed Cache sous WordPress, la [documentation LiteSpeed](https://docs.litespeedtech.com/lscache/lscwp/installation/) indique l'en-tête à chercher : `X-LiteSpeed-Cache: hit` à partir de la deuxième requête, et `X-LiteSpeed-Cache-Control: no-cache` sur les pages volontairement exclues.

```bash theme={null}
# Le panier doit répondre no-cache
curl -s -o /dev/null -D - https://example.com/panier/ | grep -i "x-litespeed-cache"
```

### Redis comme cache d'objets, sur un VPS

```bash theme={null}
sudo apt install redis-server

# Redis ne doit écouter qu'en local
ss -ltnp | grep 6379
redis-cli ping
```

Un cache qui n'a pas de plafond finit par manger la RAM dont PHP et la base ont besoin le jour du pic. Fixez une limite et une politique d'éviction dans `/etc/redis/redis.conf` :

```ini theme={null}
# Valeur d'exemple : à dimensionner selon la RAM de votre VPS
maxmemory 256mb
# Recommandée par la documentation Redis comme choix par défaut pour un cache
maxmemory-policy allkeys-lru
```

```bash theme={null}
sudo systemctl restart redis-server
```

Côté WordPress, l'extension [Redis Object Cache](https://wordpress.org/plugins/redis-cache/) se pilote en WP-CLI :

```bash theme={null}
wp plugin install redis-cache --activate
wp config set WP_REDIS_HOST "127.0.0.1"
wp config set WP_REDIS_PORT "6379"
# Préfixe utile si plusieurs sites partagent le même Redis
wp config set WP_REDIS_PREFIX "boutique_"
wp redis enable
wp redis status
```

Après quelques heures de trafic normal, regardez le taux de succès :

```bash theme={null}
redis-cli INFO stats | grep -E "keyspace_(hits|misses)|evicted_keys"
```

La [documentation Redis](https://redis.io/docs/latest/develop/reference/eviction/) donne la formule : `keyspace_hits / (keyspace_hits + keyspace_misses)`. Un taux faible avec beaucoup d'`evicted_keys` signifie que le plafond est trop bas.

<Warning>
  Un Redis joignable depuis Internet sans mot de passe est une porte d'entrée, pas un cache. Voir notre avis [RediShell](/fr/redishell-cve-2025-49844) pour les réglages `bind` et ACL.
</Warning>

**PrestaShop.** Dans Paramètres avancés > Performances, laissez le cache Smarty activé, n'utilisez pas la compilation forcée des templates (réservée à l'édition d'un thème), et vérifiez que le mode debug est désactivé. La [documentation PrestaShop 8](https://docs.prestashop-project.org/v.8-documentation/user-guide/configuring-shop/advanced-parameters/performance) recommande de tester le site après avoir activé le cache JavaScript du CCC.

**Bon résultat :** un en-tête de cache `hit` sur les pages publiques, `no-cache` sur le panier et la commande, un TTFB nettement plus bas à la deuxième requête qu'à la première.

## 2. Un test de charge, avant le jour J

Vous ne savez pas combien de visiteurs votre serveur encaisse tant que vous ne l'avez pas mesuré. Le seul bon moment pour le découvrir, c'est avant la vente.

[k6](https://grafana.com/docs/k6/latest/) est libre, se lance en une commande via Docker, et s'arrête avec un code d'erreur si vos seuils ne sont pas tenus. Lancez-le depuis **une autre machine** que le serveur testé, sinon vous mesurez votre poste plus que votre site.

```javascript theme={null}
// charge.js
import http from 'k6/http';
import { check, sleep } from 'k6';

const BASE = __ENV.BASE_URL;

export const options = {
  // Paliers d'exemple : partez du pic de l'an dernier relevé dans vos statistiques
  stages: [
    { duration: '2m', target: 20 },
    { duration: '5m', target: 20 },
    { duration: '2m', target: 50 },
    { duration: '5m', target: 50 },
    { duration: '1m', target: 0 },
  ],
  thresholds: {
    // Moins de 1 % d'erreurs
    http_req_failed: ['rate<0.01'],
    // 95 % des réponses avec un premier octet en moins de 800 ms
    http_req_waiting: ['p(95)<800'],
  },
};

export default function () {
  // Une page en cache, une fiche produit, une recherche (jamais en cache)
  const pages = ['/', '/produit/exemple/', '/?s=cadeau&post_type=product'];
  for (const path of pages) {
    const res = http.get(`${BASE}${path}`);
    check(res, { 'statut 200': (r) => r.status === 200 });
    sleep(1);
  }
}
```

```bash theme={null}
docker run --rm -i grafana/k6 run -e BASE_URL=https://example.com - <charge.js
```

`http_req_waiting` est, selon la [référence des métriques k6](https://grafana.com/docs/k6/latest/using-k6/metrics/reference/), le temps d'attente du premier octet : le TTFB. Pendant le test, regardez le serveur en parallèle :

```bash theme={null}
# Colonnes si/so : swap, wa : attente disque. Une ligne toutes les 5 secondes
vmstat 5

# Erreurs côté serveur web pendant la fenêtre du test
sudo tail -f /var/log/nginx/error.log
```

<Warning>
  Ne testez que votre propre site, et jamais le tunnel de paiement : vous créeriez de vraies commandes et déclencheriez les filtres antifraude de votre prestataire. Sur un hébergement mutualisé, le serveur est partagé avec d'autres clients : parlez-en au [support](https://help.onetsolutions.net/fr/console/support) avant de lancer quoi que ce soit.
</Warning>

Si les seuils cassent, corrigez le cache d'abord : c'est presque toujours moins cher qu'un serveur plus gros. Si le serveur sature malgré un cache qui sert, redimensionnez l'instance depuis la console, et faites-le avant la semaine de la vente. Un redimensionnement est un changement comme un autre : il passe par le snapshot de la section suivante.

**Bon résultat :** k6 termine avec le code de sortie 0 au niveau de trafic visé, sans swap, sans erreur 5xx dans les journaux.

## 3. Un snapshot avant chaque changement, puis le gel

Chaque changement de la semaine (configuration du cache, redimensionnement, dernière mise à jour) commence par un [snapshot](https://help.onetsolutions.net/fr/vps/snapshot) depuis la console. Il coûte une minute et vous donne un point de retour daté.

Pour qu'un snapshot de VPS capture une base de données dans un état cohérent, l'[agent QEMU](https://help.onetsolutions.net/fr/vps/agent) doit tourner : c'est lui qui gèle le système de fichiers pendant la capture.

```bash theme={null}
systemctl is-active qemu-guest-agent
```

<Note>
  Un snapshot n'est pas une sauvegarde. Il sert à revenir en arrière après un changement raté, pas à survivre à la perte du serveur. C'est le rôle de la section 4.
</Note>

Puis **gelez**. Appliquez toutes les mises à jour avant la vente, et plus aucune pendant : ni déploiement, ni mise à jour d'extension ou de thème, ni changement de configuration. Gardez en revanche les mises à jour mineures automatiques du cœur WordPress, celles qui portent les correctifs de sécurité, comme expliqué dans [notre guide de durcissement WordPress](/fr/securiser-wordpress-apres-wp2shell).

```bash theme={null}
# Noter les extensions en mise à jour automatique, pour les rétablir après la vente
wp plugin auto-updates status --all --enabled-only --field=name > ~/auto-updates-extensions.txt

# Suspendre les mises à jour automatiques des extensions et des thèmes
wp plugin auto-updates disable --all
wp theme auto-updates disable --all

# Après la vente : rétablir la configuration d'origine
xargs -r wp plugin auto-updates enable < ~/auto-updates-extensions.txt
```

Écrivez dès maintenant l'unique exception : une faille critique activement exploitée pendant le gel. [wp2shell](/fr/wp2shell-cve-2026-63030) a été exploitée dans les heures suivant sa publication. Dans ce cas : snapshot, correctif, vérification du tunnel de commande. Rien d'autre.

**Bon résultat :** un snapshot pris après les dernières mises à jour, l'agent QEMU actif, et une liste vide pour `wp plugin auto-updates status --all --enabled-only` pendant la vente.

## 4. Des sauvegardes restaurées pour de vrai

Une sauvegarde qui n'a jamais été restaurée est une hypothèse. La règle 3-2-1, telle que la formule le [guide de l'US-CERT publié par la CISA](https://www.cisa.gov/sites/default/files/publications/data_backup_options.pdf) :

* **3** copies de chaque fichier important : l'original et deux sauvegardes ;
* sur **2** supports différents ;
* dont **1** hors site.

Appliqué à un site hébergé chez nous :

| Copie | VPS | Hébergement web |
| - | - | - |
| 1. Production | Le serveur | Le compte cPanel |
| 2. Sauvegarde chez l'hébergeur | L'option [Backup](https://help.onetsolutions.net/fr/vps/backup), quotidienne | Une [sauvegarde cPanel](https://help.onetsolutions.net/fr/web-hosting/backup) complète |
| 3. Hors site | Un export vers un autre prestataire ou vos locaux | L'archive cPanel téléchargée et conservée ailleurs |

Le snapshot n'entre pas dans le décompte : il vit au même endroit que le serveur.

Testez ensuite la restauration de la base, la partie qui casse le plus souvent :

```bash theme={null}
# Export cohérent d'une base InnoDB, sans verrouiller les tables
mysqldump --single-transaction --quick --routines --triggers boutique | gzip > ~/boutique-$(date +%F).sql.gz

# Restauration dans une base jetable, chronométrée
mysql -e "CREATE DATABASE restore_test"
time (gunzip -c ~/boutique-$(date +%F).sql.gz | mysql restore_test)

# Comparer le nombre de commandes : wp_wc_orders si la boutique utilise HPOS,
# sinon wp_posts avec post_type = 'shop_order'
mysql -N -e "SELECT COUNT(*) FROM boutique.wp_wc_orders"
mysql -N -e "SELECT COUNT(*) FROM restore_test.wp_wc_orders"

# Nettoyer
mysql -e "DROP DATABASE restore_test"
```

Adaptez le nom de la base et le préfixe des tables à votre installation. Sur PrestaShop, comparez `ps_orders`.

**Bon résultat :** les comptes concordent, le site redémarre sur l'environnement de test, et vous savez combien de temps prend une restauration complète. C'est ce chiffre qui vous dit combien de ventes vous perdriez un vendredi soir.

## 5. Surveiller le TTFB, pas seulement la disponibilité

Une sonde de disponibilité classique se contente d'un code 200. Une boutique qui répond 200 en neuf secondes est en ligne pour la sonde, et fermée pour vos clients.

Mesurez le TTFB (temps jusqu'au premier octet). [web.dev](https://web.dev/articles/ttfb) classe un TTFB de 0,8 s ou moins comme bon, et au-delà de 1,8 s comme mauvais, en précisant que c'est un repère indicatif et non un Core Web Vital. Partez de là, puis ajustez sur vos propres mesures.

Surveillez deux adresses : une page en cache, qui mesure le serveur web, et le panier, qui ne l'est jamais et mesure donc PHP et la base. C'est le panier qui ralentit le premier.

```bash theme={null}
#!/usr/bin/env bash
# ttfb-check.sh — à lancer depuis une autre machine que le serveur surveillé
set -u
URLS=("https://example.com/" "https://example.com/panier/")
SEUIL=0.8                                   # secondes
WEBHOOK="https://hooks.example.com/votre-webhook"   # webhook entrant Slack ou Mattermost
ETAT=/var/tmp/ttfb-check
mkdir -p "$ETAT"

for url in "${URLS[@]}"; do
  cle=$(printf '%s' "$url" | md5sum | cut -c1-12)
  mesure=$(curl -o /dev/null -s --max-time 10 -w '%{http_code} %{time_starttransfer}' "$url")
  code=${mesure%% *}
  ttfb=${mesure##* }
  if [ "$code" != "200" ] || awk -v t="$ttfb" -v s="$SEUIL" 'BEGIN { exit !(t > s) }'; then
    n=$(( $(cat "$ETAT/$cle" 2>/dev/null || echo 0) + 1 ))
    echo "$n" > "$ETAT/$cle"
    # Alerter au troisième échec consécutif, pas sur un pic isolé
    if [ "$n" -eq 3 ]; then
      curl -s -X POST -H 'Content-Type: application/json' \
        -d "{\"text\": \"$url : HTTP $code, TTFB ${ttfb}s\"}" "$WEBHOOK" > /dev/null
    fi
  else
    echo 0 > "$ETAT/$cle"
  fi
done
```

```bash theme={null}
sudo install -m 755 ttfb-check.sh /usr/local/bin/ttfb-check.sh
# Une mesure par minute : alerte après trois minutes de lenteur
( crontab -l 2>/dev/null; echo "* * * * * /usr/local/bin/ttfb-check.sh" ) | crontab -
```

Si vous préférez des graphiques, Uptime Kuma fait partie du catalogue [One Click Apps](/fr/one-click-apps) et trace le temps de réponse de chaque sonde. Installez-le sur un autre serveur que la boutique : une surveillance qui tombe avec le site ne prévient personne.

**Bon résultat :** quelques jours de mesures avant la vente pour connaître votre niveau normal, et une alerte de test reçue sur le bon canal, par la bonne personne.

## 6. DNS : baisser le TTL 48 h avant toute migration

Le meilleur conseil DNS pour la semaine du Black Friday : ne migrez pas. Si vous devez quand même changer de serveur, préparez la bascule à l'avance.

Les résolveurs gardent un enregistrement en cache pendant toute la durée de son TTL. Si votre enregistrement `A` a un TTL d'un jour, une partie de vos visiteurs continuera d'arriver sur l'ancien serveur jusqu'à un jour après le changement. Baissez donc le TTL **avant**, puis attendez au moins l'ancienne durée avant de basculer. Quarante-huit heures couvrent les TTL usuels d'un jour avec de la marge.

Lisez le TTL configuré directement sur un serveur qui fait autorité, pas dans le cache de votre résolveur :

```bash theme={null}
NS=$(dig +short NS example.com | head -1)
dig +noall +answer example.com A @"$NS"
dig +noall +answer www.example.com A @"$NS"
# Le deuxième champ de chaque ligne est le TTL, en secondes
```

Si l'ancien TTL dépasse 48 h, attendez d'autant plus longtemps. Dans la zone DNS de votre domaine sur la console, le champ TTL propose 5 minutes, soit 300 secondes. Si le domaine est lié à un hébergement web, la zone se gère dans cPanel. La [page sur le pointage d'un domaine vers un VPS](https://help.onetsolutions.net/fr/vps/redirect-my-domain) détaille les enregistrements à écrire.

Après la bascule, laissez l'ancien serveur en ligne tant que son journal d'accès reçoit des requêtes, puis remontez le TTL.

**Bon résultat :** `dig` sur le serveur faisant autorité affiche `300` au moins 48 h avant la bascule.

## 7. La sécurité sous charge : décidée avant, pas pendant

Le vendredi soir n'est pas le moment de découvrir comment bannir une adresse IP. Tout ce qui suit se pose et se teste maintenant.

**Extensions à jour avant le gel.**

```bash theme={null}
wp core version
wp plugin list --update=available --fields=name,version,update_version
```

**fail2ban sur SSH.** Depuis Debian 12, `rsyslog` n'est plus installé par défaut selon les [notes de version](https://www.debian.org/releases/bookworm/amd64/release-notes/ch-information.en.html) : il n'y a donc pas de `/var/log/auth.log`, et la prison `sshd` doit lire le journal systemd. Les paquets de Debian 13 et d'Ubuntu 24.04 le prévoient déjà, celui de Debian 12 non. L'écrire dans `jail.local` couvre les trois.

```ini theme={null}
# /etc/fail2ban/jail.local
[DEFAULT]
# Vos adresses fixes (bureau, agence) ne doivent jamais être bannies
ignoreip = 127.0.0.1/8 ::1 203.0.113.10

[sshd]
enabled = true
backend = systemd
```

**Limiter le débit là où c'est utile, et nulle part ailleurs.** Sur WordPress, la page de connexion est la cible habituelle. Le [guide de durcissement nginx](/fr/auditer-et-durcir-nginx-sur-un-vps) explique `limit_req` en détail. Pour `wp-login.php` :

```nginx theme={null}
# Dans le bloc http — débit d'exemple, à ajuster
limit_req_zone $binary_remote_addr zone=connexion:10m rate=5r/m;
```

```nginx theme={null}
# Dans le bloc server, avant le location générique des fichiers PHP
location = /wp-login.php {
    limit_req zone=connexion burst=5 nodelay;
    include snippets/fastcgi-php.conf;
    # Adaptez le socket à votre version de PHP
    fastcgi_pass unix:/run/php/php8.4-fpm.sock;
}
```

Le `fastcgi_pass` n'est pas optionnel : sans lui, nginx servirait le fichier PHP comme un fichier statique. fail2ban fournit ensuite un filtre `nginx-limit-req`, qui lit le journal d'erreurs de nginx et bannit les adresses qui dépassent la limite de façon répétée :

```ini theme={null}
# À ajouter dans /etc/fail2ban/jail.local
[nginx-limit-req]
enabled = true
backend = auto
logpath = /var/log/nginx/error.log
```

`backend = auto` n'est pas décoratif : Ubuntu 24.04 règle toutes les prisons sur le journal systemd par défaut, alors que nginx écrit ses erreurs dans un fichier.

```bash theme={null}
sudo nginx -t && sudo systemctl reload nginx
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
sudo fail2ban-client status nginx-limit-req
```

N'appliquez aucune limite sur les adresses de retour de votre prestataire de paiement, ni sur `/wp-json/` dans son ensemble : un webhook de paiement bloqué, c'est une commande payée qui reste « en attente ».

**WooCommerce : limiter les tentatives de commande.** Si votre boutique utilise le bloc Checkout, WooCommerce propose une limitation de débit de la validation de commande, dans WooCommerce > Réglages > Avancé > Fonctionnalités. Selon la [documentation de la Store API](https://developer.woocommerce.com/docs/apis/store-api/rate-limiting/), elle est désactivée par défaut et, une fois activée, plafonne la validation à 3 requêtes par 60 secondes. Passez une commande de test après l'avoir activée.

**La procédure, par écrit.** Qui est d'astreinte, et comment bannir une adresse à la main :

```bash theme={null}
sudo fail2ban-client set nginx-limit-req banip 198.51.100.7
sudo fail2ban-client set nginx-limit-req unbanip 198.51.100.7
```

<Warning>
  N'activez pas le [pare-feu de la console](https://help.onetsolutions.net/fr/vps/firewall) dans l'urgence. Dès la première règle ajoutée, il bloque tout le trafic qui n'est pas explicitement autorisé. Si vous en voulez un, posez-le bien avant la vente, avec les règles SSH, HTTP et HTTPS. En cas d'erreur, la [console KVM](https://help.onetsolutions.net/fr/vps/kvm-console) reste accessible.
</Warning>

**Bon résultat :** aucune extension en attente de mise à jour, les deux prisons fail2ban actives, une commande de test passée avec la limitation WooCommerce activée, et une procédure que quelqu'un d'autre que vous peut suivre.

## Ce qui compte vraiment

Rien de tout cela ne rend un serveur infaillible. Ces vérifications déplacent le travail : du vendredi soir, quand chaque minute coûte des ventes, vers les semaines d'avant, quand une erreur ne coûte qu'un retour au snapshot.

Si vous n'avez le temps que pour deux, faites le test de charge et la restauration. Ce sont les deux qui révèlent ce que vous croyez acquis.

Une question sur un serveur hébergé chez nous ? [Notre équipe est disponible](https://help.onetsolutions.net/fr/console/support) depuis votre espace client.

<Info>
  **Black Friday chez OnetSolutions.** Du vendredi 27 novembre 2026 à 00 h 00 au mardi 1er décembre 2026 à 23 h 59 (heure de Paris), une seule offre sur la première année de nos VPS et hébergements web en facturation annuelle. Réservée aux nouveaux services, une fois par client. Le renouvellement se fait au tarif annuel normal. [Le principe et les dates](https://onetsolutions.net/black-friday).
</Info>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.