Wie wir die Performance von Moove um 59 % verbessert haben
Die meisten Moove-Nutzer sind weit von unseren Servern entfernt. So senkten wir die Zeit bis zur ersten Antwort um 59 %, ohne einen Server zu verlegen.
Die Entfernung war unsere langsamste Abhängigkeit
Die meisten Menschen, die die Moove app öffnen, nutzen Mobilfunknetze in Nigeria und Indonesien, Tausende Kilometer von den Servern entfernt, die ihre Anfragen beantworten. In diesem Monat haben wir geändert, wie ihre Anfragen bei uns ankommen, und unsere Zeit bis zum ersten Byte (TTFB), also die Zeitspanne zwischen dem Absenden einer Anfrage durch ein Smartphone und dem Eintreffen des ersten Teils der Antwort, sank um 59 %, von 0,74 Sekunden auf 0,31 Sekunden. Dafür mussten wir keinen einzigen Server verlegen.
Dieser Beitrag erklärt, warum uns die Entfernung mehr kostete, als wir erwartet hatten, was wir geändert haben, welcher Teil sich als schwieriger erwies als die Änderung selbst und was wir einem anderen Team raten würden, das dasselbe vorhat.
Warum aus einer langen Strecke drei werden
Die Verzögerung zwischen dem Senden und dem Ankommen von Daten nennen Ingenieure Latenz, die Zeit, die eine Nachricht bis zu einem Server und die Antwort zurück braucht, Umlaufzeit (RTT). Von Lagos zu unseren Servern liegt die RTT zwischen 200 und 300 Millisekunden. Für sich genommen ist das erträglich. Das Problem ist, dass eine Anfrage selten allein unterwegs ist.
Bevor ein Smartphone über eine gesicherte Verbindung etwas anfragen kann, muss es zwei Handshakes abschließen, kurze Austausche, die eine Verbindung aufbauen. Der TCP-Handshake öffnet die Verbindung, und der TLS-Handshake vereinbart anschließend die Schlüssel, die sie verschlüsseln und privat halten. Jeder von beiden kostet einen vollen Hin- und Rückweg. Erst dann geht die eigentliche Anfrage hinaus, das ist der dritte Weg. Bei 250 Millisekunden pro Weg wartet ein Nutzer rund eine Dreiviertelsekunde, bevor unsere Server überhaupt etwas getan haben.
In Mobilfunknetzen fällt dieser Aufwand viel öfter an, als man hoffen würde. Smartphones wechseln zwischen Funkmasten, Funkmodule gehen zum Stromsparen in den Ruhezustand, und Apps werden in den Hintergrund geschickt. Jedes dieser Ereignisse kann die Verbindung kappen, und die nächste Anfrage muss mit einer kalten Verbindung beginnen, bei der noch kein Handshake erfolgt ist, und die volle Aufbauzeit erneut bezahlen. Eine warme Verbindung, die bereits offen und gesichert ist, springt direkt zur Anfrage.
Wir konnten Lagos nicht näher an unsere Server rücken. Wir konnten aber den Verbindungsaufbau näher an Lagos rücken.
Den Handshake verlagern, nicht die Server
Ein Content Delivery Network (CDN) wird meist als Cache beschrieben: ein Netz von Standorten weltweit, die Kopien von Dateien vorhalten, damit sie aus der Nähe ausgeliefert werden können. Wir haben eines aus einem anderen Grund eingesetzt. Für unsere API, die Schnittstelle, über die die App alles erledigt, was sie tut, ist das Caching vollständig abgeschaltet. Jede Anfrage läuft weiterhin bis zu unserem Origin, so nennt das CDN die dahinterliegenden Server.
Geändert hat sich, wo die Verbindung beginnt. Ein Smartphone baut seine Verbindung jetzt zum nächstgelegenen Edge-Standort auf, auch Point of Presence (PoP) genannt: einer der Standorte des CDN rund um die Welt, oft nur Dutzende statt Hunderte Millisekunden entfernt. Der Edge führt die TLS-Terminierung durch, das heißt, die gesicherte Verbindung vom Smartphone endet dort. Anschließend nutzt er einen Pool warmer Verbindungen zu unserem Origin, die per keep-alive offen gehalten werden, einer Einstellung, die eine Verbindung zwischen Anfragen offen lässt, statt sie zu schließen. Die zwei teuren Aufbauwege werden über die kurze Strecke erledigt, und nur die Anfrage selbst überquert den Ozean, auf einer bereits warmen Verbindung.
Aus drei langen Wegen wird ein langer Weg und zwei kurze. Das ist die ganze Idee.
Den Rest haben wir bewusst unspektakulär gehalten:
- Clients haben nichts bemerkt. Die App und die Website behielten dieselben Adressen, deshalb war kein App-Release nötig, und niemand musste etwas aktualisieren.
- Das Fehlerverhalten blieb gleich. Die Timeouts entsprechen dem, was vorher galt, sodass alles, was vorher fehlschlug, genauso fehlschlägt. Wir wollten keine neuen Arten von Fehlern.
- Der Edge schließt ruhende Verbindungen zuerst. Jede Verbindung hat ein Leerlauf-Timeout, also die Zeit, die sie ungenutzt bleiben darf, bevor sie geschlossen wird. Würden unsere Server eine ruhige Verbindung schließen, während der Edge sie noch für offen hält, würde die nächste Anfrage scheitern. Ein kürzeres Timeout am Edge stellt sicher, dass er immer zuerst aufgibt und stattdessen eine neue Verbindung öffnet.
- Neuere Protokolle für Smartphones. Smartphones können sich über HTTP/3 verbinden, die neueste Version des Anfrageprotokolls des Webs. Es läuft auf QUIC, das beide Handshakes in einem einzigen Hin- und Rückweg zusammenfasst und mit dem in Mobilfunknetzen häufigen Paketverlust besser zurechtkommt.
- Keine Region ausgelassen. Günstigere Tarife eines Edge-Netzwerks lassen oft ausgerechnet in den Teilen der Welt Standorte aus, in denen unsere Nutzer leben, deshalb haben wir die volle Abdeckung gewählt.
Was wir gemessen haben
Wir haben von Sydney aus gemessen, das ungefähr so weit von unseren Servern entfernt ist wie Lagos, und den alten Weg mit dem neuen verglichen. Für jeden haben wir fünf frische kalte Verbindungen geöffnet, den Fall, der in Mobilfunknetzen am meisten zählt, und den Median genommen, auch p50 genannt: das mittlere Ergebnis, das die Hälfte der Anfragen unterbietet und die andere Hälfte nicht. Im selben Projekt haben wir außerdem die Kompression für die Skripte unserer Website eingeschaltet, die bis dahin in voller Größe gesendet wurden. Die Kompression verkleinert eine Datei vor dem Senden, und der Browser entpackt sie bei der Ankunft wieder; wir haben Brotli verwendet, ein für das Web entwickeltes Kompressionsformat.
| Was wir gemessen haben | Vorher | Nachher | Verbesserung |
|---|---|---|---|
| TCP- und TLS-Handshakes abgeschlossen (p50) | 490 ms | 59 ms | 88 % schneller |
| Zeit bis zum ersten Byte (p50) | 743 ms | 307 ms | 59 % schneller |
| Skript-Payload der Startseite | 1,76 MB | 560 KB | 68 % kleiner |
Aus der Zeit bis zum ersten Byte stammen die 59 %. Eine Verbindung, die früher eine halbe Sekunde zum Aufbau brauchte, ist jetzt in weniger als einem Zehntel davon bereit, und ein Erstbesuch auf unserer Website lädt jetzt zwei Drittel weniger herunter, auf Verbindungen, bei denen viele Menschen für jedes Megabyte zahlen.
Diese Zahlen stammen aus einer einzigen Stadt und sind kein globaler Benchmark. Die Rechnung lässt sich aber auf Lagos und Jakarta übertragen, und dort sind unsere Nutzer.
Der schwierige Teil war zu wissen, wer anfragt
Etwas vor die eigenen Server zu schalten ist einfach. Die Schutzmaßnahmen dahinter funktionsfähig zu halten, war der Teil, der die meiste Arbeit gekostet hat.
Wie die meisten Zahlungsplattformen nutzt Moove Ratenbegrenzung (Rate Limiting), eine Obergrenze dafür, wie viele Anfragen ein einzelner Aufrufer in einer bestimmten Zeit stellen darf, und diese Grenzen beziehen sich auf die IP-Adresse des Aufrufers, die Nummer, die ein Gerät im Internet identifiziert. Hinter einem Edge-Netzwerk kommt jede Anfrage stattdessen von der Adresse eines Edge-Standorts, nicht von der des Nutzers. Hätte sich sonst nichts geändert, hätten sich alle in Lagos ein einziges Kontingent geteilt, und ein einziger geschäftiger Nachmittag hätte begonnen, Menschen abzuweisen, die nichts falsch gemacht hatten.
Die Lösung beruht auf zwei Ideen.
Genau den Schichten vertrauen, die man hat. Ein CDN ist eine Art Reverse-Proxy, ein Server, der vor deinem steht und Anfragen weiterreicht. Jeder Proxy trägt die Adresse, von der er eine Anfrage erhalten hat, in einen Standard-Header namens X-Forwarded-For ein, sodass der tatsächliche Aufrufer eine feste Anzahl von Schritten, auch Hops genannt, weiter hinten in dieser Liste steht. Diese Zahl falsch anzusetzen ist in beide Richtungen ein Fehler. Zählt man zu wenige Schichten, sieht jeder Nutzer aus wie sein Edge-Standort. Zählt man zu viele, vertraut man plötzlich einem Eintrag, den der Aufrufer selbst geschrieben hat. Deshalb haben wir die Zahl zu einer Eigenschaft der Infrastruktur gemacht statt des Codes. Sie ändert sich im selben Moment wie das Netzwerk, und unser Dienst weigert sich zu starten, wenn der Wert keinen Sinn ergibt, statt zu raten.
Den Edge für den Aufrufer bürgen lassen und nur dem Edge glauben. Der Edge schreibt jetzt die echte Adresse des Aufrufers in jede Anfrage und überschreibt damit alles, was der Aufrufer stattdessen mitgeschickt hat. Unsere Schutzmaßnahmen glauben diesem Wert nur, wenn sie prüfen können, dass die Anfrage wirklich über unseren Edge kam. Jede Grenze, die früher auf die Netzwerkadresse bezogen war, bezieht sich bei Edge-Traffic jetzt auf den echten Aufrufer. Wir haben diese Regeln neben den alten ergänzt, statt sie zu ändern, sodass jeder Schritt des Rollouts eine reine Ergänzung war, die jeder in einem Durchgang prüfen konnte.
Ein Fehler, den wir vor der Auslieferung gefunden haben
Moove Profiles können auf der eigenen Domain eines Händlers liegen. Anfragen für diese Domains wurden mit angehängter Händlerdomain über unsere Website weitergereicht, damit die Seite wusste, welches Profil sie anzeigen soll.
Der neue Edge vor der Website entfernt solche Informationen aus eingehenden Anfragen, und das ist genau richtig so, denn ein Besucher darf sie niemals selbst setzen. Es bedeutete aber auch: Sobald die Website hinter dem Edge lag, hätte jede Händlerdomain stillschweigend die Moove-Startseite statt des Händlerprofils angezeigt.
Wir haben das im Review bemerkt, den Pfad für Händlerdomains zuerst auf eine eigene Route verlegt und unsere Infrastruktur so eingerichtet, dass sie die Änderung an der Website überall verweigert, wo diese Verlegung nicht stattgefunden hatte. Ein Fehler, der früher nur im Kopf eines Reviewers lebte, wird heute vom Build gestoppt.
Die allgemeine Lehre: Wenn du eine Schicht hinzufügst, die Eingaben bereinigt, suche nach allem, was von den Eingaben abhing, die du gleich bereinigst.
So haben wir ausgerollt
Bei Zahlungsinfrastruktur gilt nicht „ausliefern und abwarten“, deshalb haben wir zuerst Staging und danach Produktion umgestellt, und ein paar Entscheidungen hielten die Umstellung ereignislos. Wir haben die TTL (Time to Live) unserer DNS-Einträge gesenkt, des Verzeichnisses des Internets, das einen Namen wie moove.xyz in eine Serveradresse übersetzt. Die TTL gibt an, wie lange der Rest des Internets diese Antwort zwischenspeichern darf, und wir haben sie von einer Stunde auf fünf Minuten gesenkt, eine volle Stunde bevor sich etwas bewegte, sodass die alte Antwort überall abgelaufen war und ein Rollback innerhalb von Minuten gewirkt hätte. Wir haben Adresseinträge in einer Form belassen, die an Ort und Stelle umgeschaltet werden konnte, denn sie zu entfernen und neu anzulegen hätte eine Lücke hinterlassen, und eine Lücke ist ein Ausfall. Jeder riskante Schritt war eine eigene kleine Änderung, mit in der richtigen Reihenfolge aufgeschriebenen Schritten zum Rückgängigmachen.
Was wir einem anderen Team raten würden
Wenn deine Nutzer weit von deinen Servern entfernt sind, lohnt sich ein Edge-Netzwerk auch dann, wenn es nichts cacht. Bevor du umstellst:
- Liste alles auf, was die Adresse des Aufrufers liest, darunter Ratenbegrenzungen, Allowlists, Betrugssignale, Audit-Logs und Sicherheitsregeln. Jedes davon sieht die Adresse des Edge, sofern du es nicht änderst.
- Mach die Anzahl vertrauenswürdiger Schichten zum Teil deiner Infrastruktur und verweigere den Start, wenn sie falsch ist.
- Lass den Edge den echten Aufrufer festhalten und vertraue dieser Angabe nur bei Traffic, von dem du prüfen kannst, dass er von deinem Edge kam.
- Stell sicher, dass deine Server Traffic nur über den Edge annehmen, und beobachte, bevor du durchsetzt.
- Wenn du Seiten cachst, bilde den Cache-Schlüssel, die Menge der Anfragedetails, anhand derer ein Cache entscheidet, ob zwei Anfragen sich eine gespeicherte Antwort teilen können, aus allem, wovon die Antwort tatsächlich abhängt. Server listen diese Details in einem Vary-Header auf, lies ihn also nach, statt dich auf dein Gedächtnis zu verlassen.
- Miss vorher und nachher, und betrachte die Handshake-Zeit und die Zeit bis zum ersten Byte getrennt, damit du den Verbindungsaufbau von der Arbeitszeit deiner Server unterscheiden kannst.
Ausblick
Die meisten unserer Seiten sind personalisiert, deshalb liegt der Edge-Cache der Website vorerst größtenteils brach. Die Verbesserung der Verbindung gilt unabhängig davon für jede Seite, und einzelne Seiten können sich jetzt für das Caching entscheiden, wenn es sicher ist, sie gemeinsam zu nutzen. Das Caching von API-Antworten bräuchte ein eigenes Design und Review, und es ist das Nächste, das wir uns ansehen wollen.
Geld sollte sich mit der Geschwindigkeit des Netzwerks bewegen, nicht mit der Lichtgeschwindigkeit über einen Ozean hinweg.
Wenn du auf Moove aufbaust, lies unsere Einführung in Web3-Zahlungs-APIs und -SDKs und das Moove Developer Program.
Verfasst vom Engineering-Team von moove.xyz.
Über moove.xyz
moove.xyz ist eine globale Web3-Fintech-Plattform für die permissionless und mühelose Bewegung von Werten. Wir befähigen Unternehmen und Privatpersonen überall, beliebige Kryptowährungen über beliebige Blockchains zu senden, zu empfangen, zu staken und zu swappen – alles auf einer einzigen Plattform.
Wir gehören weltweit zu den ersten Web3-Fintech-Unternehmen, die eine vollständige Infrastruktur für Krypto-Zahlungen und dezentrale Finanzen entwickeln und aufbauen. Sie umfasst integriert und umfassend Multi-Chain-Wallet-Zugang, personalisierte Wallet-Handles, Cross-Chain-Token-Swaps, eingebettete Cross-Chain-Transaktionen und ein dezentrales soziales Finanznetzwerk. Zu unseren wichtigsten Produkten gehören Moove Profile, Moove Send, Moove Receive, Moove Stake, Moove Swap, Moove Rewards, Moove Discover und mehr.
Unsere Mission ist einfach: permissionless und mühelose Finanztechnologie für die nächsten 1 Milliarde Web3-Nutzer zu entwickeln und zu verbreiten. Wir sind zutiefst überzeugt, dass die Zukunft der Bewegung von Geld und Werten kostenlos, grenzenlos, permissionless, mühelos und für alle gebaut sein wird – und wir bauen die ultimative Web3-Fintech-Plattform, um diese Zukunft Wirklichkeit werden zu lassen.
Dein Geld. Deine Entscheidung.






