ข้ามไปยังเนื้อหา

Sticky Bucketing

เมื่อ GrowthBook กำหนด variation ให้กับผู้ใช้ ระบบจะใช้การแฮชแบบ deterministic จาก user ID ซึ่งหมายความว่าผู้ใช้คนเดิมจะได้รับ bucket เดิมเสมอ — ตราบเท่าที่การตั้งค่า experiment ไม่เปลี่ยนแปลง ปัญหาเกิดขึ้นเมื่อมีการเปลี่ยนแปลง

สมมติว่าคุณเริ่ม experiment ที่ traffic 100% โดยแบ่ง 50/50 ระหว่าง control กับ variant หนึ่งสัปดาห์ต่อมาคุณลด traffic เหลือ 50% เพื่อจำกัดการเปิดเผย ผู้ใช้ที่เคยอยู่ใน variant อาจหลุดออกจาก experiment ทั้งหมด หรือที่แย่กว่านั้นคือถูกย้ายไป control โดยที่ไม่รู้ตัว ส่งผลให้ข้อมูลเสียหายและประสบการณ์ของผู้ใช้ไม่สอดคล้องกัน

Sticky bucketing แก้ปัญหานี้โดยบันทึก assignment ของ variation แรกที่ผู้ใช้ได้รับ และนำกลับมาใช้ซ้ำในทุกการประเมินครั้งถัดไป ไม่ว่าการตั้งค่า experiment จะเปลี่ยนแปลงอย่างไรก็ตาม

GrowthBook เปิดให้ใช้ option stickyBucketService ในตัว constructor ของ SDK คุณเพียงระบุ storage backend — SDK มาพร้อมกับ LocalStorageStickyBucketService สำหรับ browser — แล้ว SDK จะจัดการอ่านและเขียน assignment ให้โดยอัตโนมัติ

เมื่อผู้ใช้ถูก bucket ครั้งแรก SDK จะบันทึกข้อมูลอย่างเช่น { experimentKey: "my-experiment", variationKey: "variant" } ลงใน store ในการโหลดหน้าครั้งถัดไป SDK จะอ่านข้อมูลนี้และข้ามการคำนวณแฮชทั้งหมด โดยส่งคืน variation ที่บันทึกไว้แทน

Sticky bucketing มีความสำคัญมากที่สุดในสถานการณ์เหล่านี้:

  • Experiment ที่ใช้เวลานาน — ผู้ใช้กลับมาหลายครั้งในช่วงหลายวันหรือหลายสัปดาห์ หากไม่มี sticky bucketing การแก้ไขการตั้งค่าใดๆ จะสร้างกลุ่มผู้ใช้ที่เคยเห็นทั้งสอง variation
  • การเปลี่ยน traffic split ระหว่าง experiment — การลดหรือเพิ่มเปอร์เซ็นต์ผู้ใช้ที่รวมอยู่อาจเปลี่ยนขอบเขต bucket และ re-assign ผู้ใช้เดิม
  • Gradual rollout ที่ทับซ้อนกับ experiment — หากคุณค่อยๆ เพิ่ม traffic พร้อมกับการรัน experiment ขอบเขต bucket จะเลื่อนทุกครั้งที่เพิ่ม
  • User journey ที่ข้ามหลาย session — เมื่อผู้ใช้เริ่ม funnel ใน session หนึ่งและเสร็จสิ้นใน session อื่น ความสอดคล้องระหว่าง session เป็นสิ่งสำคัญสำหรับการ attribution ที่แม่นยำ

ส่ง instance ของ stickyBucketService เมื่อสร้าง GrowthBook ตัวอย่างด้านล่างใช้ LocalStorageStickyBucketService ซึ่งบันทึก assignment ใน localStorage ของ browser

import { GrowthBook, LocalStorageStickyBucketService } from '@growthbook/growthbook';

const gb = new GrowthBook({
  apiHost: 'https://cdn.growthbook.io',
  clientKey: 'sdk-YOUR_KEY',
  stickyBucketService: new LocalStorageStickyBucketService(),
});

await gb.init({ timeout: 2000 });

// Now a user assigned to 'variant' stays in 'variant'
// even if you later reduce traffic from 100% to 50%.
const result = gb.run({
  key: 'my-experiment',
  variations: ['control', 'variant'],
});

console.log('Variation:', result.value);
ตัวเลือกBenefitCost
Sticky Bucketingผู้ใช้เห็น variation เดิมเสมอ UX consistentต้องจัดการ storage (cookie/localStorage) เพิ่ม
ไม่ sticky (recalculate ทุกครั้ง)ง่ายกว่า ไม่ต้องเก็บ stateผู้ใช้อาจเห็น variation เปลี่ยนกลางทาง
  • ไม่เปิด sticky bucketing สำหรับ experiment ที่ user เห็นผลต่อเนื่องยาวนาน (เช่น pricing) ทำให้ user เห็นราคาสลับไปมา
  • เปลี่ยน targeting attribute ระหว่าง experiment กำลังรันโดยไม่เข้าใจผลกระทบต่อ sticky assignment
  • ไม่ตั้ง storage ที่เหมาะสมสำหรับเก็บ sticky bucket ฝั่ง client

💡 ตัวอย่างจากของจริง

platform e-commerce ที่ทดสอบราคาสินค้าแบบ A/B ต้องใช้ sticky bucketing เสมอ เพื่อไม่ให้ user เดียวกันเห็นราคาต่างกันในการเข้าชมแต่ละครั้ง

Sticky bucketing แก้ปัญหาอะไร?
คุณต้องให้อะไรกับ GrowthBook SDK เพื่อเปิดใช้ sticky bucketing?
สถานการณ์ใดที่คุณต้องการ sticky bucketing มากที่สุด?