Gran parte del trabajo de ingeniería que hemos realizado en los últimos años se ha centrado en ayudar a los clientes a reducir el uso de CPU y el tiempo de reloj de pared. Hace unos meses actualizamos nuestro modelo de precios para reflejar esto, eliminando el medidor de duración para centrarnos estrictamente en las peticiones y el consumo de vCPU. Este nuevo modelo está dando a los clientes más control para que, cuando escriban código más eficiente, reduzcan directamente su gasto.
Este impulso por la eficiencia también se refleja en parte de nuestro trabajo de ingeniería reciente impulsado por clientes, en el que se nos planteó la necesidad de admitir peticiones de backend de mayor duración, especialmente para flujos de trabajo agénticos con uso intensivo de computación, que hacen que los servicios alcancen su límite de tiempo de reloj de pared.
Dado que actuar como proxy de peticiones a modelos de lenguaje de gran tamaño (LLM) lleva tiempo, queríamos ofrecer a los desarrolladores una forma de esperar estas respuestas sin inmovilizar sus recursos disponibles en el edge. Abordar esta necesidad ha evolucionado hasta convertirse en una mejora más amplia de la plataforma que seguiremos ampliando. La mejora es una nueva funcionalidad de transferencia de petición, y ya está disponible en la versión 0.13.0 del SDK de Rust de Fastly.
Gestión de límites de guest de Wasm y peticiones de larga duración
Compute suele aplicar un tiempo de espera de reloj de pared de 2 minutos para los huéspedes de Wasm. Este límite es intencionado para proteger los recursos y garantizar una rotación saludable de las peticiones. El diseño también funciona perfectamente para la gran mayoría de los microservicios y la lógica de edge, donde mantenemos una correspondencia 1:1 entre los huéspedes de Wasm en ejecución y las peticiones entrantes.
Sin embargo, esta arquitectura a veces puede volverse problemática cuando se espera a backends lentos o que no responden. Esto puede deberse a una carga elevada en el origen que ralentiza todas las peticiones en curso, o a la necesidad de finalizar un cálculo intensivo para generar una respuesta. A veces, puede que ni siquiera sea algo que esté bajo el control del origen, como una petición POST de larga duración que tarda en escribir los bytes del cuerpo en el origen debido a una carga grande o a un goteo lento de bytes desde un cliente móvil.
(Nota: los guest de Wasm son módulos de Wasm compilados que se ejecutan dentro de un host de Wasm. Los guest de Wasm se ejecutan en un entorno aislado estricto para que el host pueda ejecutar código no fiable de forma segura sin permitir que comprometa el sistema subyacente.)
La solución: PendingRequest::send_to_client
Para ofrecer una mejor compatibilidad con estas peticiones de backend de larga duración y aumentar el rendimiento de RPS, hemos incorporado una nueva capacidad de PendingRequest::send_to_client. Con esta nueva funcionalidad, podemos enviar una petición asíncrona a un origen y, si es una transferencia directa o una petición de hit-for-pass, podemos transferirla del guest al host mientras sigue en curso, incluso antes de conocer la respuesta final. A continuación, indicamos a la plataforma que devuelva la respuesta al cliente downstream cuando finalmente se resuelva. Como la petición sigue ejecutándose en segundo plano, el guest de Wasm puede finalizar antes y liberar sus recursos para futuras peticiones. Este enfoque aumenta drásticamente el rendimiento de RPS y evita que los servicios de Compute agoten sus instancias de Compute disponibles al esperar a que se completen las peticiones de larga duración.
Ejemplo de Hello World:
use fastly::{Error, Request};
fn main() -> Result<(), Error> {
// 1. Receive the incoming downstream request from the client:
let req = Request::from_client();
// 2. Dispatch the direct pass request asynchronously to your slow backend:
let pending_req = req.with_pass(true).send_async("my_slow_origin_backend")?;
// 3. Hand off the unresolved, in-flight request directly to the host daemon:
pending_req.send_to_client()?;
// 4. Terminate the guest cleanly.
// The host daemon takes over, monitoring the request and piping the eventual
// response back downstream completely independently.
Ok(())
}Casos de uso clave
Puertas de enlace de IA con gran carga computacional y bucles de LLM de larga duración: A principios de este año, exploramos cómo los desarrolladores están creando bucles de agentes de IA de baja latencia seguros directamente en Fastly Compute. En un flujo de trabajo agéntico, un servicio de edge suele coordinar múltiples iteraciones de razonamiento, llamadas a herramientas y prompts de modelos externos. Aunque nuestro tiempo de ejecución proporciona un entorno excepcionalmente seguro para ejecutar estos agentes autónomos, las tareas intensivas de generación de texto o el procesamiento complejo de proveedores de LLM ascendentes pueden escalar drásticamente los tiempos de procesamiento antes de que se generen los encabezados. Al readaptar esos patrones de conexión con la nueva interfaz de programación de aplicaciones del SDK de Rust, puedes usar Fastly Compute como una puerta de enlace de IA inteligente y de alto rendimiento. Tu aplicación de edge puede autorizar la petición mediante backends dinámicos, evaluar los permisos del cliente o inyectar niveles de almacenamiento en caché semántica, y luego lanzar la llamada pesada al LLM de forma asíncrona.
Optimización de protección: La mayoría de las arquitecturas enrutan las peticiones iniciales a un punto de presencia edge, que luego actúa como proxy hacia un punto de presencia de protección donde se produce la manipulación intensiva. Con frecuencia, el punto de presencia edge no modifica la respuesta final, sino que simplemente deja pasar directamente la respuesta del punto de presencia de protección. Con la transferencia de petición pendiente, el punto de presencia edge puede lanzar la petición de shield de forma asíncrona, transferirla y finalizar al instante su huella local de guest, minimizando drásticamente el tiempo total de reloj de pared en tus puntos de presencia edge más cercanos.

Figura 1: El gráfico muestra un servicio de Compute que protege hacia NYC y recibe tráfico constante en Brisbane (BNE), transfiriendo sus peticiones de shield. El tiempo de reloj de pared en BNE casi desaparece después de usar la funcionalidad de transferencia.
Cargas de larga duración: Si tu servicio recibe contenido entrante en el edge desde clientes con poco ancho de banda, usar esta funcionalidad permite que tu servicio evite alcanzar los tiempos de espera del reloj de pared del huésped al permitir que la plataforma continúe la carga de forma independiente de la ejecución del huésped de Wasm.
Modificación de encabezados y gestión de errores
Esta nueva funcionalidad también incluye la capacidad de modificar encabezados en la respuesta final. Puedes poner en cola cambios para eliminar o insertar encabezados específicos antes de realizar la transferencia real. Esto te permite especificar cambios como «elimina este nombre de encabezado» o «inserta este encabezado con el valor X », que se realizarán una vez que llegue la respuesta:
use fastly::{Error, Request};
use fastly::http::request::PendingResponseKind;
fn main() -> Result<(), Error> {
// 1. Receive the incoming downstream request from the client:
let req = Request::from_client();
// 2. Dispatch the direct pass request asynchronously to your slow backend:
let mut pending = req.with_pass(true).send_async("my_slow_origin_backend")?;
// 3.1 Remove the `Server` header added by the origin's application server:
pending.remove_response_header("Server", PendingResponseKind::Response);
// 3.2 Insert the current service version for debugging:
pending.set_response_header(
"X-Service-Version",
fastly::compute_runtime::service_version().to_string(),
PendingResponseKind::Any
);
// 4. Hand off the unresolved, in-flight request directly to the host daemon:
pending.send_to_client()?;
// 5. Terminate the guest cleanly.
// The host daemon takes over, monitoring the request and piping the eventual
// response back downstream completely independently.
Ok(())
}Fíjate en el uso del tipo PendingResponseKind en el ejemplo anterior. Esto permite que el servicio controle si los cambios en los encabezados se aplican a las respuestas del origen PendingResponseKind::Response, a las respuestas de error sintéticas generadas cuando falla la petición en curso PendingResponseKind::Error o a ambas PendingResponseKind::Any. En los casos en que falle la petición en curso, se generará una respuesta 5XX adecuada y se devolverá al cliente. Normalmente, será una de estas:
504 Gateway Timeout: se devuelve automáticamente si la conexión con tu origen agota el tiempo de espera o si se alcanza el tiempo de espera del primer byte para el backend.
502 Bad Gateway: se devuelve si el origen devuelve un cuerpo de respuesta incompleto o mal formado, el backend tiene un certificado de seguridad de la capa de transporte (TLS) no válido o, por cualquier otro motivo, no funciona ni responde correctamente.
Puedes usar el gráfico «Peticiones y errores de backend» en el panel de observabilidad del panel de control de Fastly para ver qué tipos de errores de backend son responsables de las respuestas 502 y 504. Consulta Errores de petición de backend para obtener más información.
Comienza hoy mismo
¡No necesitas esperar a haber desplegado tu servicio en producción para ver cómo esta nueva funcionalidad puede beneficiarte! Es totalmente compatible con los lanzamientos recientes de Viceroy, nuestro entorno de pruebas local. Puedes emular tiempos de espera prolongados del backend, refactorizar tu código para usar Request::send_async/PendingRequest::send_to_client y depurar tus Operaciones de encabezados en cola directamente desde tu terminal de desarrollo local. Aunque la funcionalidad de transferencia está actualmente disponible en exclusiva para nuestro SDK de Rust (v0.13.0), la ampliaremos al resto de nuestros SDK oficiales. Además, asegúrate de consultar nuestra documentación para obtener más información y cuéntanos qué estás creando en nuestro foro.

