A/B testi, mağazanızdaki bir değişikliğin siparişleri gerçekten artırıp artırmadığını, yoksa yalnızca iyi bir haftaya denk gelip gelmediğini ayırt etmenin en güvenilir yoludur. Yanlış kurmak da bir o kadar kolaydır: testi erken durdurursanız, az trafikle çalıştırırsanız ya da sayfa önbelleği ziyaretçiye yanlış varyantı gösterirse "kazanan" dediğiniz sonuç gürültüden ibaret olur. Bu rehberde bir sonucun güvenilir olup olmadığını belirleyen adımları (hipotez, metrikler, örneklem büyüklüğü, süre, analiz ve geçerlilik kontrolleri) ve Google Optimize kapandıktan sonra elde kalan uygulama seçeneklerini anlatıyoruz. Aşağıdaki tüm sayılar yanlarında yazan varsayımlarla hesaplandı; hiçbiri sizin için beklenen bir artış değildir.
1. A/B testi neyi yanıtlar, neyi yanıtlayamaz?
Ziyaretçiler rastgele iki gruba ayrılır: biri mevcut sürümü (kontrol, A), diğeri değiştirilmiş sürümü (B) görür. Kimin neyi göreceğine yalnızca şans karar verdiği için birincil metrikte rastgele dalgalanmayı aşan bir fark çıkarsa bu fark değişikliğe bağlanabilir. A/B testinin iyi yaptığı iş budur: tek bir değişikliğin nedensel (causal) etkisini, önceden seçilmiş tek bir metrikle ölçmek.Ziyaretçilerin neden farklı davrandığını söylemez; bunu oturum kayıtları, anketler ve kullanıcı testleri yanıtlar. Tekrar satın alma gibi uzun vadeli etkiler hakkında, onları daha uzun bir pencerede ölçmedikçe pek bir şey söylemez. Gruplar sınırlı bir kaynağı paylaştığında da zorlanır; örneğin bir varyant stoğu ya da kampanya bütçesini iki grup için birden tüketebilir. Trafiğinizin izin verdiğinden küçük etkileri de yakalayamaz: ayda birkaç bin ziyaretçi alan bir sayfada düğme rengi testi neredeyse her zaman "sonuçsuz" biter, çünkü gerçekçi bir etkiyi görmek için gereken örneklemi toplamak aylar, hatta yıllar sürer. Trafiğiniz azsa onu cesur değişiklikleri test etmeye ya da kullanıcı araştırmasına ayırın.
Hipotezi, kimse bir şey geliştirmeye başlamadan önce yazın:
{Gözlem veya veri} nedeniyle, {sayfa veya kitle} için {değişiklik} yapmanın {birincil metriği} artıracağını (veya azaltacağını) düşünüyoruz. Test, her varyant {N kullanıcıya} ulaşıp {tam hafta sayısı} dolduğunda bitecek. Fark için %95 güven aralığı sıfırı içermiyorsa ve {koruma metrikleri} {eşik} değerinden fazla kötüleşmiyorsa sonucu başarılı sayacağız.
2. Metrik seçimi: bir birincil metrik, birkaç koruma metriği
- Dönüşüm oranı (conversion rate): en az bir sipariş veren kullanıcılar bölü varyanta atanan kullanıcılar. Paydada rastgeleleştirme birimini kullanın (oturumu değil, kullanıcıyı); aksi halde bir müşterinin on oturumu birbirinden bağımsız on gözlem gibi sayılır. Tekrar siparişler de önemliyse kullanıcı başına sipariş sayısını ayrı bir ortalama metriği olarak izleyin ve RPV gibi analiz edin.
- Ziyaretçi başına gelir (revenue per visitor, RPV): hem dönüşümü hem sepet büyüklüğünü yakalar, ama ziyaretçilerin çoğu hiç harcama yapmadığı için varyansı yüksektir. Varsayımsal bir örnek: dönüşüm %2, ortalama sepet 500 TL ve sepet tutarının standart sapması 500 TL ise RPV'nin ortalaması 10 TL, standart sapması yaklaşık 99,5 TL olur. Bu durumda RPV'de %10'luk göreli bir değişikliği yakalamak için varyant başına yaklaşık 155.408 kullanıcı gerekir; aynı göreli değişikliği dönüşüm oranında yakalamaya 80.682 kullanıcı yeter (bölüm 3). Yani RPV neredeyse iki kat trafik ister. Aşırı büyük siparişleri nasıl sınırlayacağınıza baştan karar verin (örneğin 99. yüzdeliğin üstündeki tutarları o değere eşitlemek; buna winsorizing denir); analizde Welch t-testi ya da bootstrap kullanın. Deney öncesi veriyle varyans azaltma (CUPED) gereken örneklemi küçültebilir.
- Ortalama sepet tutarı (average order value, AOV): yalnızca satın alanları kapsar. Varyant kimin satın aldığını değiştiriyorsa AOV karşılaştırması yanıltır; bu yüzden RPV'nin yanında ikincil metrik olarak raporlayın.
- Koruma metrikleri (guardrail metrics): iade ve iptal oranı, ödeme hataları, sayfa hızı (örneğin LCP), JavaScript hataları ve müşteri hizmetlerine gelen talepler. Daha çok satıp bunlardan birini bozan varyant kazanan değildir.
3. Örneklem büyüklüğü (sample size) ve en küçük saptanabilir etki (MDE)
Kaç kullanıcıya ihtiyacınız olduğunu dört girdi belirler:- Başlangıç oranı (baseline, p1): teste girecek kullanıcıların mevcut dönüşüm oranı; son birkaç tam haftanın verisinden alın.
- En küçük saptanabilir etki (minimum detectable effect, MDE): yakalamaya değer en küçük değişiklik. Göreli mi mutlak mı olduğunu açıkça yazın: %2 üzerinde %10'luk göreli artış %2,2 eder; mutlak fark 0,2 yüzde puandır.
- Anlamlılık düzeyi (alfa, significance level): kabul ettiğiniz yanlış pozitif oranı; genellikle çift yönlü 0,05.
- İstatistiksel güç (power, 1 − beta): etki gerçekten MDE kadarsa onu yakalama olasılığı; genellikle %80.
Kod:
n = [ z(1−α/2)·√(2·p̄·(1−p̄)) + z(1−β)·√(p1·(1−p1) + p2·(1−p2)) ]² / (p2 − p1)²
- √(2 × 0,021 × 0,979) = √0,041118 ≈ 0,202776 ve √(0,02 × 0,98 + 0,022 × 0,978) = √0,041116 ≈ 0,202771
- 1,959964 × 0,202776 + 0,841621 × 0,202771 ≈ 0,397434 + 0,170656 = 0,568090
- 0,568090² ≈ 0,322726; bunu (0,002)² = 0,000004'e bölünce yaklaşık 80.681,5 çıkar
Python:
import math
from statsmodels.stats.power import NormalIndPower
from statsmodels.stats.proportion import proportion_effectsize
baseline = 0.02 # mevcut dönüşüm oranı
target = baseline * 1.10 # %10 göreli MDE -> 0.022
h = proportion_effectsize(target, baseline) # Cohen's h
n = NormalIndPower().solve_power(effect_size=h, alpha=0.05, power=0.80,
ratio=1.0, alternative="two-sided")
print(f"h = {h:.5f}, varyant başına kullanıcı = {math.ceil(n):,}")
# h = 0.01395, varyant başına kullanıcı = 80,638
| Başlangıç dönüşümü | Göreli MDE %5 | Göreli MDE %10 | Göreli MDE %20 |
|---|---|---|---|
| %1 | 637.010 | 163.095 | 42.693 |
| %2 | 315.206 | 80.682 | 21.109 |
| %3 | 207.938 | 53.211 | 13.914 |
| %5 | 122.124 | 31.234 | 8.158 |
4. A/B testi ne kadar sürmeli?
Test süresini hesaplamak için: süre = (varyant başına kullanıcı × varyant sayısı) ÷ teste her gün giren yeni kullanıcı sayısı; sonucu tam haftaya yuvarlayın. Günlük oturumu değil, test edilen sayfaya ulaşan tekil kullanıcıyı sayın, çünkü geri dönen ziyaretçi teste yalnızca bir kez girer. Günde 12.000 yeni kullanıcıyla örnek test 161.364 ÷ 12.000 ≈ 13,4 gün sürer; yani iki tam hafta.- Tam haftalar: hafta içi ve hafta sonu alışveriş yapanlar farklı davranır. Örneklemini üç günde dolduran bir test bile en az bir, tercihen iki tam haftayı kapsamalıdır.
- İş döngüleri ve kampanyalar: Kasım indirimleri (Black Friday, 11.11), yılbaşı, Sevgililer Günü, Anneler Günü, okula dönüş, Ramazan ve Kurban Bayramı öncesi haftalar ve maaş günleri siteye kimin, neden geldiğini değiştirir. Testleri bu dönemlerin dışında tutun ya da dönemi kapsayıp kampanya günlerini ayrıca analiz edin; indirim avcıları arasında kazanan çıkan bir varyant sıradan bir haftada aynı sonucu vermeyebilir.
- Yenilik ve alışkanlık etkileri (novelty / primacy effect): düzenli müşteriler yeni bir öğeye sırf yeni olduğu için tıklayabilir ya da alışkın olmadıkları için ondan kaçınabilir. Günlük farkı grafiğe dökün, yeni ve geri dönen kullanıcıları ayrı ayrı karşılaştırın; haftadan haftaya zayıflayan bir etki uyarı işaretidir.
- Çok uzun da olmamalı: test uzadıkça daha çok ziyaretçi çerezini kaybeder ve yeniden atanır (Safari, JavaScript ile document.cookie üzerinden yazılan çerezlerin ömrünü yedi günle, bazı durumlarda daha kısa bir süreyle sınırlar); mevsimsellik de araya girer. Testleri yaklaşık dört ila altı hafta içinde bitecek şekilde planlayın.
- Yazılı bir durdurma kuralı: örneğin "Her varyant 80.682 kullanıcıya ulaşıp 14 tam gün dolunca dur; ödeme hatalarının ikiye katlanması gibi bir koruma metriği bozulmadıkça erken durma."
5. Sonucu analiz etmek: istatistiksel anlamlılık ve güven aralığı
Dönüşüm oranlarında iki oran z-testi (two-proportion z-test) ile 2×2 tablo üzerindeki ki-kare testi (süreklilik düzeltmesi olmadan) aynı p değerini verir. Yalnızca p değerini değil, farkı güven aralığıyla (confidence interval) birlikte raporlayın. Varsayımsal sayılarla bir örnek:
Python:
from statsmodels.stats.proportion import proportions_ztest, confint_proportions_2indep
conv_b, n_b = 1790, 80650 # varyant B: sipariş veren kullanıcı, toplam kullanıcı
conv_a, n_a = 1614, 80700 # kontrol A
z, p = proportions_ztest([conv_b, conv_a], [n_b, n_a])
lo, hi = confint_proportions_2indep(conv_b, n_b, conv_a, n_a, compare="diff")
rlo, rhi = confint_proportions_2indep(conv_b, n_b, conv_a, n_a, compare="ratio")
fark = conv_b / n_b - conv_a / n_a
artis = (conv_b / n_b) / (conv_a / n_a) - 1
print(f"z = {z:.2f}, p = {p:.4f}")
print(f"fark = {fark*100:+.2f} yüzde puan, %95 güven aralığı [{lo*100:+.2f}, {hi*100:+.2f}]")
print(f"göreli = {artis:+.1%}, %95 güven aralığı [{rlo-1:+.1%}, {rhi-1:+.1%}]")
Kod:
z = 3.07, p = 0.0022
fark = +0.22 yüzde puan, %95 güven aralığı [+0.08, +0.36]
göreli = +11.0%, %95 güven aralığı [+3.8%, +18.6%]
p değeri ne demektir? Gerçekte hiçbir fark olmasaydı, en az bu kadar uç bir sonucun ortaya çıkma olasılığıdır. B'nin daha iyi olma olasılığı değildir, sonucun tesadüf olma olasılığı da değildir ve etkinin büyüklüğü hakkında bir şey söylemez. Hesabı adım adım görmek için p değeri nasıl hesaplanır ve yorumlanır konumuza bakabilirsiniz.
Ara sonuçlara bakma sorunu (peeking problem): %5'lik yanlış pozitif oranı, yalnızca planlanan örneklemde bir kez bakarsanız geçerlidir. Her senaryo için 200.000 A/A testi simüle ettik (gerçek fark yok, dönüşüm %2, varyant başına 80.682 kullanıcı) ve her testi p < 0,05 görülen ilk bakışta durdurduk. Eşit aralıklı 7 bakışta testlerin yaklaşık %16,6'sı, her gün bakılan 14 bakışta yaklaşık %22'si, 28 bakışta ise yaklaşık %27,5'i bir "kazanan" ilan etti. Sonuçları sürekli izlemeniz gerekiyorsa buna göre tasarlanmış bir yöntem kullanın: alfa harcama (alpha spending) fonksiyonlu grup ardışık tasarımlar (örneğin O'Brien-Fleming sınırları) ya da her an geçerli (always-valid) ardışık testler. GrowthBook frekansçı motorunda ardışık test (sequential testing) seçeneği sunar; Optimizely'nin Stats Engine'i de ardışık test üzerine kuruludur.
Bayesçi raporlama sonucu "B'nin A'yı geçme olasılığı" ve "B'yi yayına alırsak beklenen kayıp" olarak ifade eder; birçok ekip bunu daha kolay yorumlar. GrowthBook varsayılan olarak Bayesçi motorunu kullanır. Bu yaklaşım raporun dilini değiştirir; örneklem tahminine ve önceden üzerinde anlaşılmış bir karar kuralına olan ihtiyacı ortadan kaldırmaz.
Birden çok varyant veya metrik: her ek karşılaştırma, yanlış pozitif için yeni bir fırsattır. Üç varyantı tek bir kontrolle karşılaştırırken Bonferroni düzeltmesiyle alfayı 0,05/3'e indirirseniz örnek test grup başına 107.616, toplamda 161.364 yerine 430.464 kullanıcı ister. Holm yöntemi Bonferroni'nin reddettiği her hipotezi reddeder, bazen daha fazlasını da; uzun bir ikincil metrik listesinde Benjamini-Hochberg yöntemi yanlış keşif oranını (false discovery rate) kontrol eder (statsmodels'te multipletests fonksiyonu, method="holm" ya da method="fdr_bh"). Tek bir birincil metrik belirleyin, gerisini keşif amaçlı yorumlayın.
6. Sonuca güvenmeden önce geçerlilik kontrolleri
Örneklem oranı uyumsuzluğu (sample ratio mismatch, SRM): 50/50 planladığınız bir testte yaklaşık 100.000 kullanıcıda 50,7/49,3 gördüyseniz bir şey kullanıcıları gruplardan eşit olmayan biçimde dışarıda bırakıyordur ve sonuç ne kadar iyi görünürse görünsün güvenilmezdir.
Python:
from scipy.stats import chisquare
observed = [50421, 49102] # A ve B'ye atanan kullanıcılar (plan: 50/50)
expected = [sum(observed) * 0.5, sum(observed) * 0.5]
stat, p = chisquare(observed, f_exp=expected)
print(f"chi2 = {stat:.2f}, p = {p:.1e}") # chi2 = 17.48, p = 2.9e-05
- Yönlendirmeli (split URL) testler: yönlendirme yalnızca bir taraftaki ziyaretçilerin bir kısmını kaybettirir ve o tarafa gecikme ekler.
- Botlar: Google Analytics bilinen botları otomatik olarak ayıklar, ama sizin atama servisiniz onları saymaya devam edebilir; bir varyant tarama botlarını (crawler) farklı biçimde çekebilir.
- Çerez rızası: analize yalnızca verisini toplamanıza izin verilen kullanıcılar girer. KVKK'nın Çerez Uygulamaları Hakkında Rehberi (Temmuz 2025 baskısı), amacı sitenin kendi kitlesini ölçmekle sınırlı birinci taraf analitik çerezlerin açık rıza gerektirmeyebileceğini değerlendirir; koşul, bu çerezlerin yalnızca anonim istatistik üretmesi ve kişileri siteler arasında izlemek için kullanılmamasıdır. Rehber, alınabilecek tedbirler arasında IP maskelemeyi, makul bir çerez ömrünü ve verinin üçüncü taraflara iletilmemesini sayar. Davranışsal reklam çerezleri ise açık rıza gerektirir. AB'de ePrivacy kuralları kesinlikle gerekli olmayan çerezler için rıza ister; bazı denetim otoriteleri dar tanımlı kitle ölçümüne istisna tanır. Deney çerezinizin ve analitik aracınızın bu çerçevede nereye düştüğünü hukuk ekibinizle netleştirin. İstatistik açısından: GA4'e yalnızca onay veren kullanıcıların verisi gidiyorsa sonucunuz onay veren kullanıcıları anlatır; onay oranını değiştiren bir varyant (örneğin içeriği çerez bandının altına kaydıran bir tasarım) SRM'ye yol açar. GA4'ün izin modu (consent mode) modellemesi raporlardaki boşlukları doldurur, ama modellenmiş veri BigQuery dışa aktarımında ve kullanıcı düzeyinde yer almaz; bu yüzden anlamlılık testine giremez.
- Titreme (flicker): istemci tarafı araçlar sayfayı çizilmeye başladıktan sonra değiştirir. Ya ziyaretçi varyanttan önce bir an orijinali görür ya da titreme önleyici bir kod parçası (anti-flicker snippet) betik çalışana kadar sayfayı gizler ve testteki herkesin sayfası geç açılır. İki durumu da yavaşlatılmış bir mobil bağlantıda kontrol edin.
- Sayfa ve CDN önbelleği: varyantları sunucu üretiyorsa ve tam sayfa önbelleği ilk yanıtı saklıyorsa herkes aynı varyantı alabilir. Varyantı önbellek anahtarına ekleyin ve varyantı atayan yanıtı asla önbelleğe almayın:
Kod:
# http {} bloğunda: yalnızca bilinen varyant değerlerini kabul et
map $cookie_ab_pdp $ab_bucket {
default "";
control control;
treatment treatment;
}
map $ab_bucket $ab_skip_cache {
"" 1;
default 0;
}
# Yalnızca test edilen sayfaları sunan location bloğunda (PHP-FPM tam sayfa önbelleği)
fastcgi_cache_key "$scheme$request_method$host$request_uri|ab=$ab_bucket";
fastcgi_cache_bypass $ab_skip_cache; # varyantı olmayan istek önbellekten okunmaz
fastcgi_no_cache $ab_skip_cache; # ve yanıtı önbelleğe yazılmaz
# Set-Cookie içeren yanıtlar varsayılan olarak önbelleğe alınmaz;
# fastcgi_ignore_headers satırına Set-Cookie eklemeyin.
Oturumu değil, kullanıcıyı atayın: aynı kişi her ziyarette ve her sunucuda aynı varyantı görmelidir. Deney boyunca tek bir kimlik kullanın; test, kullanıcı giriş yapmadan önce başlıyorsa girişten sonra hesap kimliğine geçmeyin, yoksa kullanıcı testin ortasında varyant değiştirir. Test sürerken trafik ağırlıklarını da değiştirmeyin: 10/90'dan 50/50'ye geçmek kullanıcıları gruplar arasında taşır ve farklı bölme oranlarına sahip dönemleri birbirine karıştırır.
İlk gerçek testten önce iki grubun da aynı sayfayı gördüğü bir A/A testi çalıştırın. SRM çıkmamalıdır; anlamlı bir fark ise alfa 0,05 iken yaklaşık yirmi A/A testinden birinde tesadüfen görülür. SRM çıkarsa ya da A/A testini tekrarladığınızda anlamlı fark yine görülürse önce ölçümü veya atamayı düzeltin.
7. Uygulama seçenekleri: istemci tarafı, sunucu tarafı, özellik bayrakları
| Yaklaşım | Nasıl çalışır | Uygun olduğu işler | Dikkat edilecekler |
|---|---|---|---|
| İstemci tarafı (client-side) | Bir JavaScript betiği sayfayı tarayıcıda değiştirir; çoğu zaman görsel editörle | Metin, yerleşim, görsel; geliştirici zamanı olmayan pazarlama ekipleri | Titreme, sayfa hızı, reklam engelleyiciler; yalnızca ön yüz değişiklikleri |
| Sunucu tarafı (server-side) | Uygulama varyantı seçer ve sayfayı ona göre üretir | Ödeme mantığı, arama sıralaması, kargo kuralları, API arkasındaki her şey | Geliştirme emeği, sayfa önbelleği |
| Özellik bayrakları (feature flags) | Bir SDK bayrağı yüzdesel dağıtımla değerlendirir, gösterimleri analitiğe bildirir | Yayına alma ve testi tek mekanizmayla yapmak; kademeli dağıtım | Ayrı bir analiz katmanı gerekir; eskiyen bayraklar temizlenmelidir |
| Uç katman (edge) | Bir CDN worker'ı varyantı atar ve ona uyan önbellekteki sayfayı sunar | Önbellekli vitrinler, titremesiz testler | Sağlayıcıya özgü kod |
- Ticari test platformları: Optimizely, VWO ve AB Tasty; Google, Optimize'ı kapatırken Google Analytics entegrasyonları için bu üç ortağın adını verdi. Kameleoon ve Convert da bu gruptaki örneklerdendir.
- Açık kaynak: GrowthBook (açık çekirdek: kodun büyük kısmı MIT lisanslı, kurumsal dizinler ticari lisanslı; Bayesçi ve frekansçı motor, ardışık test, CUPED ve SRM kontrolü) ve PostHog (ee/ dizini dışındaki kod MIT; deney özelliği olan ürün analitiği). Özellik bayrağı platformları: Unleash (AGPL-3.0) ve Flagsmith (BSD-3-Clause). Unleash varyant gösterimlerini analitik aracınıza gönderir, analiz orada yapılır; Flagsmith'te ise bu yazı yazılırken beta aşamasında olan, Bayesçi istatistik motoruna sahip yerleşik bir deney (experimentation) özelliği de var. Lisanslar değişebilir; kendi sunucunuza kurmadan önce depodaki LICENSE dosyasını okuyun.
- Mobil uygulamalar: Firebase A/B Testing; iOS ve Android'de Remote Config, Cloud Messaging ve In-App Messaging ile çalışır.
Kod:
// Ziyaretçi test edilen öğeyi gerçekten gördüğünde bir kez gönderin
gtag('event', 'experiment_impression', {
experiment_id: 'pdp-delivery-date-v1',
variant_id: 'treatment'
});
Hash ile yapışkan atama (sticky assignment, PHP): değişmeyen bir kimliği deney anahtarıyla birlikte hash'lemek, atama tablosu tutmadan her istekte ve her sunucuda aynı varyantı verir. Yeni bir anahtar, bir sonraki deney için kullanıcıları yeniden rastgele dağıtır.
PHP:
<?php
// Aynı kimlik + aynı deney anahtarı => her istekte ve her sunucuda aynı varyant
function ab_variant(string $unitId, string $experimentKey, array $weights): string
{
$hash = hash('sha256', $experimentKey . ':' . $unitId);
$x = hexdec(substr($hash, 0, 8)) / 4294967296; // [0, 1) aralığında sayı
$cumulative = 0.0;
foreach ($weights as $variant => $weight) {
$cumulative += $weight;
if ($x < $cumulative) {
return $variant;
}
}
return array_key_last($weights); // yuvarlama payı
}
// Ziyaretçi kimliği: sunucunun yazdığı birinci taraf, HttpOnly çerez.
// Rıza kurallarınız gerektiriyorsa bu bloğu yalnızca onaydan sonra çalıştırın.
$visitorId = $_COOKIE['vid'] ?? '';
if (!is_string($visitorId) || !preg_match('/^[a-f0-9]{32}$/', $visitorId)) {
$visitorId = bin2hex(random_bytes(16));
setcookie('vid', $visitorId, [
'expires' => time() + 180 * 86400,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
}
$variant = ab_variant($visitorId, 'pdp-delivery-date-v1', ['control' => 0.5, 'treatment' => 0.5]);
// Sayfa önbelleğine hangi varyantın sunulacağını bildirir (Nginx örneğine bakın); kimlik değildir
if (($_COOKIE['ab_pdp'] ?? '') !== $variant) {
setcookie('ab_pdp', $variant, ['expires' => time() + 30 * 86400, 'path' => '/', 'secure' => true, 'samesite' => 'Lax']);
}
8. Hipotez olarak yazılmış e-ticaret test fikirleri
Bunlar vaat edilen sonuçlar değil, başlangıç noktalarıdır. Ürün sayfası ve ödeme adımı tasarımının kendi alt forumları var; burada odak, her testin nasıl kurgulanacağı.- Kargo ücreti mesajı: kargo ücretinin ilk göründüğü adımda çıkışlar arttığı için ürün ve sepet sayfalarında ücretsiz kargo eşiğini ve kalan tutarı göstermek dönüşüm oranını artıracaktır. Koruma metriği: sipariş başına marj; AOV'yi ikincil metrik olarak izleyin.
- Teslim tarihi: "1-3 günde kargoda" yerine tahmini teslim tarihini ("Perşembe kapınızda") göstermek siparişi artıracaktır. Yalnızca tarih güvenilirse test edin; koruma metriği: geç teslimat şikâyetleri.
- Ürün sayfasında bilgi sırası: giyimde beden tablosunu ve iade koşullarını ilk ekrana taşımak siparişi artıracak ve bedene bağlı iadeleri azaltacaktır. Birincil metrik: dönüşüm oranı; koruma metriği: iade oranı.
- Ödeme adımları: üye olmadan devam etme (misafir ödeme) seçeneği ya da daha az form alanı tamamlanan siparişi artıracaktır. Koruma metrikleri: ödeme hataları ve sahtekârlık oranı.
- Ödeme seçeneklerinin sırası: taksit tablosunu ürün sayfasında göstermek ya da kart, havale/EFT, kapıda ödeme ve dijital cüzdan seçeneklerinin sırasını değiştirmek ödemeyi tamamlama oranını değiştirecektir. Koruma metrikleri: ödeme maliyetleri ve kapıda ödemede teslim alınmayan siparişler.
9. A/B testinde sık yapılan hatalar
| Hata | Ne bozulur | Çözüm |
|---|---|---|
| İlk anlamlı sonuçta durmak | İki hafta boyunca her gün bakıldığında yanlış pozitif oranı %5'ten yaklaşık %22'ye çıkar (yukarıdaki simülasyon) | Sabit örneklem ve süre ya da ardışık bir yöntem |
| Örneklem hesabı yapmamak | Gücü yetersiz testler "sonuçsuz" biter ya da gürültüyü kazanan ilan eder | Geliştirmeye başlamadan önce başlangıç oranı ve MDE'den n'yi hesaplayın |
| Birim olarak oturum kullanmak | Aynı müşteri iki varyantı da görür; gözlemler bağımsız olmaz | Kullanıcı bazında atayın ve analiz edin |
| Test ortasında bölme oranını değiştirmek | Kullanıcılar grup değiştirir; farklı oranlı dönemler karışır | Ağırlıkları sabit tutun ya da testi yeniden başlatın |
| Birçok metrik arasından en iyisini seçmek | Çoklu karşılaştırma yanlış pozitifleri artırır | Tek birincil metrik, diğerleri için düzeltme |
| SRM'yi görmezden gelmek | Dengesiz gruplar her sonucu anlamsız kılar | Bölme oranını her gün kontrol edin; durdurup nedeni düzeltin |
| Yalnızca kampanya döneminde test etmek | Kazanan varyant sıradan haftalarda aynı sonucu vermeyebilir | Normal tam haftalar ya da kampanya için ayrı analiz |
| Varyantların önünde sayfa önbelleği | Ziyaretçi yanlış varyantı alır | Varyantı önbellek anahtarına ekleyin ya da atamayı uç katmanda yapın |
| Biten testi açık bırakmak | Google gereksiz uzun süren bir deneyi arama motorlarını yanıltma girişimi sayabilir; trafik de boşa gider | Yönlendirmeli testlerde 302 ve rel=canonical kullanın; karar verilince testi kaldırın |
Sık sorulan sorular
A/B testi için en az ne kadar trafik gerekir?Evrensel bir alt sınır yok, hesabı tersten yapın. %2 başlangıç oranında (alfa 0,05, güç %80) varyant başına 25.000 kullanıcı ancak yaklaşık %18'lik, 50.000 kullanıcı ise yaklaşık %13'lük göreli bir değişikliği yakalayabilir. Gerçekçi olarak bekleyebileceğiniz etki bundan küçükse daha cesur değişiklikler test edin ya da nitel araştırmaya yönelin.
Araç %95 gösterdiğinde testi durdurabilir miyim?
Sabit süreli (fixed-horizon) bir testte hayır. Eşiğin ilk geçildiği anda durmak, yukarıdaki simülasyonun gösterdiği gibi yanlış pozitifleri artırır. Planlanan örneklemi ve süreyi bekleyin ya da sürekli izlemeye uygun bir yöntem ve araç kullanın.
A/B testi mi, çok değişkenli test mi?
Çok değişkenli test (multivariate test, MVT) birden çok öğeyi aynı anda değiştirir ve kombinasyonları karşılaştırır. İkişer sürümlü üç öğe sekiz hücre eder; her hücreyi kontrolle aynı güçte karşılaştırmak, çoklu karşılaştırma düzeltmesinden önce bile iki varyantlı bir testin yaklaşık dört katı trafik ister. MVT'yi çok trafik alan sayfalara saklayın.
Fiyat testi yasal ve etik olarak yapılabilir mi?
Aynı ürüne aynı anda rastgele müşterilere farklı fiyat göstermek hukuki ve güven açısından risklidir. Türkiye'de mal satışına ilişkin indirim reklamlarında, indirimden önceki fiyat olarak indirimin yapıldığı satış kanalında indirimin başlangıcından önceki on gün içinde uygulanan en düşük fiyat esas alınır (Ticari Reklam ve Haksız Ticari Uygulamalar Yönetmeliği; 1 Temmuz 2026 tarihli ve 33297 sayılı Resmî Gazete'deki değişiklik, 1 Ağustos 2026'dan beri yürürlükte). Üstü çizili fiyat gösteren bir varyant da bu kurala uymak zorundadır. AB'de Omnibus Direktifi (2019/2161), fiyat otomatik karar almaya dayalı olarak kişiselleştirildiğinde tüketicinin bilgilendirilmesini ister ve indirim duyuruları için en az 30 günlük bir önceki fiyat kuralı getirir. Fiyatın kendisi yerine sunumunu (taksit, kargo eşiği, paket) test etmeyi tercih edin, her zaman gösterdiğiniz fiyatı tahsil edin ve hukuki görüş alın.
Google Optimize'ın yerini ne aldı, alternatifleri neler?
Web siteleri için GA4'te yerleşik bir karşılığı yok. Google, Google Analytics ile entegre olan üçüncü taraf araçlara (AB Tasty, Optimizely ve VWO'nun adını verdi) ve entegrasyon API'lerine yönlendiriyor. Açık kaynak seçenekler arasında GrowthBook ve PostHog var; mobil uygulamalar için Firebase A/B Testing kullanılabilir.
Sonuç ve sonraki adımlar
Güvenilir bir A/B testini belirleyen kararların çoğu yayına almadan önce verilir: tek hipotez, tek birincil metrik, tam haftalar içinde ulaşılabilecek bir örneklem ve yazılı bir durdurma kuralı. Yayından sonra izlemeniz gereken p değeri değil, bölme oranı ve koruma metrikleridir. Sonraki adımlar:- Değiştirmek istediğiniz sayfanın son dört tam haftalık verisini çekin; başlangıç dönüşüm oranını ve günlük trafiğini not edin.
- İş açısından anlamlı bir MDE için örneklem büyüklüğünü hesaplayın; test altı haftadan uzun sürecekse daha cesur bir değişiklik seçin.
- Uygulama yolunu seçin (istemci tarafı, sunucu tarafı ya da özellik bayrakları) ve atamayı, ölçümü ve SRM kontrolünü doğrulamak için bir A/A testi çalıştırın.
- Hipotezi, metrikleri, koruma metriklerini ve durdurma kuralını ortak bir belgeye yazın, ardından testi başlatın.
An A/B test is the most reliable way to find out whether a change to your store causes more orders, rather than just coinciding with a good week. It is also easy to get wrong: stop too early, run it on too little traffic or let a page cache serve the wrong variant, and the "winner" is noise. This guide covers what decides whether a result can be trusted (hypothesis, metrics, sample size, duration, analysis and validity checks) and the implementation options left now that Google Optimize is gone. Every number below is computed from the assumptions stated next to it; none of them is an uplift you should expect.
1. What an A/B test can and cannot answer
Visitors are split at random between the current version (control, A) and a changed version (B). Because only chance decides who sees what, a difference in the primary metric that is larger than random noise can be attributed to the change. That is what an A/B test does well: a causal comparison of one change, judged by one metric chosen in advance.It cannot tell you why visitors behave differently; session recordings, surveys and user tests answer that. It says little about long-term effects such as repeat purchases unless you measure them over a longer window. It struggles when the groups share a limited resource, for example stock or a campaign budget that one variant can use up for both. And it cannot detect effects smaller than your traffic allows: a button-colour test on a page with a few thousand visitors a month will almost always end "inconclusive", because the sample needed for a realistic effect would take months, even years, to collect. If traffic is scarce, spend it on bold changes or on user research.
Write the hypothesis before anyone builds anything:
Because {observation or data}, we believe that {change} for {page or audience} will {increase/decrease} {primary metric}. The test ends when each variant has {N users} and {number of whole weeks} have passed. We will call it a success if the 95% confidence interval for the difference excludes zero and {guardrail metrics} do not worsen by more than {threshold}.
2. Metrics: one primary, several guardrails
- Conversion rate: users who placed at least one order, divided by users assigned to the variant. Use the unit you randomise on (users, not sessions) as the denominator; otherwise one shopper's ten sessions count as ten independent observations. If repeat orders matter, track orders per user as a separate mean metric and analyse it like RPV.
- Revenue per visitor (RPV): captures both conversion and basket size, but its variance is high because most visitors spend nothing. An illustration with assumed values: 2% conversion and an average order of 500 TL with a standard deviation of 500 TL give an RPV mean of 10 TL and a standard deviation of about 99.5 TL. Detecting a 10% relative change in RPV then takes about 155,408 users per variant, almost twice the 80,682 needed for the same relative change in conversion rate (section 3). Decide in advance how to cap extreme orders (for example at the 99th percentile, known as winsorizing) and analyse with Welch's t-test or a bootstrap. Variance reduction with pre-experiment data (CUPED) can shrink the required sample.
- Average order value (AOV): covers buyers only. If the variant changes who buys, AOV comparisons mislead, so report it as a secondary metric next to RPV.
- Guardrail metrics: returns and cancellations, payment failures, page speed (for example LCP), JavaScript errors and customer-service contacts. A variant that sells more but breaks one of these is not a winner.
3. Sample size and minimum detectable effect (MDE)
Four inputs decide how many users you need:- Baseline rate (p1): the current conversion rate of the users who will enter the test, taken from the last few whole weeks.
- Minimum detectable effect (MDE): the smallest change worth detecting. Say whether it is relative or absolute: a 10% relative lift on 2% is 2.2%, an absolute difference of 0.2 percentage points.
- Significance level (alpha): the false-positive rate you accept, usually 0.05 two-sided.
- Power (1 − beta): the chance of detecting the MDE if it is real, usually 80%.
Kod:
n = [ z(1−α/2)·√(2·p̄·(1−p̄)) + z(1−β)·√(p1·(1−p1) + p2·(1−p2)) ]² / (p2 − p1)²
- √(2 × 0.021 × 0.979) = √0.041118 ≈ 0.202776 and √(0.02 × 0.98 + 0.022 × 0.978) = √0.041116 ≈ 0.202771
- 1.959964 × 0.202776 + 0.841621 × 0.202771 ≈ 0.397434 + 0.170656 = 0.568090
- 0.568090² ≈ 0.322726, and 0.322726 ÷ (0.002)² = 0.322726 ÷ 0.000004 ≈ 80,681.5
Python:
import math
from statsmodels.stats.power import NormalIndPower
from statsmodels.stats.proportion import proportion_effectsize
baseline = 0.02 # current conversion rate
target = baseline * 1.10 # +10% relative MDE -> 0.022
h = proportion_effectsize(target, baseline) # Cohen's h
n = NormalIndPower().solve_power(effect_size=h, alpha=0.05, power=0.80,
ratio=1.0, alternative="two-sided")
print(f"h = {h:.5f}, users per variant = {math.ceil(n):,}")
# h = 0.01395, users per variant = 80,638
| Baseline conversion | Relative MDE 5% | Relative MDE 10% | Relative MDE 20% |
|---|---|---|---|
| 1% | 637,010 | 163,095 | 42,693 |
| 2% | 315,206 | 80,682 | 21,109 |
| 3% | 207,938 | 53,211 | 13,914 |
| 5% | 122,124 | 31,234 | 8,158 |
4. How long to run an A/B test
Duration = (users per variant × number of variants) ÷ new users entering the test per day, rounded up to whole weeks. Count unique users who reach the tested page, not daily sessions, because a returning visitor enters the test only once. With 12,000 new users a day, the example needs 161,364 ÷ 12,000 ≈ 13.4 days, so two full weeks.- Whole weeks: weekday and weekend shoppers behave differently. Even a test that reaches its sample in three days should cover at least one full week, preferably two.
- Business cycles and campaigns: November sales (Kasım indirimleri, including Black Friday and 11.11), New Year, Valentine's Day, Mother's Day, back-to-school, the weeks before the Ramazan and Kurban Bayramı holidays, and paydays all change who visits and why. Either keep tests out of these periods or run through them and analyse the campaign days separately; a winner found among deal-seekers may not hold in an ordinary week.
- Novelty and primacy effects: regular customers may click a new element because it is new, or avoid it because it is unfamiliar. Plot the daily difference and compare new with returning users; an effect that fades week by week is a warning sign.
- Not too long either: the longer a test runs, the more visitors lose their cookies and get re-assigned (Safari caps cookies written by JavaScript through document.cookie at seven days, and shorter in some cases), and seasonality creeps in. Plan tests that finish within roughly four to six weeks.
- A written stopping rule: for example "stop when each variant has 80,682 users and 14 full days have passed; stop early only if a guardrail breaks, such as payment errors doubling."
5. Analysing the result: statistical significance and confidence intervals
For conversion rates, a two-proportion z-test and a chi-square test on the 2×2 table (without continuity correction) give the same p-value. Report the difference with its confidence interval, not just the p-value. An example with hypothetical counts:
Python:
from statsmodels.stats.proportion import proportions_ztest, confint_proportions_2indep
conv_b, n_b = 1790, 80650 # variant B: buyers, users
conv_a, n_a = 1614, 80700 # control A
z, p = proportions_ztest([conv_b, conv_a], [n_b, n_a])
lo, hi = confint_proportions_2indep(conv_b, n_b, conv_a, n_a, compare="diff")
rlo, rhi = confint_proportions_2indep(conv_b, n_b, conv_a, n_a, compare="ratio")
diff = conv_b / n_b - conv_a / n_a
lift = (conv_b / n_b) / (conv_a / n_a) - 1
print(f"z = {z:.2f}, p = {p:.4f}")
print(f"difference = {diff*100:+.2f} pp, 95% CI [{lo*100:+.2f}, {hi*100:+.2f}]")
print(f"relative = {lift:+.1%}, 95% CI [{rlo-1:+.1%}, {rhi-1:+.1%}]")
Kod:
z = 3.07, p = 0.0022
difference = +0.22 pp, 95% CI [+0.08, +0.36]
relative = +11.0%, 95% CI [+3.8%, +18.6%]
What a p-value means: if there were no real difference, a result at least this extreme would turn up with probability p. It is not the probability that B is better, not the probability that the result is a fluke, and it says nothing about the size of the effect. Our thread on how to calculate and interpret a p-value walks through the computation step by step.
The peeking problem: the 5% false-positive rate holds only if you look once, at the planned sample. We simulated 200,000 A/A tests per scenario (no real difference, 2% conversion, 80,682 users per variant) and stopped each one at the first look with p < 0.05. With 7 equally spaced looks, about 16.6% of them declared a "winner"; with 14 daily looks, about 22%; with 28 looks, about 27.5%. If you need to monitor results, use a method built for it: group sequential designs with alpha spending (such as O'Brien-Fleming boundaries) or always-valid sequential tests. GrowthBook offers sequential testing in its frequentist engine, and Optimizely's Stats Engine is built on sequential testing.
Bayesian reporting expresses results as "probability that B beats A" and "expected loss if we ship B", which many teams find easier to act on; GrowthBook uses its Bayesian engine by default. It changes the language of the report, not the need for a sample size estimate and a decision rule agreed in advance.
Several variants or metrics: every extra comparison is another chance for a false positive. With three variants against one control and a Bonferroni-corrected alpha of 0.05/3, the example needs 107,616 users per group, 430,464 in total instead of 161,364. Holm's method rejects everything Bonferroni rejects and sometimes more; for a long list of secondary metrics, Benjamini-Hochberg controls the false discovery rate (in statsmodels: multipletests with method="holm" or method="fdr_bh"). Keep one primary metric and treat the rest as exploratory.
6. Validity checks before you believe anything
Sample ratio mismatch (SRM): if you planned 50/50 and got 50.7/49.3 on about 100,000 users, something is excluding users unevenly, and the result cannot be trusted however good it looks.
Python:
from scipy.stats import chisquare
observed = [50421, 49102] # users assigned to A and B (planned 50/50)
expected = [sum(observed) * 0.5, sum(observed) * 0.5]
stat, p = chisquare(observed, f_exp=expected)
print(f"chi2 = {stat:.2f}, p = {p:.1e}") # chi2 = 17.48, p = 2.9e-05
- Redirect (split URL) tests: the redirect loses some visitors and adds delay on one side only.
- Bots: Google Analytics drops known bots automatically, but your assignment service may still count them, and one variant can attract crawlers differently.
- Consent: the analysis contains only users whose data you may collect. KVKK's cookie guide (Çerez Uygulamaları Hakkında Rehber, July 2025 edition) considers that first-party analytics limited to measuring the site's own audience may not need explicit consent, provided the cookies produce only anonymous statistics and are not used to track people across sites; it lists IP masking, a reasonable cookie lifetime and not passing the data to third parties among the measures to take. Cookies for behavioural advertising do need explicit consent. In the EU, the ePrivacy rules require consent for cookies that are not strictly necessary, and some regulators exempt narrowly defined audience measurement. Check with your legal team where your experiment cookie and analytics tool fall. Statistically, if GA4 receives only consenting users, your result describes consenting users, and a variant that changes the consent rate (for example by moving content under the cookie banner) creates SRM. GA4's consent-mode modelling fills gaps in reports, but modelled data is not in the BigQuery export or available at user level, so it cannot feed a significance test.
- Flicker: client-side tools change the page after it starts rendering. Either visitors glimpse the original before the variant appears, or an anti-flicker snippet hides the page until the script runs, which slows rendering for everyone in the test. Check both on a throttled mobile connection.
- Page and CDN cache: if the server renders variants and a full-page cache stores the first response, everyone may receive the same variant. Put the variant into the cache key and never cache the response that assigns it:
Kod:
# In the http {} block: accept only known variant values
map $cookie_ab_pdp $ab_bucket {
default "";
control control;
treatment treatment;
}
map $ab_bucket $ab_skip_cache {
"" 1;
default 0;
}
# Only in the location block that serves the tested pages (PHP-FPM full-page cache)
fastcgi_cache_key "$scheme$request_method$host$request_uri|ab=$ab_bucket";
fastcgi_cache_bypass $ab_skip_cache; # a request without a variant is not served from cache
fastcgi_no_cache $ab_skip_cache; # and its response is not stored
# Responses with Set-Cookie are not cached by default;
# do not add Set-Cookie to fastcgi_ignore_headers.
Assign users, not sessions: the same person must see the same variant on every visit and on every server. Keep one identifier for the whole experiment; if the test starts before login, do not switch to the account ID after login, or users change variants mid-test. Do not change traffic weights during the test either: moving from 10/90 to 50/50 shifts users between groups and mixes periods with different splits.
Before the first real test, run an A/A test with the same page in both groups. It should show no SRM; a significant difference, on the other hand, turns up by chance in about one A/A test in twenty at alpha 0.05. If you see SRM, or a significant difference that comes back when you repeat the A/A test, fix tracking or assignment first.
7. Implementation: client-side, server-side or feature flags
| Approach | How it works | Good for | Watch out for |
|---|---|---|---|
| Client-side | A JavaScript snippet changes the page in the browser, often through a visual editor | Copy, layout, images; marketing teams without developer time | Flicker, page speed, ad blockers, front-end changes only |
| Server-side | The application picks the variant and renders it | Checkout logic, search ranking, shipping rules, anything behind an API | Developer effort, page cache |
| Feature flags | An SDK evaluates a flag with a percentage rollout and reports exposures to analytics | Releasing and testing with one mechanism; gradual rollouts | Needs an analysis layer; stale flags must be removed |
| Edge | A CDN worker assigns the variant and serves the matching cached page | Cached storefronts, tests without flicker | Vendor-specific code |
- Commercial testing platforms: Optimizely, VWO and AB Tasty, the three partners Google named for Google Analytics integrations when it closed Optimize; Kameleoon and Convert are other examples.
- Open source: GrowthBook (open core: most of the code is MIT-licensed, enterprise directories are under a commercial licence; Bayesian and frequentist engines, sequential testing, CUPED and SRM checks) and PostHog (MIT outside its ee/ directory; product analytics with experiments). Feature-flag platforms: Unleash (AGPL-3.0) and Flagsmith (BSD-3-Clause). Unleash sends variant impressions to your analytics tool, where the analysis happens; Flagsmith also has built-in experimentation with a Bayesian statistics engine, in beta at the time of writing. Licences change, so read the LICENSE file before you self-host.
- Mobile apps: Firebase A/B Testing works with Remote Config, Cloud Messaging and In-App Messaging on iOS and Android.
Kod:
// Send once, when the visitor actually sees the tested element
gtag('event', 'experiment_impression', {
experiment_id: 'pdp-delivery-date-v1',
variant_id: 'treatment'
});
Sticky assignment with hashing (PHP): hashing a stable identifier together with the experiment key returns the same variant on every request and every server, without an assignment table. A new key re-randomises users for the next experiment.
PHP:
<?php
// Same unit ID + same experiment key => same variant on every request and server
function ab_variant(string $unitId, string $experimentKey, array $weights): string
{
$hash = hash('sha256', $experimentKey . ':' . $unitId);
$x = hexdec(substr($hash, 0, 8)) / 4294967296; // number in [0, 1)
$cumulative = 0.0;
foreach ($weights as $variant => $weight) {
$cumulative += $weight;
if ($x < $cumulative) {
return $variant;
}
}
return array_key_last($weights); // rounding guard
}
// Visitor ID: a first-party HttpOnly cookie written by the server.
// If your consent rules require it, run this block only after consent.
$visitorId = $_COOKIE['vid'] ?? '';
if (!is_string($visitorId) || !preg_match('/^[a-f0-9]{32}$/', $visitorId)) {
$visitorId = bin2hex(random_bytes(16));
setcookie('vid', $visitorId, [
'expires' => time() + 180 * 86400,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
}
$variant = ab_variant($visitorId, 'pdp-delivery-date-v1', ['control' => 0.5, 'treatment' => 0.5]);
// Tells the page cache which variant to serve (see the Nginx example); not an identity
if (($_COOKIE['ab_pdp'] ?? '') !== $variant) {
setcookie('ab_pdp', $variant, ['expires' => time() + 30 * 86400, 'path' => '/', 'secure' => true, 'samesite' => 'Lax']);
}
8. E-commerce test ideas, written as hypotheses
These are starting points, not promised results. Product-page and checkout design have their own sub-forums; the focus here is how to frame each test.- Shipping-cost messaging: because exits rise at the step where the shipping cost first appears, showing the free-shipping threshold and the remaining amount on product and cart pages will increase the conversion rate. Guardrail: margin per order; watch AOV as a secondary metric.
- Delivery date: showing an estimated delivery date ("arrives Thursday") instead of "ships in 1-3 days" will increase orders. Test it only if the date is reliable; guardrail: late-delivery complaints.
- Product page information order: for apparel, moving the size chart and the return policy above the fold will increase orders and reduce size-related returns. Primary: conversion rate; guardrail: return rate.
- Checkout steps: a guest checkout option or fewer form fields will increase completed orders. Guardrails: payment failures and fraud rate.
- Payment option order: in Türkiye, showing the instalment (taksit) table on the product page, or changing the order of card, bank transfer, cash on delivery and digital wallets, will change the checkout completion rate. Guardrails: payment costs and refused cash-on-delivery parcels.
9. Common A/B testing mistakes
| Mistake | What goes wrong | Fix |
|---|---|---|
| Stopping at the first significant result | False positives rise from 5% to about 22% with daily looks over two weeks (simulation above) | Fixed sample and duration, or a sequential method |
| No sample size estimate | Underpowered tests end "inconclusive" or crown noise | Compute n from baseline and MDE before building |
| Sessions as the unit | One shopper sees both variants; observations are not independent | Assign and analyse by user |
| Changing the split mid-test | Users switch groups; periods with different splits get mixed | Keep weights fixed, or restart |
| Picking the best of many metrics | Multiple comparisons inflate false positives | One primary metric, corrections for the rest |
| Ignoring SRM | Unbalanced groups make any result meaningless | Check the split daily; stop and fix the cause |
| Testing only during a campaign | The winner may not hold in ordinary weeks | Whole normal weeks, or a separate campaign analysis |
| A page cache in front of variants | Visitors receive the wrong variant | Variant in the cache key, or assignment at the edge |
| Leaving a finished test running | Google may treat an unnecessarily long experiment as an attempt to deceive search engines; traffic is wasted | For split URLs use 302 redirects and rel=canonical; remove the test once decided |
FAQ
How much traffic do I need for A/B testing?There is no universal minimum, so run the calculation in reverse. At a 2% baseline (alpha 0.05, 80% power), 25,000 users per variant can detect only about an 18% relative change, and 50,000 users per variant about 13%. If the effect you can realistically expect is smaller, test bolder changes or use qualitative research instead.
Can I stop the test when the tool shows 95%?
Not with a fixed-horizon test. Stopping at the first crossing inflates false positives, as the simulation above shows. Wait for the planned sample and duration, or use a method and tool designed for continuous monitoring.
A/B test or multivariate test?
A multivariate test (MVT) changes several elements at once and compares the combinations. Three elements with two versions each make eight cells; comparing each cell with control at the same power needs about four times the traffic of a two-variant test, before any multiple-comparison correction. Keep MVT for high-traffic pages.
Can I test prices legally and ethically?
Showing different prices for the same product at the same time to random customers carries legal and trust risks. In Türkiye, a discount advertisement for goods must use as its "before" price the lowest price applied in the same sales channel during the ten days before the discount starts (Ticari Reklam ve Haksız Ticari Uygulamalar Yönetmeliği, as amended in Resmî Gazete No. 33297 of 1 July 2026, in force since 1 August 2026), so a strike-through price variant must follow that rule. In the EU, the Omnibus Directive (2019/2161) requires telling consumers when a price has been personalised by automated decision-making, and it introduced a prior-price rule of at least 30 days for announced price reductions. Prefer testing how prices are presented (instalments, shipping thresholds, bundles), always charge the price you showed, and get legal advice.
What replaced Google Optimize, and what are the alternatives?
For websites, nothing built into GA4. Google points to third-party tools that integrate with Google Analytics (it named AB Tasty, Optimizely and VWO) and to its integration APIs. Open-source options include GrowthBook and PostHog, and Firebase A/B Testing covers mobile apps.
Conclusion and next steps
Most of what makes an A/B test trustworthy is settled before launch: one hypothesis, one primary metric, a sample you can reach in whole weeks and a stopping rule in writing. After launch, your job is to watch the split and the guardrails, not the p-value. Next steps:- Pull four whole weeks of data for the page you want to change, and note its baseline conversion rate and daily traffic.
- Compute the sample size for an MDE that matters to the business; if the test would run longer than about six weeks, choose a bolder change.
- Choose an implementation (client-side, server-side or feature flags) and run an A/A test to validate assignment, tracking and the SRM check.
- Write the hypothesis, metrics, guardrails and stopping rule into a shared document, then launch.
Son düzenleyen: