7 min de lectura

¿Qué latencia debe tener una pasarela de ejecución de escritorio?

Define objetivos p50 y p95 de latencia de pasarela de ejecución de escritorio, compara HTTP y SSH directos con intermediados y separa la aprobación.

¿Qué latencia debe tener una pasarela de ejecución de escritorio?

Una pasarela de ejecución de escritorio solo merece un sitio en el flujo si su demora de máquina queda por debajo del ruido del trabajo interactivo y el tiempo de aprobación se publica aparte. No aprobaría un despliegue basándome en una media, una sola ejecución caliente ni un gráfico que mezcla el tiempo que tarda alguien en tocar Touch ID con el de ejecución del software. Esos números pueden quedar bonitos, pero no dicen si la pasarela interrumpirá el ciclo de editar y probar.

Para HTTP normal y SSH ya conectado, uso como punto de partida un aumento máximo de 25 ms en p50 y 75 ms en p95 en los Mac de desarrollo previstos. Una conexión SSH nueva necesita un presupuesto distinto: 50 ms en p50 y 150 ms en p95. Son requisitos iniciales, no constantes universales. Cada equipo debe ajustarlos según su línea directa, frecuencia de llamadas, red y pruebas de percepción. El método siguiente aporta la evidencia necesaria sin esconder un extremo lento detrás de una mediana aceptable.

Los percentiles deben describir la misma operación

p50 y p95 solo significan algo si cada muestra representa el mismo límite. p50 es la mediana: la mitad de las llamadas terminó en ese valor o antes. p95 es el valor que alcanzó como máximo el 95%. En 200 muestras ordenadas, la definición de rango más cercano toma la observación 190. Las diez más lentas siguen visibles en vez de desaparecer en una media.

Define el límite desde que el llamador inicia la operación hasta que recibe el resultado completo. Esa es la espera del agente. Incluye trabajo del proceso local, transporte, ejecución remota, transferencia de respuesta y todo el trabajo de la pasarela en la ruta. Excluye la preparación de la prueba y, en la pista desatendida, la confirmación humana.

Es habitual comparar límites distintos. El gráfico HTTP directo puede usar time_starttransfer de curl mientras el gráfico de la pasarela mide tiempo de pared alrededor de un proceso. El primero termina con el primer byte; el segundo espera a serializar y devolver todo el resultado. La pasarela pierde antes de empezar. Usa finalización total en ambas rutas y conserva las fases como columnas de diagnóstico.

La misma regla vale para SSH. Una conexión TCP nueva, el protocolo SSH, la autenticación, el comando y la desconexión forman una operación. Un comando por una conexión compartida ya abierta es otra. Informa de ellas por separado. Mezclarlas hace que p50 describa principalmente reutilización y p95, creación de conexión.

Publica al menos estos datos por clase:

  • p50 y p95 de pared para la ruta directa
  • p50 y p95 de pared para la ruta intermediada
  • p50 y p95 del aumento calculado por pares
  • número de muestras, fallos y tiempos agotados
  • equipo, red, versión de pasarela y modo de aprobación

La distribución de diferencias emparejadas importa más que restar dos percentiles de portada. Para la pareja i, calcula delta_i = brokered_i - direct_i bajo la misma condición y después sus p50 y p95. p95(brokered) - p95(direct) aporta contexto, pero no es el p95 del coste y puede ocultar la relación entre picos de red y trabajo de la pasarela.

Un contrato previo evita resultados convenientes

Escribe el contrato antes de medir, porque casi toda optimización accidental cambia la pregunta. Registra modelo de Mac, macOS, alimentación, estado térmico, ruta de red, región del servidor, protocolo HTTP, negociación SSH, tamaños, tiempo límite, concurrencia y reutilización. La carga de fondo debe parecerse a un equipo de desarrollo. Un portátil limpio con editor y compilación cerrados responde a una pregunta de laboratorio.

Usa un destino local y otro remoto realista. El local descubre el coste de máquina porque apenas hay variación de red. El remoto muestra si ese coste sigue importando junto al transporte real. Añadir 40 ms a una llamada local de 3 ms no se siente igual que añadirlos a una llamada remota de 300 ms, y ambos resultados deben aparecer.

Crea clases en vez de una suite mezclada. Como mínimo: respuesta HTTP pequeña con conexión reutilizada, la misma con conexión nueva, conexión SSH nueva que ejecute true y comando SSH sobre conexión disponible. Añade una carga y una respuesta representativas del trabajo del equipo. No uses una API destructiva ni un servidor SSH de producción.

Haz un calentamiento que no entre en la muestra. Luego recoge al menos 200 llamadas por clase alternando el orden directo e intermediado. Si ejecutas primero todas las directas, un cambio térmico, de red, DNS o caché posterior acabará contado como coste de la pasarela. El orden aleatorio sirve, pero la alternancia estricta es más fácil de revisar.

Usa concurrencia uno para la prueba interactiva. Un agente que espera una herramienta actúa en serie. Si varios agentes compartirán la pasarela, añade una prueba de carga etiquetada como capacidad. Veinte llamadas simultáneas descubren colas, pero no sustituyen la latencia de una llamada.

Los fallos se quedan en el informe. Registra el tiempo agotado como fallo con su duración y publica la tasa junto a los percentiles. Eliminar errores premia a una ruta que falla deprisa o pierde las llamadas lentas. Si tantos fallos vuelven inestable p95, repara primero la fiabilidad.

Mide HTTP sin alterar su significado

HTTP directo e intermediado deben usar método, destino, cabeceras, cuerpo, límite y consumo de respuesta iguales. La fuente de la credencial puede cambiar porque aislarla es la función de la pasarela, pero el servidor debe recibir peticiones equivalentes. Antes de medir, confirma estado, cabeceras elegidas y hash del cuerpo.

Las variables write-out documentadas por curl dan relojes de fase. time_connect termina al conectar la red, time_appconnect incluye TLS, time_starttransfer llega al primer byte y time_total a la finalización. Sirven para localizar regresiones, pero el límite comparable sigue siendo el reloj del llamador porque el intermediario puede trabajar antes o después del cliente ascendente.

Esta sonda directa imprime cuatro campos en segundos sin salida de progreso:

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

Para medir pares, coloca la orden directa completa en DIRECT_CMD y la orden de la pasarela en BROKER_CMD. Este ejecutor alterna el orden, usa reloj monotónico, conserva fallos y emite un objeto JSON por observación. Trata cada orden como vector de argumentos para impedir que entren operadores o expansiones del shell.

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=(",", ":")))

Guarda la salida como JSON Lines. Antes del cálculo, compara códigos de éxito y hashes fuera del bucle medido. Una petición intermediada que devuelve menos datos parecerá más rápida; una directa que sigue redirecciones cuando la otra no lo hace mide otro trabajo.

Controla también la reutilización. Si el protocolo y la pasarela conservan una conexión HTTP ascendente, compáralos con un cliente directo persistente. Lanzar curl de nuevo en cada muestra puede perder la reutilización y favorecer al intermediario. Fuerza conexiones nuevas en ambos lados o crea dos clientes persistentes, y publica la elección.

SSH necesita mediciones nuevas y reutilizadas

La preparación SSH suele dominar un comando corto, por lo que un único percentil explica poco. El manual de OpenSSH documenta la conexión compartida con ControlMaster y ControlPersist. Las sesiones posteriores reutilizan transporte y autenticación. Es una optimización válida si ambas rutas reciben la misma oportunidad.

Para la clase nueva, desactiva la conexión compartida, ejecuta un comando inocuo como true y desconecta. En un servidor dedicado, la orden directa puede ser:

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

La pareja intermediada debe usar la acción SSH normal con el mismo servidor, usuario y comando. No impongas una preparación artificial que el agente real nunca utilizará. Haz coincidir la ruta directa con el comportamiento documentado o declara la diferencia arquitectónica.

Para la clase reutilizada, abre la conexión antes del calentamiento y ejecuta solo true durante el muestreo. Verifica la reutilización. El diagnóstico detallado de OpenSSH muestra el contacto con el socket de control; la pasarela debe aportar tiempos o registros equivalentes. Si no puedes probarlo, etiqueta el estado como desconocido y no lo compares con uno conocido.

Repite después con una tarea real no destructiva, como leer un archivo pequeño fijo o consultar el estado de un servicio de prueba. true aísla conexión y ejecución, pero no cubre transferencia, decodificación ni límites. Fija el contenido y calcula el hash recibido.

La autenticación también cambia la comparación. No entregues una clave privada al agente solo para facilitar la línea directa. Ejecuta esa ruta en un arnés aislado con acceso equivalente y considera la exposición de la clave una condición de prueba, no un diseño recomendado. La latencia mide el coste de mediación; no decide si un proceso autónomo debe tener la clave.

Instrumenta el trabajo interno de la pasarela

Verifica la ejecución después
Comprueba sin conexión el registro encadenado sobre texto cifrado con sp audit verify.

El cronómetro externo demuestra el resultado visible; las marcas internas explican la causa. Añade reloj monotónico al recibir, terminar validación, terminar autorización, completar la operación de credencial, enviar al destino, recibir el primer byte, terminar la respuesta, confirmar auditoría y entregar el resultado. Registra duraciones o un identificador opaco, nunca secretos ni cuerpos.

Estas marcas dividen el aumento en partes sobre las que actuar:

  • análisis y serialización del protocolo local
  • consulta de autorización y espera en cola
  • operación de bóveda o credencial
  • preparación del cliente y obtención de conexión
  • persistencia de auditoría y devolución

No compares relojes de pared entre procesos sin resolver sus diferencias. En un Mac, el reloj monotónico de cada proceso sirve para duraciones, pero sus orígenes pueden no coincidir. Lo más seguro es que cada componente informe de su duración y unir los registros con un identificador de prueba.

La auditoría queda dentro del límite si la pasarela promete registrar antes de responder bien. Mover la escritura después gana la prueba debilitando la garantía. Agrupar escrituras puede ser válido, pero el punto de durabilidad publicado debe coincidir con producción. Mide el producto normal con diario y controles activos.

Perfila solo cuando las fases señalen al sospechoso. Si p50 crece con la respuesta, revisa copias y serialización. Si p95 sube y p50 no, revisa bloqueos, colas, vaciados de auditoría, fallos de caché de conexiones y planificación del sistema. El perfil CPU de una mediana tranquila rara vez explica un atasco extremo.

Protege la prueba del coste de observarla. El registro detallado en terminal puede bloquear E/S. Escribe eventos compactos a archivo o memoria, mide una vez con diagnóstico y comprueba que la diferencia sea despreciable. Mantén modos equivalentes en ambas rutas cuando sea posible.

La confirmación humana tiene otro nivel de servicio

El tiempo de confirmación empieza cuando aparece la tarjeta y termina cuando la decisión llega a la llamada bloqueada. No es latencia de máquina. Mezclarlo con llamadas automáticas hace que p95 dependa de la mano, la atención, la pantalla y la interrupción. Eso mide si la aprobación encaja en el trabajo, no la eficiencia de ejecución.

Publica tres distribuciones: máquina antes del aviso, aviso visible hasta decisión y máquina desde la decisión hasta el resultado. El total puede aparecer al lado, siempre que nadie lo use para diagnosticar transporte.

No automatices clics y lo llames demora humana. La automatización mide presentación y transmisión de la decisión, ambas de máquina. Un estudio humano requiere participantes informados, una tarea definida y marcas que no capturen datos sensibles. Indica cuántos participaron y si esperaban el aviso. Un Touch ID esperado en un guion será más rápido que una aprobación inesperada al programar.

Los modos de aprobación también van en filas distintas. Una acción en sesión autorizada, la primera llamada que autoriza un proceso y una confirmación por uso siguen rutas diferentes. Mezclarlas deja el resultado a merced de su frecuencia accidental.

Un presupuesto útil describe la interrupción. Por ejemplo, exige que la tarjeta aparezca en 150 ms desde la llegada a p95, y mide la decisión humana sin aprobarla o suspenderla hasta observar uso real. Después fija objetivos según abandonos, errores y ruptura de la tarea. Una tarjeta rápida es mala si omite identidad o acción necesarias para decidir.

Calcula las diferencias antes de dibujar

Revoca una ejecución sospechosa
El diario Sessions permite revocar al instante ejecuciones activas de agentes.

El calculador debe emparejar observaciones, sacar los pares incompletos de la distribución y contarlos como fallos. Así una llamada directa correcta no se compara con la siguiente intermediada después de que su pareja agotara tiempo. Usa el número de pareja como unión.

Emplea una sola definición. El rango más cercano ordena y elige ceil(p * n), empezando en uno. Algunas bibliotecas interpolan y devuelven un valor no observado. La interpolación puede servir, pero cambiar de método entre cuaderno y panel crea discusiones cerca del límite. Decláralo.

Este calculador lee el JSON Lines anterior y muestra recuentos, p50 y p95 de rango cercano para tiempo directo, intermediado y aumento:

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 salida contiene complete_pairs, fallos por ruta y bloques con p50_ms, p95_ms y max_ms. Añade intervalos de confianza si ya se usan, pero revisa también las filas lentas. Un percentil cambia por variación del sistema o del muestreo; los datos originales permiten distinguirlo.

Las diferencias negativas son válidas. Aparecen si el intermediario reutiliza una conexión que la orden directa abre o si el ruido favorece una muestra. No las conviertas en cero. Corrige una configuración injusta o conserva la variación. Recortarlas sesga el resultado al alza.

Conserva toda la precisión y redondea solo al presentar, por ejemplo a una décima de milisegundo. Evalúa el límite con el dato sin redondear. Un 75,0 mostrado puede estar apenas por encima del requisito.

La cola lenta indica dónde se pierde la confianza

El trabajo interactivo castiga más una pausa irregular que un coste pequeño y estable. Un desarrollador se adapta a 15 ms en cada llamada. Una pausa aleatoria de 800 ms hace parecer roto al agente, sobre todo en una secuencia. Por eso p95 es un requisito.

Examina las observaciones lentas y etiqueta conexión HTTP nueva, protocolo SSH, desbloqueo, escritura de auditoría, despertar, presión de CPU o pico de red. No borres un valor porque puedas explicarlo. Si ocurrirá en producción, pertenece a la distribución. Retira solo un fallo probado de la prueba, conserva el original y publica la regla.

p99 ayuda durante ingeniería, pero 200 llamadas lo dejan en las dos más lentas. Exijo p50 y p95 para adoptar y reviso máximo y filas extremas. Una ejecución nocturna más larga puede sostener p99 después de superar la prueba interactiva.

Separa estados fríos y calientes. Mide inicio de app o desbloqueo como operaciones propias si el usuario las encuentra, y haz lo mismo con reposo y reactivación del Mac. Una app permanente puede ir bien tras calentarse y fallar en la primera acción después de comer.

Cuenta también el coste de secuencia. Doce llamadas en serie acumulan aumentos. Reproducir una secuencia capturada y limpiada descubre rotación de conexiones o un diario que se ralentiza. Conserva distribuciones individuales y añade la diferencia total como dato secundario.

Fija el límite según el coste interactivo

Intermedia sin exponer secretos
Sallyport inyecta credenciales HTTP y SSH, y el agente solo recibe el resultado de la acción.

La pasarela pasa cuando el aumento es pequeño tanto en términos absolutos como frente a la ruta directa. Empiezo con estos límites:

  • HTTP reutilizado: 25 ms en p50 y 75 ms en p95
  • HTTP nuevo: 30 ms en p50 y 100 ms en p95
  • SSH reutilizado: 25 ms en p50 y 75 ms en p95
  • SSH nuevo: 50 ms en p50 y 150 ms en p95

Aplica además un máximo relativo del 20% cuando el p95 directo alcance 100 ms. En una llamada local de 3 ms, el 20% exige menos de un milisegundo y mide ruido. En una llamada remota lenta, solo el límite absoluto puede permitir una fracción excesiva. Ambas reglas cubren casos distintos.

Exige una tasa de fallos no peor que la directa más una tolerancia pequeña declarada, e investiga cualquier tiempo agotado causado por la pasarela. No cambiaría fiabilidad por ganar 10 ms de mediana. Exige equivalencia del resultado y durabilidad prevista; una ruta que modifica la respuesta o registra tarde suspende otra prueba más seria.

Ejecuta en el Mac compatible más lento que use el equipo, no solo en el último modelo. Repite con alimentación y con editor más compilación. Para destinos remotos, haz tres ejecuciones en días o periodos distintos. Así una ventana de red favorable no se convierte en promesa.

Ajusta los números con una prueba ciega. Inyecta demoras fijas en una pasarela simulada, reproduce una tarea típica y pide valorar la interrupción sin revelar el retraso. Pon p95 por debajo de la primera demora que provoque quejas constantes. Conserva 150 ms para SSH nuevo solo si el protocolo directo domina y la tarea completa aún parece inmediata.

Rechaza el despliegue si una clase común incumple p95 aunque el agregado pase. Muchas llamadas HTTP rápidas pueden tapar SSH lento. Aprueba por clase y luego revisa la secuencia completa para comprobar que varios costes aceptables no sumen una pausa inaceptable.

Haz que la adopción sea reversible y comprobable

Empieza con un grupo piloto y una condición de retirada escrita. Congela script, datos de prueba, configuración y calculador en control de versiones. Guarda observaciones, no capturas de pantalla. Un revisor debe poder recalcular y ver cada fallo.

Para Sallyport, ejecuta el mismo arnés por sus canales HTTP y SSH con bóveda, autorización de sesión, ajuste por llamada y auditoría iguales al despliegue previsto. Su registro cifrado y encadenado puede verificarse sin conexión mediante sp audit verify; ejecútalo después para que el informe y la comprobación cubran las mismas llamadas.

Amplía solo cuando cada clase pase en Mac representativos, coincidan los hashes, se verifique la auditoría y los desarrolladores acepten la reproducción completa. Mantén una salida directa en el piloto y registra por qué se usa. Si la gente evita la pasarela por un p95 irregular, la prueba omitió el flujo real. Corrige la medición antes de ampliar.

FAQ

¿Qué p50 es aceptable para una pasarela de ejecución de escritorio?

Para conexiones HTTP o SSH reutilizadas, empieza exigiendo un aumento máximo de 25 ms en p50. Calcula la diferencia de muestras emparejadas en los Mac que usa el equipo, porque la pasarela no debe atribuirse una variación favorable de la red.

¿Qué p95 debe cumplir una pasarela de ejecución?

Un límite inicial práctico es un aumento de 75 ms para HTTP y SSH reutilizados, 100 ms para una conexión HTTP nueva y 150 ms para una conexión SSH nueva. Evalúa cada clase por separado y reduce el límite si una prueba ciega detecta interrupciones menores.

¿Debe incluirse el tiempo de aprobación en la latencia?

No lo mezcles con el percentil de máquina. Publica por separado el tiempo anterior al aviso, el intervalo visible hasta la decisión humana y el tiempo posterior hasta entregar el resultado; muestra el total como métrica de flujo.

¿Cuántas muestras necesita una prueba p95?

Recoge al menos 200 llamadas medidas por clase después del calentamiento. Así p95 tiene observaciones suficientes y todavía resulta sencillo revisar las diez más lentas para localizar conexiones perdidas, colas o fallos de prueba.

¿Deben ejecutarse por lotes las llamadas directas e intermediadas?

No. Alterna el orden dentro de pares para que la temperatura, las cachés y los cambios de red no favorezcan una ruta. Conserva el identificador de pareja y calcula percentiles de cada diferencia.

¿Cómo afecta la reutilización de SSH a la prueba?

Mide las conexiones SSH nuevas y reutilizadas como clases distintas. La conexión compartida de OpenSSH evita configurar transporte y autenticar de nuevo; mezclarlas vuelve ambiguos tanto la mediana como el extremo lento.

¿Basta la latencia media para adoptar la pasarela?

No. La media oculta pausas irregulares que hacen parecer averiado al agente. Exige p50 y p95, publica fallos y tiempos agotados, y revisa el máximo y las observaciones lentas originales.

¿Puede una prueba local sustituir una prueba remota?

Usa ambas. Un destino de bucle local hace visible el coste de máquina; uno remoto y realista muestra cuánto pesa ese coste junto a la red. Ninguno describe por sí solo el trabajo interactivo.

¿Conviene desactivar la auditoría durante la prueba?

No, si producción registra una acción antes de declarar que terminó bien. Mide la durabilidad normal; aplazar la escritura cambia la garantía y produce un resultado rápido que no representa el despliegue.

¿Cuándo debe rechazarse el despliegue de una pasarela?

Deténlo si una clase habitual incumple p95, cambia el resultado, añade fallos sin explicar o no demuestra la auditoría prevista. Un gráfico agregado no debe ocultar una ruta lenta bajo muchas llamadas rápidas.

Sallyport

Sallyport ejecuta llamadas de API y comandos SSH por tu agente de IA. Las claves se quedan en una bóveda local de tu Mac; tú apruebas cada ejecución y cada acción queda en un registro sellado.

© 2026 Sallyport · Código abierto bajo Apache-2.0 · Oleg Sotnikov