Elido
13 min de lecturaFunciones
Esencial

Smart links explicados: enrutamiento edge sin un servicio extra

Qué es un smart link, dónde se ejecuta y las dimensiones de enrutamiento que Elido admite. Deep-dive de ingeniería sobre invalidación de caché edge, semántica first-match y cuándo no usar uno

Marius Voß
DevRel · edge infra
Diagram of a single short link branching into three destinations based on country, device, and language

Imprimimos 18.000 folletos para un lanzamiento de producto DACH en marzo. Un enlace corto en el reverso, tres páginas de aterrizaje regionales a las que queríamos enviar a la gente: /de para visitantes alemanes, /fr para la pequeña fracción francesa, /en para todos los demás. La líder de marketing hizo la pregunta obvia: ¿imprimimos tres folletos o uno?

Imprimes uno. El enlace hace el enrutamiento.

Un "smart link" es una sola URL corta cuyo destino se computa en la redirección, no en el momento de creación del enlace. Hay un slug. Hay varios destinos posibles. La decisión ocurre en el mismo handler que de otra manera emitiría un 302 plano - sin servicio separado al que llamar, sin shim JS en una página de aterrizaje, sin salto extra. Esta publicación trata sobre cómo se ve realmente bajo el capó, las seis dimensiones sobre las que Elido enruta, y los casos en los que deberías alcanzar otra herramienta en su lugar.

La gente alcanza los smart links desde tres experiencias previas diferentes, y las compensaciones son diferentes en cada una.

Redirección plana. Un slug, un destino, cero lógica. El handler de redirección hace una búsqueda en caché y escribe un 302. No puedes vencerlo en latencia; tampoco puedes hacerlo condicional. Ese es el suelo - cualquier cosa más sofisticada cuesta algo.

Smart link en el edge. Un slug, varios destinos posibles, un pequeño paso de evaluación de reglas insertado entre la búsqueda en caché y la respuesta. Como la regla vive en el mismo proceso que la búsqueda en caché, el coste es submilisegundo (0,3ms p50 / 1ms p95 en el caso de Elido). El visitante ve un round trip HTTP. La caché del navegador no se envenena, porque las respuestas 302 no son cacheables por defecto según RFC 7234 §4.2.2 - un hecho que importa aquí, porque el enrutamiento por solicitud solo tiene sentido si a cada solicitud se le permite elegir su propio destino.

Router A/B JavaScript en una página de aterrizaje. Una página HTML neutral se renderiza, JS examina navigator.userAgent o un servicio geo-IP, luego window.location = '/foo'. Esta es la peor opción de las tres. El visitante ve una renderización HTML, luego una redirección, luego la página real - al menos un round trip extra, a menudo dos si la búsqueda geo es de terceros. La indexación SEO está confusa porque los crawlers ven la página neutral. Los navegadores que bloquean cookies y las extensiones de privacidad rompen la mitad JS. Las notas de la versión Intelligent Tracking Prevention 2.3 de Apple llaman a este patrón exactamente: los enlaces de tracking del lado del cliente vía document referrer son throttled, y la mitigación requiere participación del lado del servidor. Si estás enrutando en JS hoy, ya estás pagando la factura.

El lugar correcto para poner una decisión de enrutamiento es el mismo salto que ya está emitiendo la redirección. Eso es lo que hacen los smart links edge.

Por qué vive en el edge - el presupuesto de latencia#

El tier de redirección de Elido tiene un presupuesto de latencia estricto: p50 5ms, p95 15ms en un cache hit, excluyendo el handshake TLS. Ese número no es aspiracional - cualquier cosa que nos empuje por encima se arranca. SQL síncrono en la ruta caliente, compilación regex por solicitud, I/O bloqueante en el evento de clic: todo fuera, todo movido a workers de ruta fría.

Las dos razones por las que existe ese presupuesto:

  1. Las redes móviles añaden su propio impuesto. La guía "Reducing Network Latency" de Apple recorre cómo los retrasos de redes celulares se componen a través de cadenas de redirección. Cada salto extra añade RTT que la red del visitante ya infló. Cuantos menos saltos añadamos, menos los castiga su red.
  2. La proximidad del edge es la palanca real. La introducción de Cloudflare al enrutamiento edge-side lo enmarca de la misma manera: la decisión más barata es la tomada en el mismo proceso que el escritor de respuesta, en el POP más cercano al visitante. No somos únicos haciendo enrutamiento edge; lo que es único es agruparlo en el acortador de URL en lugar de pedirte que despliegues una función Workers / Lambda@Edge separada.

Si pateáramos la evaluación de reglas a un servicio downstream - digamos, una hipotética "rules-api" accesible por HTTP - añadiríamos un round trip same-region en cada solicitud. En la región eso son alrededor de 5ms mínimo (un salto en la misma región sobre una red privada), y en tráfico entre regiones la cola se pone fea muy rápido. El p95 de 15ms no sobrevive al round trip. Por eso las reglas de smart link son inline, en el binario edge, evaluando contra matchers compilados que se construyeron cuando el enlace se cargó en la caché. Todo el motor de reglas son alrededor de 400 líneas de Go.

Ese acoplamiento estrecho es también por lo que podemos hacer ediciones de reglas en tiempo real: los cambios de reglas se propagan vía un canal pub/sub de la caché en memoria (link:invalidate) al que cada POP edge se suscribe. El LRU L1 evicciona dentro de un segundo de la publicación, la siguiente solicitud repuebla desde L2, y la nueva regla está en vivo. Más sobre esto abajo.

Las seis dimensiones de enrutamiento#

Los smart links de Elido coinciden en seis cosas. Cada una mapea a una entrada específica a la que el edge tiene acceso por solicitud.

País. Dos letras ISO 3166-1 alpha-2, derivado de la IP del visitante vía geoip. Útil cuando tienes escaparates regionales y el aumento en conversión por país vale la complejidad del enrutamiento. El truco clásico aquí son los viajeros - un alemán de vacaciones en España golpea el destino español si enrutas solo por país. Si la preferencia de idioma importa más que la ubicación geográfica, enruta en languages en su lugar. Discutimos el flujo geoip completo en la publicación de privacidad de analytics - la IP se trunca antes del almacenamiento para que el lado GDPR se mantenga limpio.

Dispositivo. mobile, tablet, desktop, analizado de la cadena User-Agent en el momento de la solicitud. El caso de uso por el que los marketers alcanzan esto: banners de instalación de app que van a la App Store en iOS, Play Store en Android, y una página de marketing en escritorio. Lo que vigilar: las cadenas User-Agent en iPad han sido un objetivo móvil desde que iPadOS comenzó a presentar la UA de Safari de escritorio por defecto, y nuestra detección de tablet lo acomoda, pero no es 100% en cada versión de navegador. Si la diferencia entre tráfico de tablet y escritorio te importa en dólares, instrumenta el destino y verifica.

OS. ios, android, macos, windows, linux. La misma fuente User-Agent que dispositivo, partición más estrecha. El caso de deep-link: enrutar visitantes iOS a un Universal Link que la app intercepta y cae a la App Store; enrutar Android a la Play Store con datos de referrer preservados. Esto es para lo que construimos la integración Apple App Site Association.

Idioma. Etiqueta de idioma principal de la cabecera Accept-Language del visitante. Códigos ISO 639-1 como de, fr, pt. La trampa: Accept-Language es la preferencia del navegador, que a menudo no está de acuerdo con la geo IP. Un expatriado francés en Berlín obtiene country: DE, languages: ["fr", "en"] - si los quieres en /fr, enruta en idioma; si los quieres en el escaparate alemán porque estás haciendo A/B testing de precios localizados, enruta en país. Secuencia las reglas en consecuencia.

Hora del día y día de la semana. Ventana HH:MM en cualquier zona horaria IANA, más un bitmap days_of_week. Ofertas con tiempo limitado - una página de aterrizaje "happy hour" que se activa a las 17:00 Europe/Berlin lun-vie y cae a la página regular fuera de esa ventana - son el ajuste natural. La ventana time_start / time_end admite wraparound (22:0002:00), que suena obvio pero nos atrapó cuando portamos el motor de reglas del prototipo que no lo manejaba. El esquema completo está en la guía de smart links.

Host del referrer. La parte del hostname de la cabecera Referer, normalizada. Útil para destinos conscientes de partners: visitantes que llegan desde partner.example obtienen una página de aterrizaje co-brandeada; todos los demás obtienen el predeterminado. Menos útil de lo que solía ser - los navegadores modernos eliminan Referer agresivamente cuando la página referente establece Referrer-Policy: no-referrer o cuando la navegación cruza contextos HTTPS de una manera que la política no permite. Trata las reglas de referrer como una señal suave, nunca como autenticación.

Eso es todo. Seis dimensiones cubren las decisiones de enrutamiento de marketing que hemos visto en tres años de conversaciones con clientes. Las omisiones deliberadas son la identidad de usuario (no la conocemos en la redirección), cabeceras HTTP arbitrarias (el coste-a-beneficio no está ahí para los pocos equipos que han preguntado), y splits aleatorizados (usa rotación de variantes en su lugar, que es una función separada).

Semántica first-match; fallback siempre requerido#

Las reglas son un array. El edge las recorre en orden. La primera regla cuyo bloque match está completamente satisfecho gana, y su destination_url es el objetivo de la redirección. El destination_url de nivel superior del enlace es el fallback incondicional. Nos negamos a crear un smart link sin uno - un smart link nunca produce un 404, por diseño.

La forma mínima viable:

{
  "destination_url": "https://acme.example/en",
  "targeting_rules": [
    {
      "match": { "countries": ["DE", "AT", "CH"] },
      "destination_url": "https://acme.example/de"
    },
    {
      "match": { "languages": ["fr"] },
      "destination_url": "https://acme.example/fr"
    }
  ]
}

Los visitantes DACH golpean /de porque la regla 1 coincide primero. Un expatriado francés en Berlín tiene country=DE, así que también golpean /de - la regla 1 coincide antes de que la regla 2 tenga la oportunidad. Si quieres al expatriado francés en /fr, intercambia las reglas para que la regla de idioma se compruebe primero. El orden en el dashboard es el orden en que evaluamos.

Elido dashboard rule builder, three rules stacked in evaluation order: DACH visitors, French speakers, iOS app fallback. Each rule has country / device / browser / destination / label fields, with an Advanced toggle for OS, language, time-of-day, and regex

Dos cosas que esto implica que vale la pena decir en voz alta:

  • Las reglas más amplias van al final. Una regla sin condiciones match coincide con todo; si está primera, ninguna regla debajo de ella se dispara. El dashboard valida contra esto y te advierte, pero la API no, por lo que las reglas construidas por script necesitan una comprobación de cordura.
  • La exclusión mutua es cosa tuya. Si dos reglas coinciden con un solo visitante, la primera gana silenciosamente. No hay error, no hay bandera, no hay métrica. Hemos considerado emitir una advertencia en el momento de carga del enlace cuando dos reglas son detectables como superpuestas, y eso está en la hoja de ruta para el próximo release minor. Por ahora: lee tus reglas de arriba a abajo y confía en el orden.

El coste: propagación de invalidación de caché#

Cada decisión de enrutamiento tiene una ventana de propagación. Las reglas de smart link editadas en el dashboard se propagan a través de las cachés L1 en los tres POPs de Elido en aproximadamente 1 segundo en el camino feliz. Aproximadamente, porque:

  • El LRU L1 en cada POP mantiene enlaces con reglas con un TTL de 60 segundos (la arquitectura de caché está documentada aquí). El TTL es el límite superior - incluso sin una publicación de invalidación, una entrada obsoleta desaparece en un minuto.
  • La publicación de invalidación es vía el pub/sub de la caché en memoria. Los POPs de la UE y EE. UU. Este comparten un cluster de caché; Asia-Pacífico tiene el suyo propio. La propagación cross-region es esencialmente la latencia de replicación de la caché más el procesamiento pub/sub de nuestro suscriptor, que ha estado por debajo de 1 segundo p99 en nuestras métricas durante el último trimestre.
  • Un POP que ha perdido su suscripción a la caché cae al TTL de 60 segundos. Alertamos sobre la pérdida de suscripción; el on-call tiene 5 minutos de clics en buffer antes de que el WAL entre en acción.

Traducción: para flujos de marketing donde 60 segundos de enrutamiento obsoleto está bien, no tienes que pensar en esto. Para flujos donde la obsolescencia importa - una rotación de descargo legal, un split de cohorte de facturación donde el destino equivocado cobra la moneda equivocada - la jugada es status=disabled primero, luego re-habilitar después de un minuto, luego publicar la nueva regla. Hemos añadido un endpoint GET /v1/links/{id}/status para que un pipeline CI pueda consultar la propagación para terminar antes de voltear un interruptor downstream.

Tres casos donde la herramienta correcta no es un smart link.

El renderizado del lado del servidor del destino es mejor. Si la variante tiene que ser inyectada en la respuesta HTML - digamos, localización de precios que depende del estado autenticado del visitante, o una página de aterrizaje que extrae un hero específico de cohorte de tu CMS - eso es un trabajo para el propio servidor del destino, no la redirección. La redirección elige adónde enviar al visitante; el destino elige qué renderizar. La lógica de enrutamiento que vive en el edge no puede ver tu sesión auth, y forzarlo requeriría o filtrar la sesión a la ruta de redirección (que no haremos) o hacer proxy a través del edge (que no hacemos por el presupuesto de latencia). Renderiza variantes en el origen.

A/B testing estadísticamente riguroso. Los smart links enrutan por solicitud, no por visitante. Si un visitante aterriza dos veces en cinco minutos desde el mismo dispositivo, podría ver dos destinos diferentes bajo una regla aleatorizada, que es el comportamiento correcto para "envía 50% del tráfico móvil a A y 50% a B" pero el comportamiento equivocado para "mide si la variante A convierte mejor que la variante B sobre una ventana de 4 semanas". Para esto último, necesitas una cookie de variante estable y una herramienta de experimentación que haga las estadísticas correctamente. PostHog, GrowthBook y LaunchDarkly todos hacen esto. Nosotros no, y no vamos a - el tooling es un trabajo diferente. Usa rotación de variantes con round_robin para muestreo de baja apuesta y alcanza una plataforma de experimentación cuando necesites defender el resultado.

Enrutamiento consciente de identidad. Los smart links son deliberadamente sin estado. Evalúan contra country | device | OS | language | time | referrer y nada más. Si necesitas enrutar basado en el tier de un usuario autenticado, sus feature flags, o cualquier cosa que requiera buscar "quién es esta persona", la ruta de redirección es la capa equivocada. Resuelve la identidad en el origen y sirve la variante desde allí. O, si realmente necesitas una decisión en el momento de la redirección, acuña enlaces cortos por usuario vía la API - cada usuario autenticado obtiene su propio slug, el destino del slug es correcto para ese usuario en el momento de la creación, y nunca tienes que hacer resolución de identidad en la ruta caliente.

Qué sigue#

Si quieres probar la forma de la regla en tus propios datos, la guía de docs recorre el esquema JSON y el editor del dashboard. El constructor de reglas vive bajo cualquier página de edición de enlace en el dashboard - Links → ⋯ → Targeting.

Dos mejoras aterrizando en el próximo release minor: una jerarquía de fallback para languages (para que pt-BR degrade limpiamente a pt, luego a en, sin escribir tres reglas), y un paso de análisis estático en el momento de guardar el enlace que marca reglas superpuestas para que el dashboard pueda advertir antes de que la regla esté en vivo. Ambos son trabajo de implementación, sin cambios de esquema rompedores. Si tienes una forma de regla que no admitimos y crees que deberíamos, el canal de feedback está en la parte inferior de la página de la función smart links.

Relacionados en el blog#

Prueba Elido

Pega una URL, obtén un enlace corto

Sin registro. El enlace vive 30 días. Crea una cuenta para conservarlo.

Gratis, sin registro · 2 por día

Prueba Elido

Acortador de URL alojado en la UE: dominios personalizados, análisis profundo y API abierta. Plan gratuito - sin tarjeta de crédito.

Etiquetas
smart links
edge routing
url shortener
conditional links
device targeting

Seguir leyendo