DEV Community

Moon Robert
Moon Robert

Posted on • Originally published at blog.rebalai.com

Edge Computing en 2026: Lo que aprendí después de dos meses migrando nuestra API al edge

En octubre del año pasado, un usuario de Chile me mandó un screenshot de DevTools mostrando 1.3 segundos de tiempo de respuesta en una llamada a nuestra API de autenticación. Nuestra infraestructura estaba en us-east-1 — perfecta para usuarios en Nueva York, bastante mala para alguien en Santiago. Llevábamos meses sabiendo que esto era un problema, pero siempre había algo más urgente. Ese screenshot me dio el empujón que necesitaba.

Somos un equipo pequeño: cinco desarrolladores, una aplicación SaaS de gestión de proyectos con unos 12,000 usuarios activos, y el 30% del tráfico viene de América Latina. Lo digo porque el edge computing no es la misma respuesta para todos. Mi experiencia es la de alguien que tiene que justificar cada hora de ingeniería.

Qué cambió en el edge entre 2024 y 2026

Cuando probé Cloudflare Workers por primera vez hace dos años, la experiencia era frustrante. El soporte de Node.js era parcial, había que reescribir medio proyecto para que funcionara con las APIs de Web, y el modelo de depuración era primitivo. Todavía recuerdo haber pasado una tarde entera intentando que crypto funcionara como esperaba.

Hoy la situación es diferente. Workers con Node.js Compatibility Mode — activado en wrangler.toml con compatibility_flags = ["nodejs_compat"] — cubre la mayoría de los módulos que usas en el día a día. No todos: hay excepciones notables, y voy a tocar eso. Pero la brecha con un entorno Node.js "normal" se cerró bastante.

Lo que más cambió, en mi opinión, es la disponibilidad de almacenamiento en el edge. Antes, Workers KV era la única opción en Cloudflare y tenía una latencia de escritura terrible — eventual consistency que podía tardar decenas de segundos en propagarse. Durable Objects y la integración con D1 hacen que casos de uso más complejos sean viables sin volverte loco.

Vercel también maduró su oferta de Edge Functions. AWS sigue con Lambda@Edge y CloudFront Functions, aunque nunca me convencieron tanto como Cloudflare para proyectos nuevos — la experiencia de desarrollo es más áspera y el debugging más opaco.

Cloudflare Workers vs Vercel Edge Functions: en qué difieren en la práctica

Estas dos plataformas no compiten exactamente en el mismo espacio, aunque superficialmente parezca que sí. Me costó un tiempo entenderlo.

Cloudflare Workers es una plataforma de propósito general. Puedes desplegar workers independientes, crear APIs completas, manejar lógica de routing — todo esto sin que tu aplicación principal esté en Cloudflare. Yo los uso para servicios que viven completamente fuera de nuestro stack de Next.js.

Vercel Edge Functions están muy integradas con el framework que despliegas en Vercel. Si tienes una app de Next.js ahí, son fantásticas para middleware: redireccionamiento basado en geolocalización, A/B testing, modificar headers de respuesta. Pero intentar construir un backend independiente en Vercel Edge Functions se siente forzado.

Una cosa que me sorprendió: los límites de CPU. Cloudflare Workers tiene un límite de 10ms de CPU por request en el plan gratuito (50ms en Workers Paid). Esto es CPU pura, no tiempo de reloj — las operaciones de I/O no cuentan. Para verificación de JWT y lógica simple de autenticación nunca lo rozé. Pero si estás pensando en algo computacionalmente intenso en el edge, esto te va a dar problemas más rápido de lo que esperas.

El pricing también importa. Con Cloudflare Workers pagas por requests (10 millones gratis al mes). Con Vercel el modelo es diferente y más difícil de predecir si tienes picos de tráfico. Para nosotros, Cloudflare resultó más barato una vez que superamos el tier gratuito.

Cómo migré nuestra autenticación al edge

El caso de uso que elegí para empezar fue la verificación de tokens JWT. Teníamos un middleware en Express que validaba el token en cada request, consultaba la base de datos para verificar que la sesión no estuviera revocada, y agregaba la información del usuario al contexto. Todo ocurría en us-east-1. Para un usuario en Buenos Aires, eso son fácilmente 200ms antes de que el request llegara a la lógica de negocio real.

La idea: mover la verificación del JWT al edge, y usar KV de Cloudflare para cachear las sesiones revocadas. Si el token está bien y la sesión no está en la lista negra, el request pasa directo. Si está en la lista negra, un 401 inmediato desde el edge sin tocar el origin.

Antes de implementar tuve que entender el modelo de datos. Workers KV tiene reads rápidos (locales en el edge) pero writes lentos y eventualmente consistentes. Para una lista de sesiones revocadas, esto es aceptable: si un usuario revoca su sesión y tarda 15-20 segundos en propagarse globalmente, no es el fin del mundo. Para un carrito de compras o saldo bancario, sería inaceptable. Con eso claro:

// auth-worker/src/index.js
// Cloudflare Workers — wrangler 3.x, compatibility_flags = ["nodejs_compat"]

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    const startTime = Date.now();

    // Rutas públicas: pasan directo al origin sin validación
    const publicPaths = ['/auth/login', '/auth/register', '/health'];
    if (publicPaths.some(p => url.pathname.startsWith(p))) {
      return fetch(request);
    }

    const authHeader = request.headers.get('Authorization');
    if (!authHeader?.startsWith('Bearer ')) {
      return new Response('Unauthorized', { status: 401 });
    }

    const token = authHeader.slice(7);

    let payload;
    try {
      // Web Crypto API está disponible nativamente — no necesitas librerías externas
      payload = await verifyJWT(token, env.JWT_SECRET);
    } catch (e) {
      return new Response('Invalid token', { status: 401 });
    }

    // Esta lectura es local en el edge: típicamente < 5ms
    const revoked = await env.REVOKED_SESSIONS.get(`session:${payload.jti}`);
    if (revoked) {
      return new Response('Session revoked', { status: 401 });
    }

    // Propagamos info del usuario al origin mediante headers internos
    const modifiedRequest = new Request(request, {
      headers: {
        ...Object.fromEntries(request.headers),
        'X-User-Id': payload.sub,
        'X-User-Role': payload.role,
        'X-Edge-Auth': 'verified', // el origin valida que este header venga del worker
      }
    });

    // Logging async — no bloquea la respuesta al usuario
    ctx.waitUntil(
      logToAxiom(env, {
        path: url.pathname,
        userId: payload.sub,
        processingMs: Date.now() - startTime,
      })
    );

    return fetch(modifiedRequest);
  }
};
Enter fullscreen mode Exit fullscreen mode

Dos semanas en producción: la latencia p95 de autenticación bajó de 340ms a 45ms para usuarios en LATAM. En Norteamérica no cambió mucho (ya estaban en 60-70ms). Europa mejoró de 180ms a 55ms.

Si tienes un caso de uso como este — stateless, con un cache que puede ser eventualmente consistente — la mejora de latencia es muy real con relativamente poco trabajo.

El debugging en el edge va a hacerte sufrir antes de que te acostumbres

wrangler dev es tu mejor amigo para desarrollo local y simula el entorno de Workers razonablemente bien. Pero "razonablemente bien" no es "perfectamente". Hay comportamientos que solo aparecen en producción, especialmente relacionados con el timing de las llamadas a fetch.

Empujé un cambio un viernes a las 5pm — sí, ya sé — y unos 2% de los requests empezaron a devolver 500 sin ningún mensaje de error útil. El problema era que Request.clone() tiene un comportamiento sutil que no había notado en dev: si lees el body del request antes de clonarlo, el clone llega vacío. En mi local, todos mis requests de prueba eran GET sin body, así que nunca lo vi. En producción, los POST con body empezaron a fallar silenciosamente.

wrangler tail te da logs en tiempo real desde producción, lo cual es genial. Pero no es lo mismo que tener un debugger adjunto. Los stack traces a veces apuntan a líneas internas del runtime de V8 que no tienen nada que ver con tu código — normalmente indica un problema de async mal manejado, pero encontrar cuál puede llevarte una hora. Aprendí a loggear con mucha más granularidad que en un backend convencional:

ctx.waitUntil(
  fetch(env.LOGGING_ENDPOINT, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      timestamp: Date.now(),
      path: url.pathname,
      userId: payload?.sub ?? 'anonymous',
      processingMs: Date.now() - startTime,
      region: request.cf?.colo, // el datacenter de Cloudflare que atendió el request
    })
  })
);
Enter fullscreen mode Exit fullscreen mode

Uso Cloudflare Analytics más Axiom para logs detallados. Funciona, pero honestamente no estoy seguro de que sea la configuración óptima — es el área donde sigo buscando algo más limpio.

Qué desplegaría al edge y qué no

Después de dos meses tengo una perspectiva más clara sobre dónde el edge tiene sentido real y dónde no.

Funciona bien: autenticación y autorización, routing personalizado por geolocalización (request.cf?.country viene gratis sin llamadas adicionales), rate limiting por IP, transformación de responses para agregar o remover headers, A/B testing con cookies. Son todas operaciones rápidas, sin estado persistente complejo, donde el beneficio de latencia es máximo.

Lo que no desplegaría todavía: cualquier cosa que requiera acceso frecuente a una base de datos relacional. Sí, existe Hyperdrive de Cloudflare para conectarse a PostgreSQL, y he experimentado con ello, pero la complejidad operacional me parece excesiva para un equipo de cinco personas. Tampoco lógica de negocio con mucho estado, procesamiento de archivos (los límites de memoria son reales), o código que depende de módulos de Node.js aún no compatibles — child_process, partes de fs, cosas así.

¿Vale la pena la complejidad adicional? Depende de dónde están tus usuarios. Si los tienes distribuidos globalmente y tu caso de uso encaja en las categorías de arriba, sí — la mejora es medible, no teórica. Si tu base de usuarios está concentrada cerca de tu región de despliegue, probablemente no. Operar dos ambientes tiene un costo real en debugging y en onboarding.

Mi punto de entrada recomendado: el middleware de autenticación, si tienes usuarios distribuidos. Tiene el mejor ratio beneficio/complejidad de todo lo que probé. Una vez que internalizas el modelo mental del edge — sin estado de proceso compartido, sin sistema de archivos, Web APIs en lugar de Node.js puro — el resto viene más natural. Como capa de optimización sobre un backend convencional, en 2026 ya tiene sentido real. Como reemplazo total de tu infraestructura, todavía no.

Top comments (0)