RRelo Docs
API & Guías

Arquitectura

Arquitectura técnica de la plataforma Relo. Edge, ingest, almacenamiento, failover, seguridad y fraud detection.

Relo está diseñado para nunca perder un evento. Cada click, pixel, postback o pull pasa por capas independientes que pueden fallar sin afectar a las demás. Esta página explica cómo se conectan los servicios, cómo fluye la data y qué pasa cuando algo se rompe.

Vista de alto nivel

Diagrama interactivo
Cargando diagrama…

Las tres capas

Edge Network — Cloudflare Workers corren en 300+ PoPs. Click wrapper, web pixel, S2S proxy y API gateway. Aquí se generan ULIDs, se setean cookies y se hace rate limiting.

Processing Engine — Servidor dedicado en Hetzner con el servicio Go (6,684 líneas, 16 paquetes), ClickHouse y DragonflyDB. Atribución, scoring de fraude, resolución de identidad y escritura batch.

Platform & Activation — Supabase para config/pagos/agregados, R2 como data lake/WAL/backups, y DSP para reenvío de eventos a Meta, Google y TikTok.


Componentes principales

Click Wrapper

t.relo.mx — genera ULID, deja cookie first-party y responde 302 en <50 ms P99.

Web Pixel

p.relo.mx — loader JS de 143 líneas. Usa Beacon API + device fingerprinting.

S2S Proxy

s2s.relo.mx — verificación HMAC, terminación TLS 1.3, protección DDoS.

API Gateway

relo-api — 250+ endpoints, JWT auth, CORS y rate limiting.

Go Ingest

Servicio Go en Hetzner: fasthttp, batch writer, identity resolution, fraud scoring.

ClickHouse

Motor analítico columnar. Schema de 35 campos, 8.6x compresión, TTL 24 meses.

DragonflyDB

Grafo de identidad, cache de fraude y contadores en tiempo real. Sub-ms lookups.

Supabase

50+ tablas: config, partners, pagos, agregados. Tamaño constante por siempre.

Cloudflare R2

Data lake, archivo CSV y backups. 11 nueves de durabilidad, zero egress fees.

DSP Activation

Meta CAPI, Google Ads y TikTok API. Reenvío de eventos de compra en tiempo real.


Ciclo de vida de un evento

Diagrama interactivo
Cargando diagrama…
PasoQué pasaAlmacenamientoLatencia
1. Llega el eventoClick, beacon o postback al edge workerMemoria edge<5 ms
2. Procesamiento edgeULID, cookies, headers geo<10 ms
3. R2 WALEscrito como NDJSON gzip antes de procesarR2<20 ms
4. Ingesta GoHMAC, GeoIP, identidad, fraude<5 ms
5. Escritura batchBuffer, flush cada 1k eventos o 1sClickHouse<1 s
6. Escritura dualCompras también a SupabaseSupabase<100 ms
7. Actualización de identidadPerfil de dispositivo + cross-deviceDragonflyDB<1 ms
8. AgregaciónMVs cada 5 min, sync a Supabase cada 10 minSupabase5-10 min
9. Recuperación DLQRevisa eventos fallidos cada 60sR2 DLQ60 s
10. Exportación DSPCompras a Meta CAPIMeta<5 s

Cómo entra cada fuente

  1. User hace click en t.relo.mx/... 2. Cloudflare Worker genera ULID y cookie first-party. 3. 302 redirect al destino final (ej. ad.admitad.com/...). 4. Evento de click se envía al Go service y se escribe en ClickHouse.

Failover por fuente

Click wrapper — 3 niveles

Diagrama interactivo
Cargando diagrama…

Web pixel — 3 niveles

Diagrama interactivo
Cargando diagrama…

S2S postbacks — 3 niveles

Diagrama interactivo
Cargando diagrama…

Disaster recovery

🔥 Servidor destruido

Edge detecta health check failure → fallback a KV/R2 → levanta nuevo servidor desde backup diario → replay de standby + DLQ. RTO: 2-4h. Cero pérdida.

🔌 Cloudflare caído

No llegan clicks/pixels/API. Go sigue vivo. AppsFlyer Pull continúa directo a Hetzner. Al recuperarse CF, los encolados se procesan. Cero pérdida.

💣 Supabase caído

Dashboard y portal pausados. ClickHouse y DragonflyDB siguen recibiendo todo. Al recuperarse, aggregator sincroniza ventana de 7 días. Cero pérdida.

⚡ Go service crashea

Systemd reinicia en <5 s. Durante el reinicio, clicks → KV → R2 DLQ, pixels → R2 DLQ. Al arrancar, recupera todo. RTO: <10 s. Cero pérdida.

💾 Disco ClickHouse

RAID-1 continúa con el disco sobreviviente. Se reemplaza el disco fallido y RAID se reconstruye. Cero pérdida, cero downtime.

🔐 DragonflyDB caído

Systemd reinicia. Grafo de identidad se reconstruye desde ClickHouse (~30 min para 90 días). Eventos siguen fluyendo. Degradación temporal, cero pérdida.


Backups y monitoreo

FrecuenciaQué hace
Cada 60sHealth check + auto-remediación (4 probes: CH, DF, R2, Supabase)
Cada 10 minAggregator sync a partner_daily_aggregates
Cada horaAppsFlyer Pull (backup externo independiente, 90 días de retención)
Diario 4
AM
Backup incremental ClickHouse a R2
Semanal (domingo)Backup completo ClickHouse a R2

Verificación real de backups

$ crontab -l
# Health check corre dentro del servicio Go cada 60s
0 4 * * *   /opt/relo-ingest/backup-clickhouse.sh --daily
0 4 * * 0   /opt/relo-ingest/backup-clickhouse.sh --full

$ tail -5 /var/log/ch-backup.log
[2026-03-12 04:00:01] Starting daily backup...
[2026-03-12 04:00:02] Exported events (last 7d): 1,247 rows
[2026-03-12 04:00:02] Exported partner_daily_aggregates: 892 rows
[2026-03-12 04:00:03] Uploading to R2: relo-backups/daily/2026-03-12/
[2026-03-12 04:00:04] ✓ Backup complete. Size: 17.6KB

Autenticación: 4 capas fail-closed

HMAC-SHA256 — S2S postbacks de AppsFlyer verificados contra X-AF-Signature. Si no hay secret configurado, todo rechazado con 503.

Bearer Token — endpoints admin protegidos con Authorization: Bearer <token>. Token vacío = todo rechazado.

JWT + RBAC — Supabase Auth con roles admin, client_manager, partner, viewer. Partners nunca ven revenue, solo su comisión.

Row-Level Security (RLS) — aislamiento a nivel de fila en PostgreSQL. Incluso con bugs en la app, la DB rechaza acceso no autorizado.


Detección de fraude

Motor de scoring con 5 señales, evaluado en ~2 µs con XGBoost compilado:

SeñalQué detecta
CTITClick-to-Install Time. Click injection y click flooding.
Geo mismatchVPN fraud: clicks de un país, installs de otro.
Device fingerprintEmuladores, granjas de dispositivos, IDs spoofeados.
Velocity checksRafagas anormales de clicks/installs por dispositivo/hora.
ML EnsembleXGBoost entrenado con datos históricos. Score 0-255.
Diagrama interactivo
Cargando diagrama…

Mejoras de alta disponibilidad (marzo 2026)

  • Systemd watchdogType=notify con WatchdogSec=120. Mata y reinicia si el proceso se cuelga.
  • External health monitor — Cloudflare Worker cron hace ping a /health cada hora, independiente del proceso Go.
  • WAL integrity verificationGET /wal/verify muestrea archivos R2, descomprime y valida JSON.
  • DLQ depth monitoring/health expone profundidad de DLQ para clicks, S2S y pixel.
  • Supabase PITR + daily backups — recuperación a cualquier segundo dentro de la ventana de retención.
  • DR drillsdrp-test.sh valida WAL + DLQ en pruebas automatizadas.

Checklist de arquitectura sana

  • Health check de Go responde OK en /health
  • DLQ depth en cero para clicks, S2S y pixel
  • ClickHouse RAID-1 sin degradación
  • DragonflyDB responde a PING y test RW
  • Último backup diario en R2 se completó sin errores
  • AppsFlyer Pull de la última hora trajo eventos
  • Supabase aggregate sync lag < 30 min
  • External CF Worker cron recibió heartbeat

On this page