5 min de lecture

Quelle latence exiger d'une passerelle d'exécution locale ?

Fixez les seuils p50 et p95 d'une passerelle d'exécution locale, comparez HTTP et SSH directs ou relayés, puis isolez le temps d'approbation.

Quelle latence exiger d'une passerelle d'exécution locale ?

Une passerelle d'exécution locale mérite d'être adoptée seulement si son délai machine reste sous le bruit du travail interactif et si le délai humain est publié à part. Je n'accepterais jamais un déploiement sur la foi d'une moyenne, d'un seul essai chaud ou d'un graphique qui mélange le geste vers Touch ID au temps logiciel. Ces chiffres ne disent pas si la passerelle brisera la boucle édition et test.

Pour HTTP courant et SSH déjà connecté, je pars d'un maximum ajouté de 25 ms au p50 et 75 ms au p95 sur les Mac visés. Une connexion SSH neuve reçoit un budget distinct: 50 ms au p50 et 150 ms au p95. Ce sont des exigences de départ. L'équipe doit les adapter à sa référence directe, à la fréquence des appels, au réseau et à des essais de perception.

Les percentiles doivent couvrir la même opération

p50 est la médiane et p95 la valeur sous laquelle finissent 95% des appels. Avec 200 observations triées, la méthode du rang le plus proche choisit la 190e pour p95 et laisse les dix plus lentes visibles.

Mesurez du lancement par l'appelant à la réception du résultat complet. Cette limite comprend processus local, transport, exécution distante, réponse et travail de passerelle. Elle exclut la préparation et, dans la série automatique, la confirmation humaine.

Ne comparez pas time_starttransfer de curl à un chronomètre entourant tout un processus. Le premier s'arrête au premier octet, le second après sérialisation et retour. Mesurez la fin complète des deux côtés et conservez les phases comme diagnostic.

Séparez aussi les connexions SSH neuves des commandes utilisant une connexion partagée. Sinon p50 décrit surtout la réutilisation et p95 surtout l'établissement de connexion.

Publiez pour chaque classe:

  • p50 et p95 directs et relayés
  • p50 et p95 des écarts par paires
  • nombre d'appels, échecs et expirations
  • machine, réseau, version et mode d'approbation

Pour la paire i, calculez delta_i = brokered_i - direct_i, puis les percentiles de ces écarts. Soustraire deux p95 globaux donne un contexte, pas le p95 du surcoût, et peut masquer une corrélation avec les pointes réseau.

Un contrat de test empêche les résultats arrangés

Avant l'essai, notez modèle de Mac, macOS, alimentation, température, trajet réseau, région cible, protocole HTTP, négociation SSH, tailles, délai maximal, concurrence et réutilisation. Gardez une charge de fond proche du poste d'un développeur.

Utilisez une cible locale et une distante réaliste. La première révèle le coût machine; la seconde montre son importance au milieu du transport. Ajouter 40 ms à 3 ms en bouclage n'a pas le même effet qu'à 300 ms à distance.

Créez au minimum quatre classes: petit HTTP réutilisé, petit HTTP neuf, SSH neuf exécutant true, et commande SSH sur connexion existante. Ajoutez une charge et une réponse représentatives, sans API destructive ni serveur de production.

Préchauffez sans conserver ces appels, puis mesurez au moins 200 paires en alternant l'ordre. Exécuter toutes les directes d'abord transforme un changement thermique, DNS, cache ou réseau en coût de passerelle.

Utilisez une concurrence de un pour l'interactif. Un test à plusieurs agents mesure la capacité et les files, pas le délai d'un agent qui attend.

Conservez les erreurs. Comptez les expirations avec leur durée et publiez le taux. Si les échecs rendent p95 instable, réparez la fiabilité avant de discuter millisecondes.

Mesurez HTTP sans en changer le sens

Les deux trajets doivent partager méthode, destination, en-têtes, corps, expiration et lecture de réponse. La source des identifiants diffère, mais le serveur doit recevoir une requête équivalente. Vérifiez statut, en-têtes retenus et empreinte du corps.

curl documente time_connect, time_appconnect, time_starttransfer et time_total. Ces phases localisent une régression, tandis que le temps complet vu par l'appelant reste la limite comparable.

Cette sonde directe imprime les quatre phases:

curl -sS -o /dev/null -w '%{time_connect} %{time_appconnect} %{time_starttransfer} %{time_total}
' -H "$AUTH_HEADER" "$ENDPOINT"

Placez la commande directe dans DIRECT_CMD et celle de la passerelle dans BROKER_CMD. Le programme suivant alterne l'ordre, utilise une horloge monotone, garde les échecs et émet un objet JSON par observation.

import json
import os
import shlex
import subprocess
import time

samples = int(os.environ.get("SAMPLES", "200"))
timeout = float(os.environ.get("TIMEOUT", "10"))
commands = {
    "direct": shlex.split(os.environ["DIRECT_CMD"]),
    "brokered": shlex.split(os.environ["BROKER_CMD"]),
}

for n in range(10):
    label = "direct" if n % 2 == 0 else "brokered"
    subprocess.run(commands[label], stdout=subprocess.DEVNULL,
                   stderr=subprocess.DEVNULL, timeout=timeout)

for n in range(samples):
    order = ("direct", "brokered") if n % 2 == 0 else ("brokered", "direct")
    for label in order:
        started = time.monotonic_ns()
        try:
            result = subprocess.run(commands[label], capture_output=True,
                                    timeout=timeout)
            ok = result.returncode == 0
            code = result.returncode
        except subprocess.TimeoutExpired:
            ok = False
            code = None
        elapsed_ms = (time.monotonic_ns() - started) / 1_000_000
        print(json.dumps({"pair": n, "path": label, "ms": elapsed_ms,
                          "ok": ok, "code": code}, separators=(",", ":")))

Conservez la sortie en JSON Lines. Hors de la boucle chronométrée, comparez codes de réussite et empreintes. Une réponse plus courte ou une politique de redirection différente mesure un autre travail.

Contrôlez la réutilisation. Si la passerelle garde la connexion montante, le client direct doit le faire aussi. Sinon forcez une connexion neuve des deux côtés. Publiez ce choix.

SSH exige des mesures neuves et réutilisées

La mise en place SSH domine souvent une commande courte. Le manuel OpenSSH décrit le partage avec ControlMaster et ControlPersist, qui évite de refaire transport et authentification. Donnez la même possibilité aux deux trajets.

Pour une connexion neuve, désactivez le partage, exécutez true, puis déconnectez:

ssh -F /dev/null -o BatchMode=yes -o ControlMaster=no -o ConnectTimeout=10 "$TEST_HOST" true

L'appel relayé utilise l'action SSH normale avec le même hôte, utilisateur et commande. N'inventez pas un montage que l'agent réel n'emploiera pas; alignez le direct ou déclarez la différence.

Pour la classe réutilisée, ouvrez avant le préchauffage et n'exécutez que true. Vérifiez le partage dans le diagnostic OpenSSH ou les mesures de la passerelle. Sans preuve, marquez l'état inconnu.

Recommencez avec une tâche réelle sans effet, par exemple lire un petit fichier fixe. true ne couvre ni transfert, ni décodage, ni limite de résultat. Comparez l'empreinte des octets.

N'offrez pas une clé privée à l'agent pour faciliter le témoin direct. Exécutez celui-ci dans un banc isolé à accès réseau équivalent. La latence mesure le coût du relais, pas l'acceptabilité de l'exposition.

Instrumentez le travail interne

Révoquez une session suspecte
Le journal Sessions permet de révoquer immédiatement une exécution d'agent active.

Le chronomètre externe prouve l'expérience; les marques internes expliquent l'écart. Horodatez réception, validation, autorisation, accès au secret, départ amont, premier octet, fin amont, validation d'audit et livraison. Gardez durées ou identifiant opaque, jamais secrets ou corps.

Décomposez ainsi:

  • analyse et sérialisation locales
  • recherche d'autorisation et file
  • opération du coffre
  • préparation du client et connexion
  • persistance d'audit et retour

Ne comparez pas les heures murales de processus différents sans traiter leurs horloges. Chaque composant peut publier sa durée monotone et les enregistrements se rejoignent sur un identifiant.

Si le produit garantit l'audit avant la réussite, cette écriture appartient à la mesure. La repousser gagnerait du temps en affaiblissant la garantie. Testez la durabilité et les contrôles ordinaires.

Si p50 croît avec la taille, examinez copies et sérialisation. Si seul p95 monte, cherchez verrous, files, vidages d'audit, connexions absentes et ordonnanceur. Un profil CPU médian explique rarement une pause de queue.

Évitez que le diagnostic bloque le terminal. Écrivez des événements compacts en fichier ou mémoire et vérifiez une fois que leur coût est négligeable.

La confirmation humaine a son propre objectif

Elle commence à l'affichage de la carte et finit au retour de la décision. Ce n'est pas du temps machine. La mélanger fait dépendre p95 de la main, de l'attention et de l'état de l'écran.

Publiez trois distributions: machine avant invite, invite visible jusqu'à décision, machine après décision. Le total reste une mesure de flux, pas un diagnostic transport.

Un clic automatisé mesure l'affichage et la transmission, pas un humain. Une étude nécessite consentement, tâche définie et marques sans données sensibles. Indiquez le nombre de participants et s'ils attendaient l'invite.

Séparez session déjà autorisée, première autorisation de processus et confirmation par appel. Ces chemins diffèrent par conception.

Un budget peut exiger l'affichage en 150 ms au p95, puis observer le délai humain sans seuil avant l'usage réel. Fixez ensuite une cible selon abandons, erreurs et interruptions. Une carte rapide mais insuffisante pour décider reste mauvaise.

Calculez les écarts avant le graphique

Testez HTTP et SSH ensemble
Une passerelle exécute les actions bearer, basic, à en-tête personnalisé et SSH par ses canaux natifs.

Associez les observations par identifiant. Retirez un couple incomplet de la distribution mais comptez-le comme échec, afin de ne pas lier la mauvaise mesure suivante.

Gardez une définition unique. Le rang le plus proche choisit ceil(p * n) après tri. Une interpolation peut être valable, mais changer entre carnet et tableau crée un désaccord artificiel.

Ce calculateur lit le JSON Lines et produit p50, p95 et maximum des trois distributions:

import json
import math
import sys

rows = [json.loads(line) for line in sys.stdin if line.strip()]
by_pair = {}
failures = {"direct": 0, "brokered": 0}

for row in rows:
    if not row["ok"]:
        failures[row["path"]] += 1
        continue
    by_pair.setdefault(row["pair"], {})[row["path"]] = row["ms"]

direct = []
brokered = []
deltas = []
for pair in sorted(by_pair):
    values = by_pair[pair]
    if "direct" not in values or "brokered" not in values:
        continue
    direct.append(values["direct"])
    brokered.append(values["brokered"])
    deltas.append(values["brokered"] - values["direct"])

def percentile(values, fraction):
    ordered = sorted(values)
    rank = max(1, math.ceil(fraction * len(ordered)))
    return ordered[rank - 1]

result = {"complete_pairs": len(deltas), "failures": failures}
for name, values in (("direct", direct), ("brokered", brokered),
                     ("added", deltas)):
    result[name] = {
        "p50_ms": percentile(values, 0.50),
        "p95_ms": percentile(values, 0.95),
        "max_ms": max(values),
    }
print(json.dumps(result, separators=(",", ":")))

La sortie contient complete_pairs, les échecs, puis p50_ms, p95_ms et max_ms. Les intervalles de confiance ne remplacent pas les lignes lentes brutes.

Conservez les écarts négatifs. Ils peuvent venir d'une connexion réutilisée ou du bruit réseau. Les ramener à zéro biaise le résultat; corrigez un montage inéquitable ou gardez la variance.

Gardez la précision et n'arrondissez qu'à l'affichage. Le seuil s'évalue sur la valeur brute, car 75,0 ms affichées peuvent dépasser légèrement 75.

La queue révèle la perte de confiance

Le travail interactif tolère mieux 15 ms stables qu'une pause aléatoire de 800 ms. Plusieurs appels en série rendent cette pause semblable à une panne. p95 est donc un critère d'adoption.

Étiquetez les lignes lentes: nouvelle connexion HTTP, protocole SSH, déverrouillage, vidage d'audit, réveil, CPU ou réseau. Une cause expliquée ne justifie pas la suppression si elle arrivera en production. Ne retirez qu'une erreur de test prouvée et publiez la règle.

Avec 200 appels, p99 dépend presque des deux plus lents. Exigez p50 et p95, puis inspectez maximum et données brutes. Une longue exécution pourra traiter p99 ensuite.

Séparez lancement, déverrouillage, sortie de veille et régime chaud. Une app permanente peut réussir après préchauffage et rater le premier appel de l'après-midi.

Rejouez aussi une séquence nettoyée. Douze appels série cumulent le coût et révèlent rotation de connexions ou journal qui ralentit. Gardez chaque distribution et ajoutez la durée totale.

Fixez le seuil selon le coût interactif

Vérifiez le test après coup
sp audit verify contrôle hors ligne le registre chaîné directement sur le texte chiffré.

Je pars de quatre limites ajoutées:

  • HTTP réutilisé: 25 ms au p50, 75 ms au p95
  • HTTP neuf: 30 ms au p50, 100 ms au p95
  • SSH réutilisé: 25 ms au p50, 75 ms au p95
  • SSH neuf: 50 ms au p50, 150 ms au p95

Quand le p95 direct atteint 100 ms, ajoutez une limite relative de 20%. Sur 3 ms locaux, ce ratio mesure surtout du bruit; sur un appel distant lent, l'absolu seul peut autoriser une trop grande fraction.

Le taux d'échec ne doit pas dépasser le direct plus une petite tolérance annoncée. Enquêtez sur toute expiration causée par la passerelle. Exigez aussi résultats équivalents et durabilité d'audit normale.

Testez le Mac compatible le plus lent réellement utilisé, sous alimentation et charge d'éditeur plus compilation. Répétez les cibles distantes à trois périodes pour ne pas transformer un réseau favorable en promesse.

Une épreuve perceptive en aveugle peut resserrer les chiffres: injectez des délais fixes, rejouez une tâche et cherchez la première gêne constante. Placez p95 en dessous avec une marge.

Refusez si une classe courante manque p95 même si l'agrégat réussit. Des HTTP rapides peuvent cacher un SSH lent. Validez chaque classe, puis la séquence complète.

Rendez l'adoption réversible et vérifiable

Commencez par un groupe pilote avec condition de retour écrite. Versionnez script, données, configuration et calculateur, puis conservez toutes les observations plutôt que des captures.

Pour Sallyport, passez le même banc par ses canaux HTTP et SSH avec coffre, autorisation de session, réglage par appel et audit identiques au déploiement prévu. Vérifiez ensuite son registre chiffré et chaîné hors ligne avec sp audit verify afin que contrôle et rapport couvrent les mêmes appels.

Étendez seulement si chaque classe passe sur les Mac représentatifs, si les empreintes correspondent, si l'audit est valide et si l'équipe accepte le scénario complet. Gardez une sortie directe pendant le pilote et consignez son usage. Si p95 pousse les gens à contourner la passerelle, corrigez d'abord la mesure.

FAQ

Quel p50 accepter pour une passerelle d'exécution locale ?

Pour HTTP ou SSH avec connexion réutilisée, commencez par limiter l'ajout à 25 ms au p50. Calculez les écarts par paires sur les Mac réellement utilisés, car la passerelle ne doit pas profiter d'une variation réseau favorable.

Quel p95 une passerelle d'exécution doit-elle respecter ?

Un bon seuil initial est 75 ms ajoutées pour HTTP et SSH réutilisés, 100 ms pour une nouvelle connexion HTTP et 150 ms pour une nouvelle connexion SSH. Évaluez chaque classe séparément et resserrez le seuil si un test en aveugle révèle une gêne plus tôt.

Faut-il inclure l'approbation dans la latence ?

Ne l'intégrez pas au percentile machine. Publiez séparément le temps avant l'invite, le délai entre son affichage et la décision humaine, puis le temps restant jusqu'au résultat; gardez le total comme mesure du flux.

Combien d'échantillons faut-il pour mesurer p95 ?

Recueillez au moins 200 appels mesurés par classe après préchauffage. p95 repose alors sur assez d'observations et les dix plus lentes restent faciles à examiner.

Faut-il exécuter les appels directs et relayés par lots ?

Non. Alternez leur ordre dans chaque paire afin que température, caches et réseau ne favorisent aucun trajet. Conservez l'identifiant de paire et calculez le percentile des écarts.

Comment la réutilisation SSH change-t-elle le test ?

Mesurez séparément connexions neuves et réutilisées. Le partage OpenSSH évite de refaire le transport et l'authentification; les mélanger rend la médiane et la queue ambiguës.

La latence moyenne suffit-elle pour décider ?

Non. Elle masque les pauses irrégulières qui donnent l'impression que l'agent est bloqué. Exigez p50 et p95, publiez échecs et expirations, puis examinez le maximum et les lignes lentes.

Un test local peut-il remplacer un test distant ?

Utilisez les deux. Le bouclage expose le coût machine; une cible distante réaliste montre son poids au milieu du réseau. Aucun ne décrit seul le travail interactif.

Faut-il couper l'audit pendant le test ?

Non si la production enregistre l'action avant de signaler sa réussite. Mesurez la durabilité normale; repousser l'écriture modifie la garantie et produit un chiffre sans rapport avec le déploiement.

Quand faut-il refuser le déploiement ?

Suspendez-le si une classe courante manque son p95, modifie le résultat, ajoute des erreurs inexpliquées ou ne prouve pas l'audit prévu. Une vue agrégée ne doit pas cacher un trajet lent.

Sallyport

Sallyport exécute les appels d'API et les commandes SSH à la place de votre agent IA. Les clés restent dans un coffre-fort local sur votre Mac ; vous approuvez chaque exécution et chaque action est consignée dans un journal scellé.

© 2026 Sallyport · Open source sous Apache-2.0 · Oleg Sotnikov