14 Min. LesezeitEngineering
Eckpfeiler

p95 < 15 ms für Redirects aus FRA, ASH und SGP erreichen

Wie der Edge-Redirect-Pfad von Elido bei Cache HIT in drei Regionen ein p95-Budget von 15 ms hält - Architektur, Cache-Strategie, Messungen aus realen Regionen

Marius Voß
DevRel · edge infra
World map showing Elido edge POPs in Frankfurt, Ashburn, and Singapore with p95 latency annotations of 12ms, 13ms, and 14ms respectively

Ein Redirect ist ein synchroner Block. Der Nutzer klickt Ihren Short-Link, sein Browser stockt, und nichts anderes passiert, bis der 302 ankommt und der nächste Seitenaufruf beginnen kann. Der Redirect ist keine Hintergrundaufgabe, die Sie de-priorisieren können. Jede Millisekunde, die Sie hier hinzufügen, ist eine Millisekunde, die der Seite abgezogen wird, auf die es eigentlich ankommt.

Deshalb haben wir ein hartes Budget gesetzt, bevor wir die erste Zeile von services/edge-redirect geschrieben haben: p50 5 ms, p95 15 ms bei einem Cache-Hit, gemessen am POP, ausgenommen voller TLS-Handshake. Nicht erstrebenswert - verbindlich. Wenn etwas uns über die Linie bringt, wird es entfernt oder in einen asynchronen Pfad verschoben.

Wir betreiben drei Produktionsregionen - Frankfurt (FRA), Ashburn (ASH) und Singapur (SGP) - seit mehreren Monaten. Dieser Beitrag ist ein vollständiger Bericht darüber, wie der Hot-Path funktioniert, warum die Zahlen so aussehen, wie sie aussehen, und was wir beim ersten Mal falsch gemacht haben.

TL;DR

  • Der Hot-Path ist Go + fasthttp auf Hetzner FRA/ASH und OVH SGP, hinter Caddy mit Anycast-Routing. Kein synchrones Bot-Scoring, keine JS-Challenge auf dem Redirect-Pfad.
  • Zwei-Tier-Cache: In-Process-ristretto-LRU (L1, ~88 % Trefferquote), unterlegt von Redis Cluster (L1+L2 kombiniert ~99,4 %). Origin-gRPC zu api-core nur bei Cold-Miss (~0,6 % der Anfragen).
  • 90-Tage-p95 nach Region: FRA 12,1 ms, ASH 13,4 ms, SGP 14,2 ms. Ein Cold-Miss fügt am p95 ~22 ms hinzu, immer noch im Budget.
  • Cache-Invalidierung bei Link-Mutation ist Redis pub/sub, Sub-Sekunden-Propagation p99. Die L1-TTL liegt als Sicherheitsnetz bei 60 Sekunden.

Warum eine 15-ms-Obergrenze

Bevor wir zur Architektur kommen: warum 15 ms und nicht 50 ms oder 5 ms?

Der 5-ms-Boden ist schnell erklärt - das ist etwa, was die physische Netzwerktransitzeit im Median für einen europäischen Besucher kostet, der auf einen Frankfurter POP trifft. Sie können die Physik nicht unterbieten. Die 50-ms-Obergrenze ist zu locker - bei 50 ms p95 fügen Sie einen wahrnehmbaren Stocker vor jedem Pageview für einen relevanten Anteil Ihres Traffics ein. Forschung zur Web-Performance zeigt konsistent, dass Netzwerkverzögerungen unter 50 ms wahrnehmbar werden auf mobilen Geräten, wo Funklatenz mit Verarbeitungszeit zusammenkommt - ein Punkt, den Apples Network-Aware-Programmierungs-Richtlinien explizit machen.

Die 15-ms-Zahl ergab sich aus ein paar konkreten Einschränkungen. Erstens: Redirects akkumulieren. Wenn eine Marketingkampagne Traffic über einen gekürzten Link schickt, der dann auf eine Produktseite umleitet, addiert sich die Redirect-Latenz zum TTFB der Landing Page. Googles Core Web Vitals verwenden LCP als primäres Signal, und eine Redirect-Kette, die bei p95 50 ms hinzufügt, ist messbar. Zweitens: Wir wollen genug Pufferbudget, um Regelauswertung für Smart-Links inline auf dem Hot-Path zu fahren - die Routing-Dimensionen (Land, Gerät, OS, Sprache, Zeit, Referrer) müssen innerhalb derselben Latenzhülle wie ein einfacher Redirect ausgeführt werden, sonst müssten wir Smart-Link-Unterstützung am Edge entfernen. Bei 15 ms mit ~0,3 ms Regelauswertung ist da Platz.

Das 15-ms-Budget gilt für Cache-Hit-Traffic. Cold-Misses dürfen langsamer sein - der Origin-gRPC-Call fügt Latenz hinzu - aber Cold-Misses sind per Design selten genug, dass sie das p95 nicht nennenswert bewegen.

Die Architektur

Drei POPs, jeder mit derselben Binary: services/edge-redirect, in Go geschrieben mit fasthttp. Der Server-Durchsatz von fasthttp ist im Benchmark-Suite ungefähr 8-fach gegenüber net/http und, für uns praktischer, der allokationsfreie Request-Pfad hält GC-Pausen unter Dauerlast vorhersagbar. Die net/http aus der Standardbibliothek ist für die meisten Dienste in Ordnung; für einen Redirect-Handler, der bei hoher Nebenläufigkeit Sub-Millisekunden-Verarbeitungszeit halten muss, ist die Vermeidung von Per-Request-Heap-Allokationen die weniger ergonomische API wert.

Caddy sitzt davor als TLS-Terminator und Reverse-Proxy. On-Demand-TLS für Tenant-Custom-Domains (detailliert beschrieben auf der Custom-Domains-Feature-Seite) stellt Zertifikate bei der ersten Anfrage bereit. Wir haben HAProxy und nginx als Alternativen evaluiert - beide sind schnell, beide haben ausgereifte Anycast-Deployment-Muster, aber Caddys On-Demand-TLS ist der sauberste Pfad zu einem touchless-Zertifikatslebenszyklus für eine beliebige Anzahl von Kundendomains, und das ist uns wichtiger, als eine weitere Bruchteil-Millisekunde auf der Proxy-Ebene herauszuquetschen.

Anycast-Routing bedeutet, dass wenn ein Besucher auf f.elido.me, s.elido.me oder b.elido.me trifft, das DNS auf ein gemeinsames Anycast-Präfix auflöst und das Netzwerk die TCP-Verbindung zum nächsten POP routet. Es gibt keine Geo-Routing-Logik auf Anwendungsebene: das Netzwerk wählt den POP. Cloudflares Anycast-Primer ist die klarste öffentliche Erklärung, warum das wichtig ist - die Schlüsseleigenschaft ist, dass Failover auf der BGP-Ebene gehandhabt wird, nicht durch DNS-TTL-Ablauf. Wenn FRA die Konnektivität verliert, wird ASH innerhalb von Sekunden zur kürzesten Route für europäischen Traffic, nicht in Minuten. Hetzners Cloud-Netzwerkinfrastruktur-Doku deckt das zugrundeliegende Routing-Setup für ihre FRA- und ASH-Regionen ab.

Wichtig: Es gibt kein synchrones Bot-Scoring auf dem Hot-Path. Eine Bot-Scoring-Prüfung, die 10 ms braucht, würde im Alleingang das p95-Budget zerstören. Alle Traffic-Qualitäts-Signale - Anonymisierer-Erkennung, Hosting-ASN-Scoring, Klick-Deduplizierung - laufen in url-scanner und click-ingester als Cold-Path-Asynchron-Worker. Der Redirect feuert, und der Klick geht auf die Redpanda-Queue; die Qualitäts-Bewertung passiert im Nachhinein.

Der Zwei-Tier-Cache

Der Cache ist der Ort, an dem das Budget lebt. Die Logik:

// Simplified cache lookup: L1 → L2 → origin, with singleflight dedup
func (h *RedirectHandler) resolve(ctx *fasthttp.RequestCtx, slug string) (*Link, error) {
    // L1: in-process ristretto LRU - sub-microsecond on hit
    if link, ok := h.l1.Get(slug); ok {
        return link.(*Link), nil
    }

    // L2 + origin share a singleflight group to prevent thundering herd
    // on concurrent cold misses for the same slug
    val, err, _ := h.sf.Do(slug, func() (interface{}, error) {
        // L2: Redis Cluster - single RTT, typically 0.3–0.8ms within POP
        if data, err := h.redis.Get(ctx, cacheKey(slug)).Bytes(); err == nil {
            link, err := unmarshalLink(data)
            if err == nil {
                h.l1.Set(slug, link, linkCost(link))
                return link, nil
            }
        }

        // Origin: gRPC to api-core - cold miss, ~20ms extra
        link, err := h.origin.GetLink(ctx, &pb.GetLinkRequest{Slug: slug})
        if err != nil {
            return nil, err
        }
        payload, _ := marshalLink(link)
        h.redis.Set(ctx, cacheKey(slug), payload, redisTTL)
        h.l1.Set(slug, link, linkCost(link))
        return link, nil
    })
    if err != nil {
        return nil, err
    }
    return val.(*Link), nil
}

L1 ist ristretto, der admission-controlled LRU-Cache von Dgraph. Der Admission-Controller ist wichtig: Ein naiver LRU unter einer Scan-Workload (ein Bot, der Tausende einzigartiger Slugs trifft) wird heiße Einträge evikten, um Platz für kalte zu schaffen, die nie wieder angefragt werden. Die TinyLFU-basierte Admission-Policy von ristretto widersteht dem - sie verfolgt Frequenz-Counter kosteneffizient und weigert sich, einen Eintrag zuzulassen, der noch nie gesehen wurde, wenn der Cache unter Druck steht. Der Nettoeffekt ist, dass die Cache-Trefferquote unter feindlichem Scan-Traffic nahe der organischen Trefferquote bleibt, statt zu kollabieren.

L2 ist Redis Cluster. Jeder POP hat seine eigene Cluster-Instanz, um regionsübergreifenden Traffic aus dem Hot-Path herauszuhalten. FRA und ASH teilen sich eine separate Redis-Instanz für pub/sub-Invalidierungs-Signale (mehr dazu unten); SGP hat seine eigene. Ein einzelner Redis-GET innerhalb desselben Rechenzentrums liegt zuverlässig unter 1 ms. Die kombinierte L1+L2-Trefferquote liegt über die letzten 90 Tage bei rund 99,4 % - Origin-Calls passieren also bei ungefähr 1 von 167 Anfragen.

Für den solutions/developers-Anwendungsfall - Teams, die die API nutzen, um Links in hohem Volumen zu erzeugen - ist die praktische Implikation, dass ein frisch erstellter Link einen Cold-Miss pro POP erfährt und dann für die Dauer seiner TTL warm ist. Links, die keinen Traffic sehen, laufen sauber aus beiden Caches ab, ohne manuelle Eviction.

Wohin die 15 ms gehen

Das Diagramm unten schlüsselt das p95-Cache-Hit-Budget nach Phase auf:

Horizontal stacked bar showing the 15ms p95 cache-hit budget decomposed into TLS resume 2ms, L1 lookup 0.4ms, header build 1ms, network return 9ms, and margin 2.6ms. Illustrative FRA median values.

Das dominante Segment ist der Netzwerk-Rückweg - rund 9 ms im Median, was bedeutet, dass die physische Distanz zwischen Besucher und POP 60 % des Budgets ausmacht. Das können wir nicht komprimieren. Mehrregionen-Deployment ist der einzige Hebel: Ein zusätzlicher POP verringert das mittlere RTT für Besucher in dieser Region. Die nächste Region auf der Roadmap verringert das SGP-p95 für südasiatischen Traffic, wo wir derzeit 14 ms routen, weil Singapur der nächste POP ist.

TLS-Sitzungswiederaufnahme bei 2 ms setzt TLS 1.3 0-RTT mit einem bereits vorhandenen Session-Ticket voraus. Für einen Erstbesuch von einem bestimmten Gerät aus fügt ein voller TLS-Handshake rund 10-15 ms obendrauf - deshalb umfasst das 15-ms-Budget explizit Cache-Hit + Resumed-Session-Traffic, was in der Praxis die überwiegende Mehrheit des Klick-Traffics ist. RFC 7234 regelt die Caching-Semantik für die HTTP-Ebene; insbesondere werden 302-Antworten standardmäßig nicht vom Browser-Cache gespeichert (§4.2.2), was für unseren Anwendungsfall das richtige Verhalten ist - jede Redirect-Anfrage erreicht den Edge, jeder Redirect erhält seine eigene Routing-Entscheidung, kein veraltetes Ziel im Browser-Cache.

Die 2,6 ms Marge sind echter operativer Spielraum, keine Polsterung. Unter Gos GC sind gelegentliche Stop-the-World-Pausen in der Größenordnung von 0,5-1 ms auch mit getunten GOGC-Einstellungen zu erwarten. Caddys Proxy-Overhead fügt einen kleinen Fixaufwand hinzu. Die Marge hält uns davon ab, das Budget zu reißen, wenn sich diese Effekte aufaddieren.

Cache-Invalidierung

Redis pub/sub ist der Mechanismus. Wenn ein Link in api-core mutiert wird - Ziel geändert, Targeting-Regeln aktualisiert, Link archiviert - veröffentlicht der Mutations-Handler auf einem Kanal link:invalidate mit dem Slug als Payload. Jeder Edge-POP abonniert diesen Kanal. Beim Empfang ruft der Subscriber l1.Del(slug) und redis.Del(cacheKey(slug)) auf. Die nächste Anfrage zu diesem Slug repopuliert beide Tier-Ebenen aus dem Origin. Dieses Verhalten, bei dem nach jeder Änderung neu vom Origin aufgelöst wird, ist genau der Grund, warum ein bearbeitbarer Kurzlink eine temporäre Weiterleitung statt einer gecachten permanenten nutzen sollte - ein Kompromiss, den wir in 301 vs. 302 Weiterleitungen genauer beleuchten.

Die 60-Sekunden-L1-TTL ist das Backup, nicht der primäre Mechanismus. Wenn der pub/sub-Subscriber unten ist - sagen wir, ein Redis-Aussetzer oder eine Netzwerkpartition zwischen POP und pub/sub-Instanz - läuft der Eintrag innerhalb von maximal 60 Sekunden aus dem L1 ab. Die L2-TTL ist auf 300 Sekunden gesetzt, sodass ein Subscriber-Ausfall bis zu 5 Minuten potenziell veralteter L2-Daten bedeutet, während dieser Zeit ist die L1-TTL das einzige Sicherheitsnetz. Wir alarmieren auf pub/sub-Abonnementverlust innerhalb von 30 Sekunden.

Für Smart-Links mit zeitfensterbasierten Regeln hat Veraltung eine spezifische Implikation: Wenn eine Regel um 17:00 aktiviert wird und der L1 des Edge-POP die vorherige Regelversion mit bis zu 60 Sekunden verbleibender TTL gecacht hat, kann Traffic zwischen 17:00 und 17:01 zum Pre-Update-Ziel gehen. Der pub/sub-Pfad eliminiert dies für den häufigen Fall; die 60-Sekunden-TTL fängt den Edge-Case ab. Für Kampagnen, bei denen die Zeitgrenze präzise zählt, lautet das empfohlene Muster: Verwenden Sie status=disabled auf der alten Regel, warten Sie einen TTL-Zyklus (60 Sekunden) und aktivieren Sie dann die neue. Wir haben einen Polling-Endpunkt unter GET /v1/links/{id}/cache-status hinzugefügt, sodass Pipelines die Propagation bestätigen können, bevor sie fortfahren.

Messungen aus realen Regionen

Die folgenden Zahlen stammen aus Demo-Workspace-Daten, die über 90 Tage bis zum 2026-05-12 gesammelt wurden. Sie spiegeln nur Cache-Hit-Traffic wider. Alle Zeitstempel sind UTC.

RegionPOPp50p95p99
EU (Frankfurt)FRA · Hetzner4,8 ms12,1 ms18,4 ms
US East (Ashburn)ASH · Hetzner5,2 ms13,4 ms20,1 ms
SE Asia (Singapur)SGP · OVH5,6 ms14,2 ms22,8 ms

FRA ist am schnellsten, weil der Großteil der Workload europäisch ist, sodass das mediane RTT niedriger ist. SGP bedient eine breitere geografische Streuung - südostasiatischer Traffic hat ein niedrigeres RTT, während südasiatischer und ostasiatischer Traffic zum Tail beitragen.

Die p99-Zahlen überschreiten das 15-ms-Budget. Das ist Absicht. Das p95 ist das Budget, nicht das p99. Das p99 wird von Ausreißerbedingungen geprägt: zellulare Handoffs, TCP-Retransmissions, der gelegentliche Redis-Latenzausschlag. Wir überwachen das p99, aber wir SLA-en nicht dagegen. Die Engineering-Entscheidung ist, dass p95 die Erfahrung "fast jeder fast immer" einfängt und das Optimieren des letzten 1 % das Eliminieren natürlicher Netzwerkvariabilität erfordern würde, die nicht unter unserer Kontrolle steht.

Das Cold-Miss-p95 liegt bei ungefähr 22 ms. Das ist die Untergrenze, die wir erreichen können, gegeben dass der Origin-gRPC einen Round-Trip im selben Rechenzentrum hinzufügt (FRA → FRA über das private Netz sind etwa 0,3 ms) plus die api-core-Postgres-Abfrage (typischerweise 1-3 ms für eine schlüsselbasierte Slug-Abfrage). Die 22-ms-Zahl ist gemessen, nicht geschätzt; sie liegt innerhalb des Budgets, das wir für Cold-Miss-Pfade erlauben - das ist auf p95 35 ms gesetzt.

Für Teams, die multi-region analytics evaluieren, sind diese Latenzzahlen als Prometheus-Metrik (redirect_duration_seconds mit region- und cache_tier-Labels) vom Metrik-Endpunkt verfügbar.

Failure-Modes, über die wir beim ersten Mal nicht gebloggt haben

Thundering Herd bei Schlüsselablauf

Bevor wir Singleflight hinzugefügt haben, würde ein Slug, der gleichzeitig aus L1 und L2 unter moderater Last abläuft, einen Schwall paralleler Origin-gRPC-Calls erzeugen - jeder einen Postgres-Read für denselben Slug machend, alle dasselbe Ergebnis zurückgebend. Unter Lasttests erzeugte das Spitzen in api-core-CPU, die nichts mit Linkerstellungsvolumen zu tun hatten. Die Singleflight-Gruppe faltet gleichzeitige Misses für denselben Slug in einen einzigen Origin-Call. Die anderen wartenden Goroutinen blockieren auf der Gruppe und erhalten dasselbe Ergebnis, wenn es aufgelöst wird. Die Implementierung ist das Standard-Go-Paket golang.org/x/sync/singleflight.

Wir haben das im ersten Prototyp falsch gemacht. Eine Thundering Herd unter Schlüsselablauf ist einer dieser Failure-Modes, der in Unit-Tests nicht auftaucht - er zeigt sich nur unter realistischer Nebenläufigkeit. Ich füge das zu diesem Beitrag hinzu, weil es eine häufige Auslassung in Cache-Architektur-Writeups ist und der Fix wirklich einfach ist.

Redis-Aussetzer-Fallback

Wenn ein POP die Konnektivität zu seinem Redis-Cluster verliert, ist der Fallback kein Fehler - der Codepfad degradiert auf L1-only plus direktes Origin-gRPC bei L1-Miss. Der POP bedient weiter. Die Trefferquote sinkt, weil L2 nicht verfügbar ist, sodass das Origin-Call-Volumen ansteigt, aber der Redirect-Pfad bleibt funktional. Der Redis-Aussetzer-Pfad wurde in der Produktion zweimal durchexerziert (beides waren Hetzner-Wartungsfenster). Die Origin-Call-Spitze während des zweiten Vorfalls war etwa 8-fach Baseline für die Dauer des Aussetzers (~4 Minuten). api-core hat das ohne Scaling-Events gehandhabt.

DNS-Propagation während POP-Failover

Anycast-Failover ist BGP-Layer - keine DNS-TTL zum Auswarten, kein Anwendungsschicht-Health-Check-Timeout im Request-Pfad. Ein POP, der offline geht, löst BGP-Widerruf der Route aus, und Netzwerk-Traffic verschiebt sich zum nächstgelegenen POP innerhalb des BGP-Konvergenzfensters (typischerweise 15-90 Sekunden, abhängig von der Anzahl der Netzwerk-Hops zum betroffenen Pfad). Der relevante Betriebsparameter ist unser Health-Check-Intervall: wir fahren TCP-Health-Checks alle 10 Sekunden pro POP. Ein Prüfungsausfall löst den Widerruf aus. Ein 10-Sekunden-Check-Intervall bedeutet, dass ein abgestürzter POP bis zu 10 Sekunden fehlgeschlagenen Traffic bedienen kann, bevor er zurückgezogen wird. Wir haben diese Grenze bewusst getestet; die tatsächliche Auswirkung in den beiden Produktionsvorfällen lag unter dem Check-Intervall.

Was wir auf dem Hot-Path nicht tun

Jedes Element, das nicht auf dem Hot-Path ist, ist eine bewusste Entscheidung, keine Auslassung.

Synchrone Klick-Writes. Klicks sind Fire-and-Forget zu Redpanda. Der Redirect-Handler hängt ein Click-Event an ein Kafka-Topic (clicks.raw) mit Slug, Zeitstempel, gekürzter IP und User-Agent-Hash und antwortet dann mit dem 302. Der Write ist nicht-blockierend. Wenn Redpanda nicht verfügbar ist, wird der Klick verworfen - nicht der Redirect. Wir haben den bewussten Trade gemacht, dass Klickverlust unter Infrastrukturausfall akzeptabel ist und Redirect-Ausfall nicht. Der click-ingester-Consumer verarbeitet das Redpanda-Topic und schreibt in ClickHouse. Deshalb sind die analytics-Daten für ein bestimmtes Click-Event mit kurzer Verzögerung verfügbar (typischerweise unter 5 Sekunden), nicht sofort.

Inline-Bot-Challenges. Eine Bot-Challenge fügt mindestens 10-50 ms synchrone Arbeit hinzu - JavaScript-Challenges fügen einen vollen Round-Trip hinzu. Wir tun keines davon auf dem Redirect-Pfad. Der url-scanner-Service verarbeitet Traffic-Qualitäts-Signale asynchron. Für solutions/developers-Teams, die Link-Kampagnen bauen, bedeutet das, dass der Redirect nie hinter einer Challenge versperrt ist, die das Erlebnis für legitimen Traffic verschlechtert.

Schema-Validierung zum Redirect-Zeitpunkt. Die Ziel-URL und die Targeting-Regeln werden zum Write-Zeitpunkt validiert, wenn der Link über api-core erstellt oder aktualisiert wird. Bis ein Slug im Cache landet, ist seine Struktur als gültig bekannt. Es gibt keine JSON-Schema-Validierung, keinen URL-Parse-Schritt, keine Regel-Syntax-Prüfung zum Redirect-Zeitpunkt. Die Edge-Binary vertraut dem Cache-Eintrag vollständig. Das ist nur sicher, weil der Write-Pfad vor der Aufnahme in den Cache validiert.

Die unsexy Teile

Drei Dinge, über die wir nicht genug schreiben, weil sie langweilig zu lesen und wichtig zu richtig zu machen sind.

Cache-Größenbudgets. ristretto wird mit einem expliziten Kostenbudget in Bytes initialisiert, nicht mit einer einfachen Element-Zahl. Jeder gecachte Link wird nach seiner serialisierten Größe bemessen, die mit der Anzahl der Targeting-Regeln variiert. Ein Link ohne Regeln kostet ungefähr 200 Bytes; ein Link mit 6 Targeting-Regeln kostet eher 800 Bytes. Das Budget ist so gesetzt, dass es höchstens 10 % des verfügbaren RAMs der Instanz konsumiert, mit Spielraum für die Go-Runtime, Caddy und Connection-Buffer. Das hier falsch zu machen, verursacht Cache-Thrashing: ein zu kleines Budget evikt Einträge, bevor die TTL abläuft, und drückt Traffic Richtung L2 und Origin.

GC-Tuning unter Last. Gos Garbage Collector ist standardmäßig gut getunt, aber das Default-GOGC=100 triggert GC bei doppelter Live-Heap-Größe. Für einen Redirect-Handler, dessen Live-Heap klein ist, dessen Allokationsrate aber moderat ist (fasthttp ist auf dem Hot-Path zero-alloc, aber es gibt Objektallokationen für Click-Events und gRPC-Calls), feuert der GC häufiger als nötig. Wir fahren in der Produktion GOGC=400. Der Effekt sind längere GC-Zyklen, aber niedrigere Frequenz - was für die Tail-Latenz zählt. Ein GC-Zyklus, der 2 ms braucht und alle 4 Sekunden passiert, trägt weniger zum p99 bei als ein 1-ms-Zyklus jede Sekunde. Wir haben das empirisch mit make bench verifiziert, bevor wir es in der Deployment-Config gesetzt haben.

Die make bench-Disziplin. Die Edge-Binary hat eine Benchmark-Suite (go test -bench=. -benchmem ./... aus services/edge-redirect heraus). Jede vorgeschlagene Änderung am Hot-Path - Hinzufügen eines neuen Headers, Änderung des Cache-Key-Formats, Anpassen des Regelauswerters - durchläuft die Benchmarks vor dem Merge. Eine Änderung, die 0,5 ms zum p50-Benchmark hinzufügt, ist eine Änderung, die das p95 in der Produktion bewegt. Der Benchmark ist das Gate, nicht eine nachträgliche Prüfung. Wir sind hier einmal nachlässig geworden, in einem Refactor, der die Slug-Normalisierungslogik änderte, und haben eine 1,2-ms-Regression ausgeliefert, die zwei Tage später in den Region-Dashboards auftauchte. Die Regression war real, und die Lektion saß.


Die Architekturentscheidungen hier sind ausführlicher unter /docs/architecture/edge-redirect dokumentiert. Wenn Sie Elido als Redirect-Infrastrukturschicht für eine Kampagne mit hohem Volumen oder eine Entwicklerplattform evaluieren, deckt die solutions/developers-Seite die API-Oberfläche und SDK-Optionen ab. Für einen Blick darauf, was der Zwei-Tier-Cache für das Smart-Link-Verhalten impliziert - insbesondere das Propagationsfenster für Regeländerungen - behandelt der smart-links-explained-Beitrag das in der Tiefe. Und falls Sie lieber Ihre eigene Redirect-Schicht bauen möchten, statt unsere zu evaluieren, deckt Wie man einen URL-Kürzer erstellt die Architektur von Grund auf ab.


Marius Voß ist DevRel und Edge-Infra bei Elido. Er war einer der Engineers, der die edge-redirect-Binary vom Prototyp zur Produktion gebracht hat und starrt seitdem auf ihre Latenz-Dashboards.

Elido testen

URL einfügen, kurzer Link in Sekunden

Kein Konto nötig. Link bleibt 30 Tage aktiv. Konto erstellen, um ihn dauerhaft zu behalten.

Kostenlos, keine Anmeldung erforderlich · 2 pro Tag

Elido testen

URL-Shortener mit EU-Hosting: eigene Domains, tiefe Analytik und eine offene API. Kostenloser Tarif - keine Kreditkarte nötig.

Tags
url shortener performance
edge redirect latency
multi-region url shortener
redirect cache strategy
fasthttp
anycast routing

Weiterlesen