Quay lại blog
14 tháng 8, 2026Sergei Solod14 phút đọc

Những gì tôi học được khi thử tần suất popunder so với mức độ tương tác của người dùng

Tôi tăng tần suất popunder trên một ứng dụng web đang chạy thật và so sánh engagement tổng hợp trước và sau thay đổi. Cuối cùng tôi giữ độ trễ ban đầu 45 giây và cooldown tối thiểu bốn phút, nhưng bài học quan trọng hơn là một mức engagement trung bình có vẻ ổn định cần được diễn giải thận trọng đến mức nào.

popundergiới hạn tần suấtkiếm tiền từ webmức độ tương tác người dùngphân tích web

Ban đầu tôi nghĩ trade-off của tần suất popunder sẽ rất rõ: hiển thị ít quảng cáo hơn để giữ trải nghiệm người dùng, hoặc hiển thị thường xuyên hơn để tăng doanh thu cho đến khi engagement bắt đầu giảm. Trong production, mối quan hệ không gọn gàng như vậy.

Sau khi tăng tần suất trên một ứng dụng web đang chạy thật, tôi kỳ vọng dữ liệu engagement sẽ có một điểm gãy rõ ràng. Thay vào đó, metric tổng hợp tiếp tục dao động gần như trong phạm vi hàng ngày quen thuộc. Có ngày tốt hơn, có ngày kém hơn, nhưng tôi không thấy một mức giảm rõ ràng và kéo dài bắt đầu cùng chính sách mới.

Cuối cùng tôi giữ cấu hình này:

Độ trễ ban đầu: 45 giây
Cooldown tối thiểu sau một popunder thành công: 4 phút

Tôi cũng giữ một frequency window cho phép tối đa một event thành công trong cùng khoảng bốn phút:

const policy = {
  initialDelaySeconds: 45,
  cooldownSeconds: 240,
  windowSeconds: 240,
  maxEventsPerWindow: 1,
};

Đây là pseudocode minh họa, cố ý không phụ thuộc vào nhà cung cấp quảng cáo, SDK, ứng dụng hay deployment cụ thể. Phần đáng quan tâm hơn không phải implementation mà là policy phía sau nó.

Thực tế có hai quyết định về tần suất

Lúc đầu tôi coi vấn đề là một câu hỏi: nên có bao nhiêu phút giữa hai popunder? Sau đó tôi nhận ra đó là abstraction sai. Có ít nhất hai quyết định: độ trễ trước cơ hội quảng cáo đầu tiên và khoảng tối thiểu trước các cơ hội tiếp theo.

Hai thời điểm này không giống nhau. Người mới chưa quyết định sản phẩm có hữu ích không; người đã engaged thì phần lớn đã quyết định. Vì vậy tôi cho rằng interruption đầu tiên cần được bảo vệ nhiều hơn những lần sau.

Vì sao tôi ngừng monetize quá mạnh trong những giây đầu tiên

Initial delay ngắn hơn làm nhiều visitor trở nên eligible sớm hơn, từ đó tạo thêm ad event tiềm năng. Về cơ học, điều đó đúng. Nhưng nó bỏ qua thời điểm monetization xảy ra.

Nếu quảng cáo xuất hiện gần như ngay sau khi người dùng vào, nó trở thành một phần của đánh giá đầu tiên về website. Nếu họ có một khoảng thời gian không bị gián đoạn để hiểu và sử dụng sản phẩm trước, cùng một cơ chế quảng cáo sẽ xuất hiện trong bối cảnh khác.

Trước đây tôi dùng delay ngắn hơn, sau đó chuyển sang 45 giây. Con số này vẫn khá sớm và không nhằm tạo một cấu hình bảo thủ. Nó đơn giản tách phần đầu của visit khỏi cơ hội monetization đầu tiên. Tôi bắt đầu xem 45 giây đó là thời gian để sản phẩm chứng minh giá trị, không phải inventory quảng cáo bị mất.

45 giây là một ngưỡng, không phải thời điểm quảng cáo được lên lịch

Hết delay chỉ có nghĩa người dùng trở nên eligible; không có nghĩa quảng cáo tự động xuất hiện đúng 00:45. Event thực tế vẫn phụ thuộc vào một interaction phù hợp. Người dùng có thể eligible lúc 00:45 và popunder đầu tiên chỉ xảy ra lúc 01:03 sau action phù hợp tiếp theo.

Cooldown cũng vậy. Bốn phút nghĩa là event tiếp theo không thể eligible trước khi đủ bốn phút kể từ event thành công trước đó. Không có nghĩa quảng cáo tự động xuất hiện bốn phút một lần. Vì thế các khoảng cấu hình là mức tối thiểu; khoảng thực tế có thể dài hơn.

Khoảng lặp quan trọng hơn độ trễ đầu tiên

Sau khi đã hài lòng với delay đầu tiên, repeat cadence trở thành biến quan trọng hơn. Cooldown dài giảm áp lực quảng cáo nhưng cũng có thể khiến nhiều engaged user không bao giờ tạo được cơ hội thứ hai.

Tôi muốn đồng thời đạt hai điều kiện: người tiếp tục sử dụng ứng dụng phải có cơ hội thực tế tạo ra một monetization event khác, và giữa các event vẫn phải có những đoạn sử dụng không bị gián đoạn đủ dài và có ý nghĩa.

Tôi giữ bốn phút. Với initial delay 45 giây, các điểm eligibility sớm nhất về lý thuyết là khoảng 00:45, 04:45, 08:45 và 12:45. Event thực tế có thể xảy ra muộn hơn vì vẫn cần qualifying interaction.

Vì sao bốn phút khác với việc chỉ tối đa hóa impressions

Giảm cooldown tạo thêm cơ hội về lý thuyết. Nếu metric duy nhất là số cơ hội quảng cáo trên mỗi user, khoảng ngắn hơn rõ ràng tốt hơn. Nhưng sản phẩm chỉ có giá trị quảng cáo chừng nào nó vẫn có giá trị đối với người dùng.

monetization bổ sung
-
tổn hại hành vi
=
giá trị ròng

Bốn phút tạo ra một khoảng sử dụng sản phẩm bình thường đủ dài mà popunder khác không thể xuất hiện. Invariant này quan trọng với tôi hơn câu “một lần mỗi bốn phút”.

Sau một monetization event, người dùng có vài phút mà một event tương tự khác không thể xảy ra.

Tôi đã kỳ vọng engagement giảm rõ rệt

Trước deployment, giả thuyết chính của tôi là tần suất quảng cáo cao hơn sẽ tạo ra before-and-after drop rõ trong analytics. Nếu điều đó xảy ra, tôi sẽ có lý do mạnh để giảm độ aggressive của policy.

Thay vào đó, aggregate engagement tiếp tục dao động gần giống trước. Tôi không thấy baseline mới thấp hơn hay một chuỗi giá trị yếu kéo dài sau khi tăng tần suất. Failure mode mà tôi nghĩ đủ lớn để nhìn thấy đã không xuất hiện rõ.

Tôi thực sự có thể tuyên bố điều gì

Tôi không thể nói quảng cáo hoàn toàn không có tác động, user không khó chịu, retention giữ nguyên tuyệt đối hoặc cấu hình này là tối ưu trên mọi sản phẩm. Aggregate average không chứng minh được những điều đó.

Phát biểu mạnh nhất được dữ liệu của tôi hỗ trợ hẹp hơn nhiều:

Sau khi tăng tần suất, tôi không quan sát thấy mức giảm aggregate engagement rõ ràng và kéo dài vượt ra ngoài biến động thông thường đã tồn tại từ trước.

Cách nói này vẫn để ngỏ các tác động nhỏ hơn, khác biệt giữa các nhóm người dùng và hành vi bị một average đơn lẻ che khuất. Tôi kiểm tra xem cấu hình có đủ chấp nhận được để giữ lại hay không, chứ không chứng minh rằng đã tìm thấy global optimum.

Một average ổn định có thể che giấu những hành vi rất khác

Aggregate average gần như không đổi có thể tương ứng với nhiều thực tế. Gần như mọi người có thể hành xử giống nhau; một số người có thể rời đi sớm hơn trong khi nhóm khác ở lâu hơn; một nhóm nhỏ có thể phản ứng tiêu cực nhưng chưa đủ lớn để kéo average xuống; hoặc tác động âm thật sự có thể nhỏ hơn biến động hàng ngày bình thường.

Vì thế tôi coi average ổn định là một tín hiệu cảnh báo hữu ích, không phải bằng chứng về zero impact.

Engagement không đồng nghĩa với thời lượng visit theo nghĩa đen

Tôi cũng tránh coi analytics engagement metric là thời lượng trung bình chính xác của session. Active engagement phụ thuộc vào định nghĩa của hệ thống analytics và không nhất thiết bằng tổng thời gian tab được mở. Người dùng đổi focus, quay lại sau hoặc điều hướng theo cách khiến mô hình đơn giản “time on site” trở nên sai lệch.

Do đó tôi không lấy interval quảng cáo từ công thức kiểu “average engagement là X, vậy popunder tiếp theo phải xảy ra trước X”. Tôi dùng metric theo hướng: sau thay đổi, sản phẩm có trông yếu đi đáng kể không? Ở aggregate level tôi theo dõi, câu trả lời là không.

Cooldown và frequency window liên quan nhưng không giống nhau

Implementation sử dụng cả cooldown 240 giây lẫn window 240 giây với tối đa một successful event. Phần lớn chúng redundant, nhưng biểu diễn constraint hơi khác nhau.

Cooldown nói không cho event mới xảy ra cho đến khi đủ thời gian từ event trước. Window nói không cho quá một successful event trong một khoảng xác định. Tôi giữ cả hai để invariant chính vẫn rõ ràng kể cả khi integration diễn giải một mechanism khác đi.

Hai successful popunder không bao giờ được xảy ra cách nhau ít hơn bốn phút.

Một event mỗi window không có nghĩa một event mỗi visit

Giá trị như maxEventsPerWindow = 1 không có nghĩa chỉ một quảng cáo trong toàn bộ thời gian visitor ở website. Scope của nó là window đã cấu hình; khi window hết, window khác có thể bắt đầu. 1 cũng không đại diện cho một user action mà là một successful monetization event trong khoảng đó.

Bây giờ mỗi khi review frequency logic, tôi hỏi ba câu: counter đếm gì, cái gì reset nó, và reset window dài bao lâu? Không có ba câu trả lời này thì raw value như 1 gần như vô nghĩa.

Tôi tách policy khỏi implementation riêng của provider

Hành vi cần tái sử dụng có thể được diễn đạt mà không lộ script, identifier hay parameter name của vendor:

function isEligible(state, now) {
  if (!state.hasShownFirstEvent) {
    return now - state.arrivalTime >= 45_000;
  }

  return now - state.lastEventTime >= 240_000;
}

Đây là pseudocode giải thích, không phải production source code. Provider, SDK và deployment architecture có thể thay đổi; policy bền hơn: bảo vệ phần đầu visit, cho phép monetization sau khi người dùng thực sự bắt đầu sử dụng, áp hard cooldown rồi mới lặp lại.

Build thành công và hành vi đúng là hai chuyện khác nhau

Typechecker, linter và production build có thể kiểm tra nhiều thuộc tính kỹ thuật, nhưng không chứng minh advertising timeline hoạt động đúng trong browser. Feature này cần cả behavioral validation.

1. Mở browser ở trạng thái sạch.
2. Interact trước khi initial delay kết thúc: không được có popunder.
3. Chờ qua initial delay.
4. Thực hiện eligible interaction: popunder đầu tiên có thể xảy ra.
5. Tiếp tục interact trước khi cooldown hết: không được có popunder thứ hai.
6. Chờ cooldown hết.
7. Interact lại: bây giờ popunder tiếp theo có thể xảy ra.

Successful build và successful behavioral test trả lời hai câu hỏi khác nhau. Cả hai đều cần.

Trải nghiệm quảng cáo tổng hợp quan trọng hơn từng placement riêng lẻ

Hai hệ thống quảng cáo độc lập có thể trông hợp lý khi xem riêng nhưng trở nên aggressive khi kết hợp. Hai format đều có limit bốn phút có thể xen kẽ để tạo interruption vào khoảng 00:45, 02:45, 04:45 và 06:45.

Điều này dẫn tôi đến một nguyên tắc tốt hơn:

Frequency cap nên được đánh giá theo trải nghiệm tổng thể của user, không phải theo từng advertising script.

Người dùng trải nghiệm tổng số interruption chứ không quan tâm file cấu hình nào tạo ra từng cái. Production audit vì thế nên hỏi trong một khoảng thời gian, một user thực tế có thể gặp bao nhiêu interruptive ad event.

Raw impression count là mục tiêu tối ưu hóa sai

Tạo thêm cơ hội bằng cách giảm cooldown là dễ. Câu hỏi khó là có thể lấy thêm bao nhiêu monetization mà không làm giảm tổng economic value của user.

Một configuration với ít ads hơn mỗi visit vẫn có thể tạo nhiều revenue hơn theo thời gian nếu giữ được repeat usage tốt hơn. Vì vậy tôi quan tâm revenue per user over time hơn impressions per visit. Cái thứ hai dễ maximize; cái đầu mới là business problem thật.

Experiment mạnh hơn phải nhìn vượt ra ngoài một aggregate graph

Production observation của tôi đủ để thấy catastrophic outcome tôi lo ngại không xảy ra một cách rõ ràng. Nhưng nó chưa đủ để xác định mọi downstream effect.

Một experiment mạnh hơn nên so sánh monetization revenue per unique user, revenue per visit, ad event per user, active engagement, interaction có ý nghĩa trong product, returning-user rate, retention theo thời gian và user value dài hạn.

Phải đo cả hai phía. Nếu chỉ đo advertising output, tôi gần như chắc chắn sẽ kết luận rằng nhiều quảng cáo hơn là tốt hơn. Nếu chỉ đo engagement, tôi có thể bỏ qua revenue gain đáng kể với behavioral cost rất thấp.

Vì sao tôi giữ policy đơn giản

Tôi không thấy lý do để thêm ngày càng nhiều exception. Final logic vẫn dễ giải thích: chờ 45 giây, monetize ở eligible interaction tiếp theo, áp hard cooldown bốn phút, rồi cho phép monetize ở eligible interaction tiếp theo sau đó.

Một số ít invariant mạnh dễ hiểu, test và debug hơn policy dựa vào nhiều ngoại lệ khó thấy.

Sự bất đối xứng là có chủ đích

Policy đối xử khác nhau với user mới và engaged user. Visitor mới được bảo vệ nhiều hơn; user tiếp tục interaction tạo thêm monetization opportunity theo thời gian.

Như vậy advertising pressure tăng cùng demonstrated engagement thay vì áp mức tối đa ngay từ đầu. Đây là một trong những thay đổi quan niệm hữu ích nhất từ experiment.

Những điều tôi sẽ không kết luận từ case study này

Tôi sẽ không nói 45 giây đúng cho mọi sản phẩm, bốn phút là optimal interval, higher-frequency popunder không bao giờ làm hại engagement, hoặc average ổn định nghĩa là user không bị ảnh hưởng. Tôi cũng không generalize một production workload cho mọi web product.

Mỗi product có user, kỳ vọng, acquisition source, usage pattern và economics khác nhau. Kết quả này có giá trị chính vì nó cụ thể, không phải vì nó chứng minh một quy luật chung.

Điều đã làm tôi thay đổi quan điểm

Trước experiment, tôi hình dung quan hệ giữa advertising pressure và engagement gần như cơ học: tăng một bên đủ mạnh thì bên kia phải giảm thấy rõ. Production behavior không gọn gàng như vậy.

Tôi tăng frequency tới mức mà bản thân xem là tương đối cao. User vẫn tiếp tục interaction và aggregate engagement vẫn nằm trong range hàng ngày quen thuộc. Điều đó không có nghĩa cost bằng 0. Nó chỉ có nghĩa cost không đủ lớn để tạo ra signal rõ ràng tôi kỳ vọng trong metric đang theo dõi.

Khác biệt giữa “không có effect” và “không có effect rõ trong phép đo này” rất quan trọng. Production system hiếm khi cho chúng ta causal story sạch sẽ như mong muốn.

Nguyên tắc của tôi bây giờ

Tôi không còn hỏi về mặt kỹ thuật có thể hiển thị popunder tiếp theo thường xuyên đến đâu. Tôi hỏi user mới nên có bao nhiêu thời gian sử dụng sản phẩm không bị gián đoạn trước khi monetization bắt đầu, engaged user nên có bao nhiêu thời gian sử dụng không bị gián đoạn trước event tiếp theo, và quảng cáo bổ sung có tăng total user value hay chỉ tăng impression counter.

Với ứng dụng này, tôi giữ:

45 giây trước eligibility đầu tiên
ít nhất 4 phút giữa các successful event

Các con số cụ thể chỉ là một implementation. Nguyên tắc tôi sẽ tái sử dụng rộng hơn:

Bảo vệ phần đầu user journey, monetize demonstrated engagement mạnh hơn initial curiosity, và đánh giá kết quả theo user-level value thay vì raw advertising volume.