Ping instable sur Starlink : la latence seconde par seconde
Dans l’une de deux séances d’une heure, les allers-retours en IPv4 ont le plus changé, avec des pics, aux secondes 12, 27, 42 et 57 de chaque minute ; dans l’autre séance, et en IPv6, la règle du test n’a trouvé aucun motif de ce type. Les allers-retours ont été lus en millisecondes entières : un changement d’une ou deux millisecondes, ou proche de leur variation habituelle, peut donc passer inaperçu, et le test porte sur une seule connexion, derrière son routeur de la maison, pendant deux heures.
Dans une séance, les allers-retours en IPv4 ont le plus changé aux secondes 12, 27, 42 et 57 de la minute
Le test a été lancé en octobre 2026 depuis un ordinateur relié par câble au réseau domestique, sur la connexion dont la page 1 a tracé la route. Toutes les routes vers les cibles sortaient par l’interface filaire ; aucun tunnel, nœud de sortie ou Wi-Fi ne transportait donc les pings. Les pings venaient du ping d’iputils : cinq requêtes d’écho par seconde vers chacune des quatre cibles pendant une heure, un processus par cible, les quatre en parallèle. Ce test d’une heure a été mené deux fois, en deux séances, deux jours différents d’octobre 2026. L’horloge de l’ordinateur a été synchronisée avant et après chaque séance ; ses secondes dans la minute correspondent donc à l’heure réelle.
Les cibles étaient deux résolveurs DNS publics par famille d’adresses :
- le résolveur de Cloudflare,
1.1.1.1en IPv4 et2606:4700:4700::1111en IPv6 ; - le résolveur de Quad9,
9.9.9.9en IPv4 et2620:fe::feen IPv6.
Une cible dans une séance forme une série de mesures, huit en tout.
Le temps aller-retour (RTT, round-trip time) d’un ping est le temps que met sa réponse à revenir. Chaque réponse compte pour la seconde de la minute pendant laquelle sa requête a été envoyée. Pour chaque minute, le changement à une seconde donnée est l’aller-retour médian des réponses de cette seconde moins la médiane de la seconde précédente, la médiane étant la valeur du milieu. La valeur d’une seconde est la taille médiane de ces changements sur l’heure, et les quatre secondes aux valeurs les plus grandes sortent des données : aucune seconde n’a été choisie à l’avance.
Les règles de chaque verdict ont été fixées avant la première séance :
- Un motif exige que les quatre secondes aux plus grands changements soient espacées de 15 secondes, et que le changement médian à ces secondes vaille au moins deux fois le changement médian entre d’autres secondes voisines. Quatre secondes sur 60 tombent à 15 secondes d’écart par hasard dans 15 cas sur 487 635.
- Un pic exige que p99 moins la médiane vaille, à ces secondes, au moins deux fois sa valeur aux autres secondes, ou que 5 pings ou plus y soient perdus, avec au moins deux fois le taux de perte constaté ailleurs. p99 est l’aller-retour sous lequel arrivent 99 réponses sur 100.
Dans la seconde séance, les deux résolveurs IPv4 ont rempli les deux règles aux mêmes quatre secondes : 12, 27, 42 et 57 de la minute, espacées de 15 secondes. C’est là que l’aller-retour a le plus changé, et c’est là qu’il a connu des pics : p99 moins la médiane y valait plus de deux fois sa valeur aux autres secondes, +46 contre +21 ms vers Cloudflare et +50 contre +22 ms vers Quad9. Dans la première séance, pour les quatre cibles, et en IPv6 dans la seconde, la règle du test n’a trouvé aucun motif.
| Séance | Cible | Motif | Quatre secondes de la minute | Changement médian, ms (là ; ailleurs) | p90 moins la médiane, ms (là ; ailleurs) | p99 moins la médiane, ms (là ; ailleurs) | Pic |
|---|---|---|---|---|---|---|---|
| Première | Cloudflare, IPv4 | aucun motif trouvé | |||||
| Première | Quad9, IPv4 | aucun motif trouvé | |||||
| Première | Cloudflare, IPv6 | aucun motif trouvé | |||||
| Première | Quad9, IPv6 | aucun motif trouvé | |||||
| Seconde | Cloudflare, IPv4 | oui | 12, 27, 42, 57 | 4 ; 2 | +13 ; +9 | +46 ; +21 | oui |
| Seconde | Quad9, IPv4 | oui | 12, 27, 42, 57 | 3 ; 2 | +13 ; +8 | +50 ; +22 | oui |
| Seconde | Cloudflare, IPv6 | aucun motif trouvé | |||||
| Seconde | Quad9, IPv6 | aucun motif trouvé |
Toutes les valeurs du tableau 1 sont en ms entières. La règle a comparé les changements médians avant de les arrondir ; c’est ainsi que les 3 et 2 ms de Quad9 remplissent la condition « au moins deux fois ».
Limite
Les allers-retours ont été lus en millisecondes entières. Un changement à peine plus grand que la variation à l’intérieur d’une seconde peut alors rester en deçà de la règle ; une série sans motif peut donc contenir des changements que la règle n’a pas repérés, ou aucun changement à ces secondes, et le test ne permet pas de savoir lequel.
Un ping est de l’ICMP, et les routeurs peuvent traiter l’ICMP autrement que le reste du trafic. Le reste du trafic du foyer passait sur la ligne pendant les deux séances. Tout cela porte sur une seule connexion, filaire, derrière son routeur de la maison, pendant deux heures.
Le tableau 2 donne la dispersion de chaque série : l’écart entre les réponses et la médiane propre à cette cible pour la séance. pN est l’aller-retour sous lequel arrivent N réponses sur 100 ; p10 moins la médiane est donc négatif. Dans chaque série, p99 était de 22 à 28 ms au-dessus de la médiane, et la réponse la plus lente de 144 à 754 ms au-dessus.
| Séance | Cible | p10 | p90 | p99 | p99,9 | Réponse la plus lente |
|---|---|---|---|---|---|---|
| Première | Cloudflare, IPv4 | −5 | +9 | +26 | +62 | +403 |
| Première | Quad9, IPv4 | −4 | +9 | +26 | +123 | +547 |
| Première | Cloudflare, IPv6 | −5 | +9 | +26 | +80 | +402 |
| Première | Quad9, IPv6 | −5 | +9 | +28 | +155 | +754 |
| Seconde | Cloudflare, IPv4 | −5 | +9 | +22 | +53 | +178 |
| Seconde | Quad9, IPv4 | −4 | +9 | +24 | +61 | +192 |
| Seconde | Cloudflare, IPv6 | −5 | +9 | +23 | +54 | +144 |
| Seconde | Quad9, IPv6 | −5 | +9 | +25 | +91 | +431 |
Les résolveurs répondent depuis le site le plus proche de leur opérateur ; chaque aller-retour traverse donc aussi le réseau de cet opérateur. Là où les deux résolveurs IPv4 ont changé aux mêmes secondes, dans la seconde séance, les changements se situent sur la partie du chemin que les deux partagent : le réseau domestique et le routeur, la liaison satellite et le réseau de Starlink jusqu’à l’endroit où les deux routes se séparent. Le test ne peut pas séparer ces parties, et il ne montre pas ce qui a causé les changements.
Des chercheurs signalent des changements toutes les 15 secondes, aux secondes 12, 27, 42 et 57 de la minute
Tanveer et al. ont mesuré depuis quatre antennes Starlink, une en Europe de l’Ouest et trois aux États-Unis (Nord-Est, Midwest et Nord-Ouest), chacune avec un ordinateur relié en Ethernet, vers des serveurs placés aux points de présence (PoP) Starlink qui desservaient ces antennes, à la milliseconde près. Ils signalent des changements importants de latence « at the 12th, 27th, 42nd, and 57th second past every minute » (à la 12e, 27e, 42e et 57e seconde de chaque minute), observés « from all our measured locations for all periods of time », c’est-à-dire depuis tous leurs sites de mesure et sur toutes les périodes (prépublication arXiv, v1, juillet 2023, section 3, consultée en octobre 2026). Ils imputent ces changements à « a global network controller » (un contrôleur réseau global) qui assigne son satellite à chaque antenne, et écrivent dans leur résumé que « these allocations are made every 15-seconds, globally » (ces attributions se font toutes les 15 secondes, à l’échelle mondiale).
Mohan et al., dans un article publié à l’ACM Web Conference 2024, ont mesuré depuis des antennes à Édimbourg et à Munich. Dans leur section 1, ils constatent que Starlink « performs network reconfigurations every 15 s » (reconfigure son réseau toutes les 15 s), et que ces reconfigurations sont « globally synchronized and likely independent of satellite handovers » (synchronisées à l’échelle mondiale et probablement indépendantes des passages d’un satellite à l’autre). Les allers-retours étaient « comparatively stable within each Starlink reconfiguration interval but potentially changing between intervals » (relativement stables à l’intérieur de chaque intervalle de reconfiguration de Starlink, mais susceptibles de changer d’un intervalle à l’autre), et ils changeaient encore entre les intervalles pendant des périodes où l’antenne britannique ne pouvait être desservie que par un seul satellite. Leur conclusion, en section 6.2 (arXiv v2, février 2024, consultée en octobre 2026) : « Hand-offs between satellites are not the cause of these effects. » Autrement dit, les passages d’un satellite à l’autre ne sont pas la cause de ces effets. La même équipe a présenté ces travaux à l’IRTF Open, lors de l’IETF 123, en juillet 2025, avec sur ses diapositives, consultées en octobre 2026, « 15-secs reconfigurations are prevalent at all locations » (les reconfigurations toutes les 15 secondes se retrouvent sur tous les sites) et « 15-secs intervals are globally synchronized » (les intervalles de 15 secondes sont synchronisés à l’échelle mondiale).
Dans la seconde séance faite ici, en IPv4, les changements des deux résolveurs sont tombés aux secondes 12, 27, 42 et 57 de la minute, celles que Tanveer et al. ont signalées. Dans la première séance, et en IPv6 dans la seconde, la règle du test n’a trouvé aucun motif. L’explication des changements toutes les 15 secondes est celle des chercheurs, pas celle de cette page.
Les propres chiffres de latence de Starlink sont construits à partir de moyennes sur 15 secondes. Son document Improving Starlink's Latency indique que Starlink recueille des mesures sur ses routeurs toutes les 15 secondes, et que ces « 15 second average latencies » (latences moyennes sur 15 secondes) donnent ses valeurs médianes et ses valeurs dans le pire des cas. Le PDF ne porte pas de date dans son texte ; le fichier a été créé en mars 2024 (consulté en octobre 2026). Un pic de moins de 15 secondes se fond dans l’une de ces moyennes.
Vous pouvez faire le même test depuis un ordinateur de votre réseau
Le test demande un ordinateur sous Linux avec ping d’iputils et Python 3, relié par câble à votre routeur.
Vérifiez que son horloge est synchronisée avant de commencer, puis de nouveau à la fin de l’heure, comme l’a fait le test. Sur un système avec systemd, cette commande affiche
yesquand c’est le cas :défile horizontalement timedatectl show -p NTPSynchronized --valueLancez ensuite les quatre pings ensemble, chacun écrivant dans son propre fichier :
défile horizontalement ping -D -O -n -i 0.2 -w 3600 1.1.1.1 > cloudflare-ipv4.txt & ping -D -O -n -i 0.2 -w 3600 9.9.9.9 > quad9-ipv4.txt & ping -D -O -n -i 0.2 -w 3600 2606:4700:4700::1111 > cloudflare-ipv6.txt & ping -D -O -n -i 0.2 -w 3600 2620:fe::fe > quad9-ipv6.txt & waitChaque ligne
pingest la commande que le test a lancée pour une cible, avec en plus seulement la redirection vers un fichier et le&.&lance chaque commande en arrière-plan pour que les quatre tournent en parallèle, etwaitrend la main une fois que les quatre se sont arrêtées. Ce que font les options, d’après ping(8) (iputils 20250605, page consultée en octobre 2026) :-Daffiche un horodatage avant chaque ligne, « unix time + microseconds as in gettimeofday » (l’heure Unix et les microsecondes, comme dans gettimeofday).-Osignale une requête qui attend encore sa réponse avant que la suivante parte ; un ping perdu laisse donc lui aussi une ligne. Sans cette option, le nombre de pertes sort à zéro.-ndonne une « numeric output only » (sortie uniquement numérique), sans résolution de noms.-i 0.2envoie un ping toutes les 0,2 seconde. « Only super-user may set interval to values less than 2 ms » (seul le superutilisateur peut fixer un intervalle inférieur à 2 ms) ; cette valeur ne demande donc pas les droits root.-w 3600arrête ping au bout de 3 600 secondes, soit une heure.
Enregistrez ce script sous le nom
latency_fold.py. Il n’utilise que la bibliothèque standard de Python 3 et n’affiche aucun aller-retour. Pour chaque seconde de la minute, il donne les pings envoyés, les pings perdus et le changement médian par rapport à la seconde précédente, à 0,1 ms près, dans les colonnessecond,sent,lostetchange_ms, puis une dernière ligne avec les quatre secondes qui ont connu les plus grands changements.Le script,
latency_fold.pydéfile horizontalement #!/usr/bin/env python3 """Fold the output of `ping -D -O -n -i 0.2 <target>` by second past the minute. For each second past the minute, by the time each request was sent on this computer's clock, it prints how many requests were sent, how many never got a reply, and the median size of the change in the round trip from the second before, in ms (round trips read in whole ms). Usage: python3 latency_fold.py < ping.txt """ import re import statistics import sys from collections import defaultdict INTERVAL_US = 200_000 # ping -i 0.2 sent_at, rtt = {}, {} # request number -> send time, round trip (microseconds) for line in sys.stdin: m = re.match(r"\[(\d+)\.(\d{6})\] .* icmp_seq=(\d+) .*time=([\d.]+) ms$", line) if m: # a reply: it was sent one round trip before it was printed seq, us = int(m[3]), int(float(m[4]) + 0.5) * 1000 # in whole ms, as ping prints 100 ms or more rtt[seq], sent_at[seq] = us, int(m[1]) * 10**6 + int(m[2]) - us m = re.match(r"\[(\d+)\.(\d{6})\] no answer yet for icmp_seq=(\d+)", line) if m: # printed as the next request goes out, one interval later sent_at.setdefault(int(m[3]), int(m[1]) * 10**6 + int(m[2]) - INTERVAL_US) by_second = defaultdict(list) # whole second of sending -> round trips (None: no reply) for seq, t in sent_at.items(): by_second[t // 10**6].append(rtt.get(seq)) sent, lost, changes = [0] * 60, [0] * 60, defaultdict(list) for t, trips in by_second.items(): sent[t % 60] += len(trips) lost[t % 60] += trips.count(None) now = [x for x in trips if x is not None] before = [x for x in by_second.get(t - 1, []) if x is not None] if len(now) >= 3 and len(before) >= 3: changes[t % 60].append(abs(statistics.median(now) - statistics.median(before))) change = {s: statistics.median(c) for s, c in changes.items()} print("second sent lost change_ms") for s in range(60): print(f"{s:6} {sent[s]:4} {lost[s]:4} " + (f"{change[s] / 1000:9.1f}" if s in change else " -")) print("largest changes at seconds:", *sorted(sorted(change, key=lambda s: (-change[s], s))[:4]))Une fois les pings arrêtés, lancez-le sur chaque fichier :
défile horizontalement python3 latency_fold.py < cloudflare-ipv4.txt python3 latency_fold.py < quad9-ipv4.txt python3 latency_fold.py < cloudflare-ipv6.txt python3 latency_fold.py < quad9-ipv6.txtSur la sortie de ping du test lui-même, dans les deux séances, ce script a donné les mêmes lignes par seconde et les mêmes quatre secondes que le script du test, pour chaque cible.
La dernière ligne nomme toujours quatre secondes. Si elles ne sont pas espacées de 15 secondes, l’heure n’a montré aucun motif selon la règle de cette page, et les quatre secondes ne veulent rien dire à elles seules. Si elles le sont, l’autre moitié de la règle compare la médiane des changements de chaque minute à ces quatre secondes avec la même médiane aux autres secondes, et
latency_fold.pyn’affiche pas ces deux valeurs. Sa colonnechange_msdonne à la place la médiane propre à chaque seconde ; les valeurs des quatre secondes comparées au milieu des 56 autres sont donc une vérification approchée, pas la règle elle-même, et quand elles sortent près de deux fois le reste, la vérification peut tomber d’un côté comme de l’autre.
Remarque
Faites l’heure entière. Dans aucune des deux séances, les 10, 20 ou 30 premières minutes n’ont montré le motif avec les secondes de l’heure complète, et une heure complète l’a trouvé ici dans deux des huit séries ; votre heure peut ne pas le montrer non plus.
Ce sont les commandes iputils de Linux ; le ping d’autres systèmes prend d’autres options, et cette page ne les donne pas. En Wi-Fi, la liaison radio à l’intérieur de votre maison fait aussi partie de chaque aller-retour, et ce test ne l’a pas couverte.
901 pings sur 143 462 sont restés sans réponse, plus souvent aux secondes 12, 27, 42 et 57 de la minute
Sur les deux séances et les quatre cibles, 901 pings sur 143 462 sont restés sans réponse : 417 sur 71 733 en IPv4 et 484 sur 71 729 en IPv6. Sur ces 901, 109 avaient été envoyés aux secondes 12, 27, 42 ou 57 de la minute, sur 9 567 envoyés à ces secondes. C’est 1,9 fois le taux de perte des autres secondes, où 792 sur 133 895 sont restés sans réponse : 2,1 fois en IPv4 et 1,8 fois en IPv6. La plupart des pings perdus n’avaient pourtant pas été envoyés à ces secondes : 109 des 901, environ 1 sur 8, l’avaient été.
Ces comptes utilisent les mêmes quatre secondes pour chaque cible dans les deux séances, quel qu’ait été le verdict propre à chaque série ; ils ne reposent donc pas sur la découverte d’un motif.
| Cible ou famille | Pings envoyés | Perdus | Envoyés aux secondes 12, 27, 42 ou 57 | Dont perdus | Envoyés aux autres secondes | Dont perdus |
|---|---|---|---|---|---|---|
| Cloudflare, IPv4 | 35 865 | 221 | 2 390 | 30 | 33 475 | 191 |
| Quad9, IPv4 | 35 868 | 196 | 2 395 | 25 | 33 473 | 171 |
| Cloudflare, IPv6 | 35 864 | 237 | 2 394 | 27 | 33 470 | 210 |
| Quad9, IPv6 | 35 865 | 247 | 2 388 | 27 | 33 477 | 220 |
| IPv4, les deux cibles | 71 733 | 417 | 4 785 | 55 | 66 948 | 362 |
| IPv6, les deux cibles | 71 729 | 484 | 4 782 | 54 | 66 947 | 430 |
| Les quatre | 143 462 | 901 | 9 567 | 109 | 133 895 | 792 |
Un ping sans réponse peut avoir été perdu à l’aller, au retour ou chez la cible. Aucun des deux résolveurs n’a perdu plusieurs fois plus de pings que l’autre dans la même famille d’adresses ; rien n’indique donc qu’un résolveur limitait l’ICMP.
Non testé ici
- Les jeux, les appels et le streaming. Aucune application n’a été testée ; cette page ne donne donc de verdict sur aucune d’elles.
- Les solutions. Aucun réglage, produit ou seconde connexion n’a été essayé.
- Le Wi-Fi et d’autres connexions. Les deux séances ont été faites sur un lien filaire, sur une seule connexion à la maison.
- La cause sur cette ligne. L’explication donnée dans la section sur la recherche est celle des chercheurs. Ce test ne peut pas dire pourquoi le motif est apparu dans la seconde séance et pas dans la première, ni en IPv4 et pas en IPv6, ni si une autre heure le montrerait.
- Les statistiques propres à l’antenne, les obstructions et la météo.
- Les temps d’aller-retour eux-mêmes. Chaque valeur en millisecondes de cette page est une différence, parce qu’un aller-retour vers le site le plus proche d’un résolveur public dit où se trouve ce site. Starlink publie ses propres chiffres, et son document est lié dans la section sur la recherche. Le chiffre de latence typique de l’étiquette de Starlink pour les États-Unis est mis à côté de l’aller-retour minimal par un satellite géostationnaire sur la comparaison des services d’Internet par satellite.
- Les coupures sur plusieurs jours. Deux heures de pings ne peuvent pas montrer à quelle fréquence une connexion se coupe sur une semaine.
Sources
- Making Sense of Constellations: Methodologies for Understanding Starlink's Scheduling Algorithms, Tanveer, Puchol, Singh, Bianchi and Nithyanand, arXiv preprint 2307.00402 v1, consulté en
- A Multifaceted Look at Starlink Performance, Mohan, Ferguson, Cech, Bose, Renatin, Marina and Ott, ACM Web Conference 2024 (arXiv 2310.09242 v2), consulté en
- A Multifaceted Look at Starlink Performance, slides, IRTF Open, IETF 123, consulté en
- Improving Starlink's Latency, Starlink, consulté en
- ping(8), iputils 20250605, man7.org, consulté en
- Starlink a-t-il un programme de parrainage ?, Starlink, consulté en
Journal des tests
- Test Deux séances d’une heure de pings, cinq fois par seconde, depuis un ordinateur relié par câble au réseau domestique vers deux résolveurs DNS publics par famille d’adresses.
Guides associés
- Héberger un serveur sur Starlink sans adresse IPv4 publique ?
Pas directement en IPv4 : sans adresse IPv4 publique, les connexions venues d’Internet arrivent sur le NAT de votre opérateur, et ouvrir un port sur votre propre routeur ne permet pas de l’atteindre.
- MTU Starlink : la MTU du chemin mesurée à 1500 octets
La MTU du chemin depuis une connexion Starlink à la maison était de 1500 octets en IPv4 comme en IPv6, sur chaque chemin testé.
- Starlink convient-il à un homelab ? Le verdict de cinq tests
Sur la seule connexion Starlink domestique testée, des paquets de 1500 octets ont traversé la connexion en IPv4 et en IPv6 en octobre 2026, et les allers-retours en IPv4 ont connu des pics à quatre secondes fixes de chaque minute dans l’un de deux tests d’une heure, avec 901 pings perdus sur 143 462 sur l’ensemble des deux ; les moyens de contourner le NAT au niveau de l’opérateur (CGNAT), comme un tunnel qui part de l’intérieur de votre réseau, ne sont pas testés ici.