Zurück zur Startseite
Leistungen

Backend Engineering, Produkt

Branche

B2B-Marktplatz

Jahr

2022-2024

A/B-Tests in einem Django-Monolithen.

Das Produktteam hatte wochenlang über Features gestritten: ein neues Kontaktformular, eine einfachere Preisanzeige, ein Onboarding-Flow. Niemand konnte belegen, dass die eigene Version besser konvertiert, und jede Änderung bedeutete ein volles Deploy, mit einem zweiten, um sie zurückzunehmen. Was das Team wollte, war schnell gesagt: beide Versionen ausliefern, die nächsten 500 Besucher entscheiden lassen, weitermachen.

DIE HERAUSFORDERUNG

Jedes Deploy war eine Alles-oder-nichts-Wette

Die Plattform hatte keine Experimentier-Infrastruktur. Eine Änderung ging an 100 % der Besucher oder an niemanden, und ein Rollback war ein weiteres Release mit einer weiteren Wartezeit. Es gab keinen Weg, ein Feature 20 % der Besucher zu zeigen und zu vergleichen, also entschieden Meinung und Dienstalter. Eine eigene Experimentierplattform lag außerhalb des Rahmens: kein gehosteter Dienst, keine neue Infrastruktur. Die Antwort musste im bestehenden Django-Stack leben und vom Produktteam bedient werden können, ohne dass ein Entwickler dazwischen sitzt.

DIE LÖSUNG

Prozent-Flags am Besucher, nicht an der Session

Ich habe mich für django-waffle statt für einen gehosteten Dienst wie LaunchDarkly entschieden. Ein gehosteter Dienst wertet Flags bei jedem Request über das Netz aus, braucht ein SDK im Prozess und rechnet pro monatlich aktivem Nutzer ab; waffle wertet im Prozess aus und speichert Flags in derselben PostgreSQL-Datenbank wie alles andere. Der Kern sind Prozent-Flags: Die Visitor-Tracking-Middleware gibt jedem Besucher ohnehin einen deterministischen Hash, und der Prozentwert des Flags ist die Schwelle, mit der dieser Hash verglichen wird. Ein Context Processor stellt den Flag-Zustand jedem Template bereit, und dasselbe Flag wird in Python geprüft, wo sich das Backend anders verhalten muss. Ein eigener FlagAdmin macht den Prozentwert in der Listenansicht editierbar, und so hebt ein Product Manager einen Test mit einem Speichern von 5 % für internes QA auf 10 %, 50 % und 100 %, oder zurück auf 0 %. Der Preis: waffle bringt keine Analytics mit. Das Team nahm den Schalter und machte die Auswertung woanders.

Die Admin-Anpassung, die den Rollout-Prozentwert in die Listenansicht holt:

Python
class FlagAdmin(WaffleFlagAdmin):
    list_display = [
        'name',
        'everyone',
        'percent',
        'superusers',
        'staff',
        'authenticated',
        'note',
        'created',
        'modified',
    ]
    list_editable = [
        'everyone',
        'percent',
        'superusers',
        'staff',
        'authenticated',
        'note',
    ]
    list_filter = ['everyone', 'superusers', 'staff']

Gleicher Besucher, gleiche Variante

Besucher landen per Hash gegen den Rollout-Prozentwert in A oder B. Drück "Besucher kommt zurück", um einen davon erneut zu schicken, eingeloggt oder nicht: Der Bucket bewegt sich nicht. Dann schalte das Flag ab: Alle sehen A, die Hashes bleiben, und beim Wiedereinschalten ist jede Zuordnung wieder da.

show_new_contact_forman
50 %

RegelHash < 50 → B

v-0001Hash 58A
v-0002Hash 22B
v-0003Hash 81A
v-0004Hash 0B
v-0005Hash 32B
v-0006Hash 29B
v-0007Hash 2B
v-0008Hash 47B
v-0009Hash 7B
v-000aHash 7B
v-000bHash 62A
v-000cHash 92A

Jeder Besucher wird einmal gehasht. Der Bucket folgt dem Hash, nicht der Session.

12Besucher
4Variante A
8Variante B
67 %Tatsächlicher B-Anteil
0Zurückgekommen, gleiche Variante

Eine Template-Bedingung, keine Python-Änderung:

HTML
{# base template, contact form A/B test #}

{% load waffle_tags %}

{% flag "show_new_contact_form" %}
  {# Variant B: simplified form #}
  {% include "contact/_form_v2.html" %}
{% else %}
  {# Variant A: original form #}
  {% include "contact/_form_v1.html" %}
{% endflag %}
DAS ERGEBNIS

Kürzere Diskussionen, drei Features nie gebaut

Das Team kam von Meinung zu Messung. Das neue Kontaktformular gewann mit einem klaren Conversion-Plus, eine vereinfachte Preisanzeige senkte die Absprungrate um 11 %, und drei geplante Features wurden vor der Entwicklung gestrichen, weil ein kleiner Rollout kein Interesse zeigte. Eine Idee braucht heute rund zwei Stunden bis zum laufenden Experiment, und eine schlechte Variante ist weg, bevor die meisten Besucher sie gesehen haben. Das Flag-System verursachte in dieser Zeit keinen Vorfall.

WICHTIGE KENNZAHLEN

14A/B-Tests in 18 Monaten
+23%Conversion-Plus, Kontaktformular
30sRollback im Schnitt
KUNDENSTIMME

"Features, über die wir früher wochenlang gestritten haben, gehen jetzt als zwei Versionen live, und die nächsten 500 Besucher entscheiden. Drei Features, von denen wir überzeugt waren, haben niemanden interessiert. Wir haben sie nie gebaut."

Product Manager

B2B-Marktplatz, Produktteam

FÜR DEIN PROJEKT

  • Wann es passt

    Du betreibst einen Monolithen, Produkt und Engineering sind sich regelmäßig uneinig, was gebaut werden soll, und eine gehostete Experimentierplattform ist für ein Dutzend Tests im Jahr schwer zu rechtfertigen. Flags im Prozess geben dir den Schalter ohne das Abo.

  • Was du prüfen solltest

    Ob du eine Besucher-Identität hast, die Login und Logout überlebt. Ohne sie bucketen Prozent-Flags Sessions statt Menschen, und die Daten halten nicht. Leg vor dem ersten Test fest, wer ein Flag in Produktion umlegen darf, nicht danach.

  • Was es braucht

    django-waffle, einen Haken in deine Visitor-Middleware, einen Context Processor und eine kleine Admin-Anpassung: keine neue Infrastruktur. Die Disziplin kostet mehr als der Code. Jedes Flag braucht ein Ticket, ein Enddatum und einen Ausbau, sonst füllt sich die Codebasis mit toten Schaltern.

FAQ

TECHNOLOGIE-STACK

Django
Python
PostgreSQL

Daniel hat bei der Gründung und Umsetzung der Unternehmen Solvster und VIARES einen entscheidenden Beitrag geleistet. Er war verantwortlich für den gesamten technischen Aufbau der Onlinepräsenz, inklusive der Serversetups, der Entwicklung und Optimierung der Website sowie der Sicherstellung der Funktionalität. Besonders beeindruckt hat mich, wie proaktiv und lösungsorientiert er immer an Verbesserungen gearbeitet hat. Daniel war stets sehr responsiv und zuverlässig - es war eine Freude, mit ihm zusammenzuarbeiten. Seine Expertise und sein Engagement haben maßgeblich zum Erfolg beider Projekte beigetragen!

Dietmar Eglhofer - Geschäftsführer, Solvster & VIARES

Schließe dich Dietmar an und starte dein nächstes Projekt mit Zuversicht.

Schreibe mirSchreibe mir