Open dataset

Thai marketplace benchmarks

Aggregated first-party measurements of Thai marketplace behaviour: what a Shopee ad click costs by hour of day, when buyers actually order by product category, how much ad-attributed conversion arrives delayed, and the platform mechanics that make those numbers read wrongly. Observational, aggregate-only, and published under CC BY 4.0.

Version
2026.08.25
Last measured
26 July 2026
Licence
CC BY 4.0
Coverage
9 panels, 8 tables, 273 figures
Open the JSON endpoint

Three things this dataset answers

Our fee dataset publishes what the platforms say about themselves. This one publishes what we measured about how they behave. Everything here is aggregate, everything is observational, and nothing here claims that anything caused anything.

What changes across the day is the auction price, not the buyer

CPM varies 2.24× and CPC 2.01× across the six windows of the day, while CTR varies 1.14× and margin 1.13×. Buyers click at roughly the same rate all day and buy products of roughly the same margin.

The paid channel was credited for a burst it did not cause

On campaign days, midnight’s share of ads-attributed orders rises 2.502× while the same shops’ all-orders share — organic included — rises 2.802×. The ads figure is the larger one in only 20.7% of shops (p = 0.00002).

The dearest hour of the day is one of the best-funded

Hour 0 costs 1.46× a shop’s own daily mean per attributed order, in 87% of shops, and absorbs 9.5% of all ad spend on the panel. Hours 20–23 are the four cheapest of the day.

How this dataset was produced

A figure derived from customer data has to say exactly what it is and what it is not. This section is not an appendix — it is part of the dataset.

  1. 1Every figure is an aggregate. There is no per-shop figure anywhere, and no shop name, shop id, campaign id or user id appears in any form.
  2. 2Any bucket — a window, a product category, a platform — backed by fewer than 8 distinct shops is suppressed rather than published with a warning.
  3. 3Panel sizes are published as bands ("80+ shops"), never as exact counts, and per-shop counts are converted to shares of the panel.
  4. 4Every figure is observational. Nothing here is the measured effect of an intervention, a counterfactual replay, or a modelled gain.
  5. 5Every table names the panel it came from, and every panel states its window, its grain, how a shop got into it, and what was excluded and why.

A figure that fails any of these is suppressed rather than softened and published. The full suppression register is at the foot of this page.

What this dataset does not tell you

No figure here says what a change would earn. The tables say what a click costs by hour and where the money currently sits. The price of moving that money between hours is not identified from observational data, and we treat that status as unmeasured. We previously held a gain figure derived from a fitted supply elasticity; a panel with a literally zero supply curve reproduces the same fitted value, so the figure was withdrawn entirely rather than reduced.

Measurement panels

Every figure on this page names one of these. Here is all of it.

Shopee intraday ad panel Shopee TH

Window
1 Dec 2025 – 16 Aug 2026
Grain
shop × hour of day, shop-local clock
Shops
80+
Measured
17 August 2026
Observations
442,496 shop-hours carrying THB 63.4M of ad spend.
Eligibility
At least 60 days of hourly ad rows, 200 clicks and 100 attributed orders in the window; then at least 5 attributed orders and 50 clicks in every one of the six day-windows.
Excluded
  • Campaign days (platform double-dates) are excluded from every pooled window table, because they invert the ranking — 88.3% of campaign-day spend falls on a Tuesday or a Saturday, so an all-days table imports both the inversion and a weekday skew.
  • An earlier 20-shop panel of the largest advertisers is excluded outright. It was measured to differ from the rest of the fleet on three of four tested properties (median best-to-worst spread 1.41× against 2.14×, Mann-Whitney p = 0.0093), so nothing computed on it is published here.

Shopee per-click and per-impression economics Shopee TH

Window
1 Feb 2026 – 16 Aug 2026
Grain
campaign × day-window, matched to the advertised product
Shops
80+
Measured
18 August 2026
Observations
9.11M of 9.21M clicks matched to a product (98.9%), across 333.9M impressions.
Eligibility
Single-product ads only. The ads fact does not carry the item id in its primary key, so a multi-item campaign dumps all of its clicks onto one arbitrary item; the filter is mandatory, not cosmetic.
Excluded
  • Margin is each campaign’s own advertised product’s realised margin, averaged over the window, and is verified to exclude ad cost — so it can be subtracted against CPC without double-counting.

Shopee order-book clock by product category Shopee TH

Window
Full Shopee order history held for the panel as at 17 Aug 2026
Grain
order line × shop-local order hour
Shops
150+
Measured
17 August 2026
Observations
4.7M order lines across 29 L1 categories. This panel is the whole order book, not only the shops that advertise.
Eligibility
Categories below 20,000 order lines are dropped, then categories below the minimum cell size of 8 distinct shops are suppressed.
Excluded
  • Category labels come from a fuzzy match against the declared commission-rate tree, not from the platform category API. Mislabelling attenuates every result toward zero, so the structure reported here is a lower bound.
  • The price-per-unit column is withheld: 318,259 bundle and free-gift lines carry a zero unit price on 100% of rows, with exposure ranging 0.02%–18.0% by category, so every category average would be understated by an unequal amount.

Shopee campaign-day panel Shopee TH

Window
9 platform double-dates against 250 ordinary days, 1 Dec 2025 – 16 Aug 2026
Grain
shop × day-window × day type
Shops
70+
Measured
17 August 2026
Observations
Shops estimable on both day types form the paired panel; the attribution comparison runs on the 50+ shops that also have an attribution-free order series for both day types.
Eligibility
A shop must have an estimable cost per attributed order in the window on both campaign days and ordinary days.
Excluded
  • The finding rests on six mid-tier February–August double-dates. 9.9 and 11.11 fall outside the window entirely, 12.12 carries only 0.34% of campaign-day spend, and 1 January is not a campaign day at all (it ranks 173rd of 259 days by spend). It therefore speaks to ordinary double-dates and not to platform mega-days, paydays or flash sales.

Shopee dark-spell panel (delayed conversion) Shopee TH

Window
1 Dec 2025 – 16 Aug 2026
Grain
campaign × hour, restricted to hours with no ad activity at all
Shops
70+
Measured
18 August 2026
Observations
1,078 campaigns and 3.62M dark campaign-hours. A dark hour is one with zero clicks, zero impressions and zero spend, observed rather than inferred: 98.09% of campaign-days carry exactly 24 rows, and the density is the platform’s own.
Eligibility
Campaigns that go dark and recorded at least one attributed order during a dark hour.
Excluded
  • The exposure denominator is the eligible click pool over the preceding 168 hours, not elapsed panel-hours. An earlier pass used panel-hours and produced a smeared survival curve rather than a delay kernel; every per-panel-hour figure is superseded.

Shopee ad configuration and platform mechanics Shopee TH

Window
Live platform reads, 7 Jul 2026 – 25 Aug 2026
Grain
campaign settings, shop toggles and ads reporting rows
Shops
60+
Measured
25 August 2026
Observations
THB 42.9M of campaign spend for the configuration mix; 180,695 attributed-GMV rows for the hour-crediting check; shop-level toggles read on 60+ shops.
Eligibility
Every shop in the intraday panel, plus the shops whose account-state toggles are ingested.
Excluded
  • These are properties of the platform, not benchmarks of seller performance. They are published because they change how every other number on this page must be read.

Shopee margin panel Shopee TH

Window
Trailing 180 days to 18 Aug 2026
Grain
order line, product model, and shop
Shops
150+
Measured
18 August 2026
Observations
2.03M order lines carrying THB 1bn+ of GMV for the hourly contribution-margin cut; 115,634 product-model rows for realised margin; 150+ shops at 92.9% COGS coverage for the net figure.
Eligibility
Order lines with a cost basis. Shops whose COGS is largely inferred rather than entered are the reason the coverage figure is published beside the margin.
Excluded
  • The three margin figures sit at three different grains (order line, product model, shop) and are not a strict arithmetic chain. They are published together because the ~11pp gap between the product-model figure and the shop net figure is the ad cost the former leaves out, and the two reconcile on that reading.

Shopee bundle-deal flag audit Shopee TH

Window
Historical bundle deals held for the panel as at 26 Jul 2026
Grain
order line × promotion tag
Shops
60+
Measured
26 July 2026
Observations
Orders that meet a live deal’s qualification threshold, compared against the orders the platform actually tags as having redeemed it.
Eligibility
Shops with at least one historical bundle deal whose qualification threshold can be evaluated from the order lines.
Excluded
  • Only the tagging rate is published. The qualification lift measured beside it is a before-and-during comparison with no control group, so it is suppressed under the no-causal-claims rule.

TikTok Shop hourly ad-reporting audit TikTok Shop TH

Window
4 Jun 2025 – 17 Aug 2026
Grain
advertiser × campaign × hour
Shops
40+
Measured
17 August 2026
Observations
1,669,959 hourly rows carrying THB 45.4M of expense, reconciled against the same accounts’ daily reporting.
Eligibility
Every TikTok Shop advertiser account connected to the panel.
Excluded
  • This panel produced no benchmarks. It is published as a negative result: the hour dimension of the source is unusable, and any intraday TikTok figure computed from it — including several we computed ourselves — is an artefact.

Tables

What a Shopee ad click costs by time of day

Ordinary days only. The first six columns are spend-weighted across the panel; the last three are equal-weighted, one vote per shop, with each window indexed to that shop’s own daily mean.

Panel:Shopee intraday ad panel · 80+ · 1 Dec 2025 – 16 Aug 2026

What a Shopee ad click costs by time of day
WindowShare of ad spendShare of clicksCPCCVRCost per attributed orderROASRelative cost per orderBest window forWorst window for
00–01 midnight14.3%9.6%THB 5.257.18%THB 738.801.2915.1%51.2%
02–07 early morning13.2%13.4%THB 3.475.64%THB 617.901.181.2%24.4%
08–11 morning20.7%20.7%THB 3.57.46%THB 4710.600.9212.8%1.2%
12–16 afternoon23.4%24.1%THB 3.397.48%THB 4511.400.8611.6%2.3%
17–19 early evening11.5%12.1%THB 3.316.84%THB 4810.400.917.0%20.9%
20–23 late evening16.9%20.2%THB 2.937.0%THB 4211.900.8052.3%0.0%

Caveats

  • The 0.0% in the bottom-right cell is a rounded count, not a proof. Block-bootstrapping days within shops puts the number of shops whose worst window is 20–23 at a mean of 2 with a 95% interval of [0, 5], against a day-multinomial null that expects 25. Quote it as “essentially no shop”, not as an exact zero.
  • The ordering survives every filter tried — none, ≥20 orders, ≥100 clicks, ≥50 orders and 200 clicks, ≥100 orders and 500 clicks: 20–23 is the worst window for no shop under all six.
  • ROAS here is Shopee’s broad attribution basis, which is multi-touch and cannot be de-duplicated, so every ROAS figure is an upper bound. CPC is spend divided by clicks and carries no attribution term, so it is invariant to the choice of basis.

The clock at hour granularity

Each shop’s hourly cost per attributed order indexed to its own daily mean, then aggregated equal-weighted. Hours that are not separable at the panel’s precision are published as a band rather than split into invented per-hour figures.

Panel:Shopee intraday ad panel · 80+ · 1 Dec 2025 – 16 Aug 2026

The clock at hour granularity
Hour of dayRelative cost per orderShare of fleet ad spend
210.764.5%
200.764.5%
230.763.5%
220.774.2%
120.815.6%
150.844.4%
190.853.9%
8–11, 13–14, 16–180.86–0.9442.7%
71.034.0%
1–61.16–1.2713.3%
01.469.5%

Caveats

  • Hour 0 is the single dearest hour of the day and absorbs 9.5% of all ad spend on the panel — more than any hour except 10 and 12.

Per-click economics by time of day

Profit per click = margin × basket value × conversion rate − CPC, using each campaign’s own advertised product’s margin. POAS is profit divided by ad spend and is the budget-constrained reading.

Panel:Shopee per-click and per-impression economics · 80+ · 1 Feb 2026 – 16 Aug 2026

Per-click economics by time of day
WindowClicksConversion rateCPCBasket valueMarginProfit per clickPOAS
00–01 midnight835k10.4%THB 6.75THB 64929.3%THB 13.012.93
02–07 early morning1.11M8.46%THB 4.45THB 45626.0%THB 5.592.25
08–11 morning1.85M10.41%THB 4.18THB 46226.7%THB 8.653.07
12–16 afternoon2.28M9.95%THB 3.96THB 48727.9%THB 9.573.42
17–19 early evening1.16M9.04%THB 3.93THB 46927.4%THB 7.712.96
20–23 late evening1.87M9.42%THB 3.36THB 46827.7%THB 8.843.63

Caveats

  • The ranking splits by metric. POAS favours 20–23 at 3.63; profit per click favours 00–01 at THB 13.01, whose POAS is fifth of six. Under a fixed ad budget — the ordinary case — the evening wins; midnight wins only if you are unconstrained.
  • No window is loss-making: the worst still returns THB 2.25 of profit per THB 1 of ad spend on this basis.
  • These are averages, not marginals. A POAS of 3.63 at 20–23 does not mean the next baht spent there returns 3.63. Nothing in this dataset prices a marginal baht.
  • The conversion side rests on broad attribution and the over-crediting is worst exactly at midnight, the platform’s checkout peak. The THB 13.01 cell is the least trustworthy number in the table.

Per-impression economics by time of day

What the auction actually allocates is impressions, not clicks. Changing basis moves exactly one pair of ranks — morning and late evening swap third and fourth, because morning’s CTR is slightly higher.

Panel:Shopee per-click and per-impression economics · 80+ · 1 Feb 2026 – 16 Aug 2026

Per-impression economics by time of day
WindowImpressionsCTRCPMProfit per 1,000 impressions
00–01 midnight28.1M2.97%THB 200.15THB 386.08
02–07 early morning39.3M2.83%THB 125.99THB 158.07
08–11 morning66.4M2.78%THB 116.33THB 240.42
12–16 afternoon85M2.68%THB 105.95THB 256.21
17–19 early evening44.5M2.61%THB 102.6THB 201.52
20–23 late evening70.6M2.65%THB 89.16THB 234.57

Caveats

  • One counter-intuitive cell: 02–07 has the second-highest CTR of the day and the worst economics of any window. People do click at night; those clicks are simply worth less and cost more than the 20–23 ones.

What actually varies across the day

Ratio of the largest to the smallest window value for each input. The two price variables move roughly twice as much as anything behavioural.

Panel:Shopee per-click and per-impression economics · 80+ · 1 Feb 2026 – 16 Aug 2026

What actually varies across the day
InputMax ÷ min across the six windowsKind
CPM2.24auction price
CPC2.01auction price
Basket value1.42buyer behaviour
Conversion rate1.23buyer behaviour
CTR1.14buyer behaviour
Margin1.13product mix

Caveats

  • Buyers click at roughly the same rate all day (2.6–3.0%) and buy products of roughly the same margin. What changes by 2.2× is what the platform charges to reach them. On this panel the intraday variation is an auction-price phenomenon, not a consumer one.
  • Margin being close to constant has a practical consequence: a shop-average margin and a per-product margin give the same window ranking, so product mix is not the lever here.

When buyers actually order, by product category

The order book, not the ad account — this table has nothing to do with advertising. Shares are of that category’s own order lines by shop-local order hour.

Panel:Shopee order-book clock by product category · 150+ · Full Shopee order history held for the panel as at 17 Aug 2026

When buyers actually order, by product category
CategoryShopsOrder linesUnits per linePeak hourPeak reproduces09–16 share20–23 share00–01 shareWeekend share
Food & Beverages30+1,745,5131.3012:0043.1%21.9%8.0%29.8%
Home & Living80+749,4281.6612:0047.2%18.3%6.3%27.8%
Beauty30+362,9941.0800:000.9939.4%22.1%12.1%29.1%
Sports & Outdoors30+305,5641.5312:0045.1%20.9%8.5%27.4%
Health20+295,0071.1112:0043.0%18.7%9.3%33.2%
Home Appliances30+244,2741.1912:0047.2%17.5%5.2%28.6%
Men Clothes10+178,9101.0800:000.9440.5%22.4%12.0%31.9%
Men Shoes20+101,4201.0412:0043.1%20.6%7.8%28.6%
Pets10+100,1531.2800:000.6239.8%22.2%10.7%33.0%
Mobile & Gadgets10+87,7151.0400:000.7142.7%22.0%11.1%26.8%
Travel & Luggage10+83,2351.0300:000.6839.6%25.0%11.3%34.8%
Hobbies & Collections10+54,9121.5612:0046.8%21.6%5.7%30.3%
Cameras & Drones10+51,5441.0500:000.9043.1%21.4%11.3%26.1%
Automobiles8+38,7741.8912:0045.1%17.2%5.9%29.4%
Stationery20+36,2753.2412:0049.3%17.4%8.2%26.6%
Computers & Accessories10+32,1671.0812:0050.6%17.0%9.2%29.8%
Women Shoes10+27,3281.1412:0043.5%20.8%7.8%29.4%
Spare Parts & Accessories20+20,6581.7511:0051.3%16.9%5.6%28.8%

Caveats

  • Read the two families as point estimates, not as an established taxonomy. Under a shop-cluster bootstrap only one of the midnight-peaking categories reproduces its peak hour at 0.95 or better; two are borderline and three are close to coin-flips. The “peak reproduces” column carries that probability, and is blank where it was not computed.
  • What does survive the same bootstrap is the evening gradient: the 20–23 share spans 16.9% to 25.0% across categories, a spread of 8.0 percentage points that exceeds the widest shop-clustered confidence interval of ±4.66.
  • A category’s buyers peaking at midnight does not make midnight a good hour to advertise in. Cost per click is set by every advertiser competing in that hour, not by that category’s own buyers — and the first principal component of the shop × hour CPC matrix explains 60.8% of its variance, i.e. the hourly price is substantially a common factor.

Campaign days invert the clock

Paired per shop across the panel: the same shops measured on platform double-dates and on ordinary days.

Panel:Shopee campaign-day panel · 70+ · 9 platform double-dates against 250 ordinary days, 1 Dec 2025 – 16 Aug 2026

Campaign days invert the clock
MeasureCampaign daysOrdinary daysPaired test
Midnight’s rank among the six windows (1 = cheapest)3.06.0Wilcoxon p = 8.5e−10
Share of shops where midnight is the worst window20.8%62.5%
Share of shops where midnight is the best window33.3%5.6%31.9% under a strict rank rule
Median midnight share of the day’s ad spend22.2%12.6%p = 3.3e−12
Midnight cost per order relative to the shop’s own day-type mean0.9471.488p = 8.9e−10
Midnight CPC ÷ the other windows’ CPC on the same day1.5421.402higher on campaign days in 69% of shops, p < 0.0001

Caveats

  • The statistic survives leave-one-day-out, leave-one-shop-out, a Poisson thin-cell placebo and conditioning on midnight spend share. The largest single shop contributes 3.8% of the total movement, so it is not one seller’s clock.
  • Midnight clicks on a campaign day are dearer, not cheaper. The entire cost-per-order improvement comes from conversion — and see the attribution result below for why that conversion is not the advertiser’s to claim.

Where the margin goes

Three margin figures at three grains. They are not a strict arithmetic chain, but the roughly 11-point gap between the second and third is the ad cost the second leaves out.

Panel:Shopee margin panel · 150+ · Trailing 180 days to 18 Aug 2026

Where the margin goes
MeasureGrainValue
Contribution margin, (revenue − COGS) ÷ revenue, before platform feesOrder line53.3–56.1%
Realised margin, after platform fees, before ad costProduct model28.5%
Net margin, after platform fees and ad costShop, trailing 180 days17.3%

Caveats

  • The contribution-margin row is a range because it is the spread across the 24 hours of the day, and that is the point of publishing it: gross margin varies by 2.8 percentage points across the entire day, with midnight the highest, not the lowest. Midnight’s larger baskets are not lower-margin baskets.
  • The net figure carries a COGS coverage of 92.9%. On shops whose cost basis is largely inferred rather than entered, a margin is a modelled quantity and not a measured one.

Standalone findings

Figures that are not naturally a table row. Each names its panel and carries its own limits.

  1. The paid channel captured LESS of the midnight burst than the order book did

    2.502 against 2.802

    Median lift in midnight’s share of the day, campaign days divided by ordinary days, measured two ways on the same shops: 2.502 counting only ads-attributed orders, and 2.802 counting all live orders including organic. The ads figure exceeds the attribution-free figure in only 20.7% of the panel, paired Wilcoxon p = 0.00002. The paid channel rode a burst it did not cause, and was credited for it.

    • This is a comparison of two observed series, not an experiment. It bounds how much of a demand-peak hour the attributed series can honestly claim; it does not measure the incremental effect of the ads.
    • The mechanism is the platform’s, not the seller’s: a double-date sale opens at 00:00 and buyers check out carts assembled beforehand.

    Panel:Shopee campaign-day panel · 70+

  2. Almost all ad-attributed conversion lands in the click’s own hour

    ≈97% same hour; 2.9–3.3% delayed

    Estimated in dark spells — campaign-hours with zero clicks, zero impressions and zero spend — where an attributed order can only have come from an earlier click, so within-day co-movement cannot masquerade as a delay. The delayed tail exceeds an exposure-exact permutation null by 0.0019–0.0022 with a contrast of 3.26× to 5.25× and an empirical p of 0.0000; the range on the headline share is the two defensible conventions for handling gap rows.

    • This is a fact about the platform’s attribution system, not about buyers. The outcome is the platform’s own attributed-order column, and no order-to-campaign link exists, so human deferral is not observable here at all.
    • It is a no-interference upper bound. While a campaign is live, a delayed conversion from an old click is liable to be re-credited to a newer click. State it as “for campaigns that go dark, measured in no-interference windows”, never as a fleet-wide delayed share.

    Panel:Shopee dark-spell panel (delayed conversion) · 70+

  3. The midnight CPC premium is near-universal

    1.46× in 87% of shops

    Hour 0 is the dearest hour of the day on the panel, at a median 1.46× the evening rate, and the premium holds in 87% of shops. The pooled best-to-worst cost-per-order ratio across the six windows is 1.75×.

    Panel:Shopee intraday ad panel · 80+

  4. The clock does not vary by day of the week

    20–23 best on 7 of 7 weekdays

    On ordinary days, 20–23 is the cheapest window on all seven weekdays and 00–01 the dearest on all seven. The best-to-worst spread by weekday runs 1.74× (Monday) to 2.14× (Sunday). At shop grain the weekday argmax is still noise — a shop’s best window is identical on all seven weekdays in about one in nine shops — so a weekday-varying schedule is not supported by this panel.

    Panel:Shopee intraday ad panel · 80+

  5. “Dear clicks convert worse” is not the pattern

    median ρ = +0.263, negative in 38% of shops

    Spearman correlation of CPC against CVR across the 24 hours of each shop. The median is positive: dear hours more often convert better, so paying up is more often right than wrong. But it is weak and it reverses in more than a third of shops, which is why it works as a per-shop diagnostic and not as a rule.

    Panel:Shopee intraday ad panel · 80+

  6. Most shops spend more in their own dearest hours than in their own cheapest

    26.4% vs 22.5% of budget; 63% of shops

    Median share of a shop’s ad budget landing in its own six dearest hours is 26.4%, against 22.5% in its own six cheapest. 63% of shops spend more in their dearest six than in their cheapest six, paired Wilcoxon p = 0.002, and the median dearest-to-cheapest cost-per-order ratio is 2.07×.

    • This is a statement about where the money currently sits, and nothing more. It is NOT a statement about what moving that money would earn. The price of moving budget between hours is not identified on this panel, so no gain figure follows from this line and none is published anywhere in this dataset.

    Panel:Shopee intraday ad panel · 80+

  7. Two categories inside one shop order at measurably different times

    2.61× the sampling-noise null

    Total-variation distance between two categories’ hourly order profiles inside the same shop: median 0.0735 observed against 0.0354 under a multinomial null drawing both categories from that shop’s own hourly distribution. Every testable shop reaches p < 0.05; Wilcoxon p = 4.8e−07. Two categories in one shop differ by about 7.4% of probability mass in when their orders arrive, and for scale two random shops differ by 10.4% — so the shop effect is only 1.4× the category effect.

    • The order clock and the bidding clock are different objects. The same panel finds no detectable category difference in the bidding clock at shop grain: every between-shop test statistic sits essentially at its label-permutation null.

    Panel:Shopee order-book clock by product category · 150+

  8. What separates the daytime categories from the evening ones is basket structure, not price

    units per line ρ = −0.542; price per unit ρ = +0.172

    The intuitive story — cheap impulse buys at night, expensive considered purchases by day — does not hold. Price per unit spans a 33× range across the categories published here with no relationship to the evening share (ρ = +0.172, p = 0.48); the most expensive category has the highest evening share. Units per line is the one significant correlate (ρ = −0.542, p = 0.017; shop-cluster bootstrap 95% CI [−0.727, −0.289]). Categories bought in multiples skew to the working day; categories bought one at a time skew to the evening and midnight.

    • Four separators were tested, so the p of 0.017 survives a Bonferroni correction across them only marginally. Treat it as a strong lead rather than a settled separator, and note that the reading “restocking versus wanting” is our interpretation, not a measurement.

    Panel:Shopee order-book clock by product category · 150+

Platform mechanics

These are not benchmarks of seller performance. They are properties of the platforms themselves, established by reading their reporting and their APIs directly, and they are published because they change how every other number on this page must be read.

  1. Shopee TH

    Shopee credits a conversion to the hour the ORDER is placed, not the hour of the click

    The seven-day attribution window is an eligibility window, not a timing one: a click on day t followed by a purchase on t+4 lands entirely on t+4. A past hour’s ad metrics therefore do not grow later as conversions arrive. The practical consequence is that in any hour where the platform concentrates checkout, ads-attributed orders spike and cost per attributed order falls — and the hour looks like the best money the seller spent, whether or not the ads did anything.

    Evidence: 100% of attributed-GMV rows checked (180,695 rows across every broad-attributed hour on the audited shops) sit in an hour that also carries a shop order in that same shop-local hour.

  2. Shopee TH

    Shopee’s broad attribution is multi-touch and cannot be de-duplicated

    Broad credits any purchase within seven days of a click to every campaign the buyer touched. It over-counts distinct orders by roughly 1.1× to 2.9×, and because ads reporting carries no order key anywhere, the duplication cannot be removed from campaign aggregates. Any ROAS computed on this basis is an upper bound. Spend, by contrast, is exact.

    Evidence: Audited on production shops against the order tables; the over-count range is measured, and the absence of an order key is a property of the reporting surface itself.

  3. Shopee TH

    A Shopee daily budget of 0 means UNLIMITED, not “off”

    The legal domain of a daily-budget write is {0} ∪ [100, ∞) in THB, and 0 is a trap: it removes the cap rather than the campaign. Anything strictly between 0 and the 100 THB platform minimum is rejected outright with a range error, so a 40 THB budget is not a small budget — it is an API error. “Stop spending” has no budget representation at all; the only way to express it is a pause.

    Evidence: Established against the live campaign API, including the specific rejection error returned for the (0, 100) interval, and confirmed by a production incident in which a “stop this campaign” push written as a budget of 0 let the campaign run uncapped.

  4. Shopee TH

    An accepted daily budget is a floor, not a cap

    On a shop with Campaign Surge enabled, Shopee raises a campaign’s daily budget by 20% each time the campaign exhausts it, up to five times — a hard ceiling of 1.2⁵ = 2.48832× the number the seller wrote. A second family exists at 30% a step, 1.3⁵ = 3.71293×. The toggle is shop-level and is distinct from wallet auto-recharge, which never touches a campaign budget.

    Evidence: Read from the shop toggle endpoint and measured against realised spend. The toggle is enabled on roughly six in ten of the 60+ shops whose account state we ingest.

  5. Shopee TH

    Shopee stores a daily budget at coarser precision than you send it

    A fractional budget is a number you can send but can never read back unchanged. Anything that pushes a budget and then reads the campaign back to confirm the write will see its own fractional intent against the platform’s rounded copy, and an exact-equality check will call that difference drift on a write that in fact succeeded.

    Evidence: Measured on a live campaign write: a budget pushed with four decimal places was stored rounded to two, and the read-back returned the platform’s rounded copy rather than the value sent.

  6. Shopee TH

    Thai Shopee ad spend is almost entirely auto-bid, all-placement

    99.4% of campaign spend on the panel is auto-bidding and 99.6% is all-placement. This is a product constraint rather than a fleet preference: sellers cannot set a CPC bid any more. The steering lever that remains is a target ROAS, which 86.7% of spend carries.

    Evidence: THB 42.9M of campaign spend across the intraday panel, read from campaign settings.

  7. Shopee TH

    Shopee’s bundle-deal redemption flag tags only about a third of qualifying orders

    The flag marks about 33% of the orders that actually meet a deal’s qualification threshold. Comparing a units-based baseline against a flag-based during-rate therefore makes a bundle deal look as though it reduced qualification. Measure both sides in units, or the sign of the comparison flips.

    Evidence: Historical deals across 60+ shops, comparing orders that meet the threshold against orders the platform tags as redeemed.

  8. TikTok Shop TH

    TikTok Shop hourly ad reporting cannot support intraday analysis

    Two independent defects, either of which alone is disqualifying. Clicks are zero on all 1,669,959 hourly rows, although the sibling daily table carries 3.3M clicks over the same period — so CPC and CVR are simply unavailable at hour grain. And 94.1% of all expense is stamped at hour 0, while hours 17–23 carry 0.0% of spend and 5.2% of attributed orders. Seven consecutive hours cannot produce orders on zero spend: the hour dimension is not a real clock. Lazada publishes no hourly ad fact at all, so the cross-platform question cannot be answered there either.

    Evidence: The tell is row concentration: TikTok’s hour-0 row count is 10.80× the median hour, against 1.01× for the equivalent Shopee table, whose every hour carries the same row count and whose spend concentration at hour 0 is 9.4%. The TikTok daily totals are correct — hourly expense reconciles to daily at exactly 1.000 per shop-day — so the table is safe at day grain and unsafe at hour grain.

Definitions and arithmetic

This section is definitions, not measurements — but you need it to read the tables correctly.

Raw ROAS overstates profit-adjusted ROAS by roughly 1 ÷ margin
Profit-adjusted ROAS is margin × realised ROAS − 1, so it is centred on zero rather than on one and break-even sits at a realised ROAS of 1 ÷ margin. At a 20% margin that is 5.0: a campaign reading a raw ROAS of 4.0 is losing money on ads, at a profit-adjusted −0.2. This is an identity, not a measurement — but it is the arithmetic that decides whether any ROAS figure in this dataset means what a reader assumes it means.
Attributed order
An order the platform credited to an ad campaign, stamped at the hour the order was placed. It is not a count of orders the ad caused, and on the broad basis it is not even a count of distinct orders.
Day-window
The six blocks the day is cut into throughout this dataset: 00–01, 02–07, 08–11, 12–16, 17–19 and 20–23, on the shop’s own local clock. Hours are inclusive at both ends.
Ordinary day
Any day that is not a platform double-date campaign day. Every pooled window table in this dataset is computed on ordinary days only.

What we hold and did not publish

A dataset that shows only what survived is not auditable. Every item below is a figure we hold and chose not to publish, with the reason.

  1. Every reallocation gain from moving ad budget between hours

    Reason: The gain is a pure function of a supply elasticity that is not identified. The fitted value turned out to be the share of spend variance that is price variance, and a panel with a literally zero supply curve reproduces it; alternative estimators disagree in sign. Across the plausible estimator range the implied gain spans roughly +3% to +110%, so no point on that curve may be quoted. The internal status is UNMEASURED and only a randomised paced-release test settles it.

  2. Every within-model counterfactual and shadow-mode replay result

    Reason: We hold a number of headline-looking percentage improvements from model bake-offs and replays. Not one of them is an observed production outcome; each is a comparison of one model’s prediction against another’s on historical data, and our own notes label them as not causal. Publishing them as marketplace benchmarks would be dishonest whatever the disclaimer said.

  3. Every per-shop result, worked case and named example

    Reason: Rule 1 of this dataset. The underlying research is full of single-shop worked cases with their own tables; none of them appears here in any form, including as an anonymised illustration, because a shop with a distinctive spend pattern is identifiable from its own numbers.

  4. Everything computed on the 20 largest advertisers

    Reason: That panel was measured to be unrepresentative on three of four tested properties — the largest advertisers have the LEAST intraday variation, not the most. Every fleet claim on this page is recomputed on the full eligible population instead.

  5. The evening spend-to-order pass-through slope

    Reason: A cross-sectional slope relating a shop’s evening spend share to its evening order share. It is descriptive, but its only use is to price a reallocation, and a reader would reasonably take it as the return on moving budget into the evening. It is not that, so it is withheld.

  6. The bundle-deal qualification lift

    Reason: A before-and-during comparison on historical deals with no control group. Only the platform’s flag under-tagging rate — which is a property of the platform and not an outcome — is published from that panel.

  7. Product categories backed by fewer than 8 distinct shops

    Reason: One L1 category clears the 20,000-order-line floor but sits below the minimum cell size, so its row is withheld entirely rather than shown with a warning. Several published categories are carried by 8 to 15 shops and their rows are therefore partly a handful of sellers’ clocks; the shop band beside each row is there so a reader can weight it accordingly.

  8. Price per unit by product category

    Reason: Known to be understated by an unequal amount across categories, because bundle and free-gift lines carry a zero unit price on 100% of rows and their share ranges 0.02% to 18.0% by category. The null result that price does not separate the clock is published; the level figures are not.

  9. The shape of the delayed-conversion tail beyond its headline share

    Reason: The share of the delayed tail arriving within 24 hours is reported against two different mechanical floors in two places in our own notes, and we have not reconciled them. Only the headline same-hour share, which is stable across both gap conventions, is published.

  10. The minimum viable daily budget below which a campaign stops pacing

    Reason: We operate a delivery floor as a constraint on our own solvers, but it is an operating rule with an asserted rationale, not a measurement from any panel here — and in the one place it was tested against a re-solve it bound on nothing. A rule we impose is not an observation of the marketplace, so it does not belong in this dataset.

Change log

Every change to the dataset, newest first. The same list is the changeLog key in the JSON.

  1. 25 August 2026

    First publication. Nine measurement panels, five aggregate tables, eight standalone findings and eight platform mechanics, with the suppression register.

Licence and citation

This dataset is published under the Creative Commons Attribution 4.0 International licence (CC BY 4.0). You may reuse, adapt and redistribute it, including commercially, as long as you give credit. Creative Commons Attribution 4.0 International

Attribution string we ask you to use

DataGlass Marketplace Benchmarks (Thailand), v2026.08.25, DataGlass Labs, https://www.dataglasslabs.com/research/marketplace-benchmarks, CC BY 4.0

JSON endpoint

Served as application/json with Access-Control-Allow-Origin set to *, so it can be fetched straight from a browser. The X-Dataset-Version header lets you detect a change with a HEAD request instead of pulling the whole body, and the payload carries a disclosure block so the conditions above travel with the data.

curl -s https://www.dataglasslabs.com/api/marketplace-benchmarks.json

The companion dataset

The Thai marketplace fee dataset publishes the rates the platforms announce themselves, and deliberately contains nothing derived from DataGlass customer accounts. This page is that missing half.

Open the fee dataset

Stop guessing. Start deploying.

Join the sellers using DataGlass to turn shop data into the next profit-maximizing action.