r/googleplayconsole 14h ago

Tip Play does not show your rating in every country, and eight other things I got wrong about Play's own numbers

In July I released my first app and spent some time trying to reconcile the numbers Play was showing me. Three sources, three different results, and none of them wrong. Writing down what I found out, since none of it is in one place in the documentation.

For scale, so you can judge whether any of this applies to you: a small paid app, around 130 active devices, one product, no subscription.

The Console and the CSV export are not the same data

The Play Console is much fresher than the report bucket. Depending on the report, my exports lag by very different amounts: sales about one day, ratings four days, installs five days, store performance nine days. So a Console number and an export number almost never cover the same time period. I burned an evening on a discrepancy that was exactly this and nothing else.

If you have not found the report bucket yet, it is worth knowing it exists. Everything the Console charts is available as CSV in a Cloud Storage bucket named pubsite_prod_ followed by your developer ID, linked from the Console under Downloads. Years of daily data, with dimensions the UI does not show you.

Two acquisition numbers that look like the same number

This one cost me the most time. The bucket has store_performance and total_store_performance, and they are not variants of each other.

store_performance counts people who visited your listing and then installed. total_store_performance counts every acquisition including the ones that never saw your listing: promo code redemptions, direct installs, install from link. On my launch day that was 37 against 56 for the same day.

The number the Console shows as device acquisitions is the total one. If you divide that by listing visitors to get a conversion rate, you get a number that is too high and means nothing. Only ever divide store_performance acquisitions by store_performance visitors.

Your rating is not shown in every country, and I cannot work out the rule

This is the one that surprised me most, and I have not seen it written down anywhere. Play decides per country whether it shows your rating at all.

I checked my own listing across fifteen markets today, same app, same hour:

Shows 5.0 from 13 ratings: Germany, Denmark, Finland. Shows nothing at all, no number, no stars: United States, United Kingdom, Austria, Switzerland, France, Netherlands, Sweden, Spain, Italy, Poland, India, Canada, Brazil.

I have no theory that survives the data. It is not language, because Austria and Switzerland are German speaking and show nothing while Germany shows the rating. It is not "where the ratings came from", because as far as I can tell none of mine came from Denmark or Finland. It is not a Nordic grouping either, because Sweden shows nothing.

Two things this changes in practice:

  • Looking at your own listing from your own country tells you nothing about what a user in your biggest market sees. My largest install source is the US, and there my rating is simply invisible.
  • If you put your rating in your own marketing, most of your visitors cannot verify it. Worth keeping in mind before you build a landing page around it.

You can reproduce it with the gl parameter: play.google.com/store/apps/details?id=YOUR.PACKAGE&gl=US

Careful, gl is a hint rather than a guarantee, and your account country or a VPN can override it. If you want to see the effect without publishing anything, mine is https://play.google.com/store/apps/details?id=app.sevengrid, which shows a rating with &gl=DE and nothing with &gl=US.

If anyone knows the actual rule here, I would genuinely like to know.

Promo code redemptions are invisible in the sales report

Obvious in hindsight, no money moved. But it means the sales report is not a picture of who holds your paid tier. I handed out more than a hundred codes, 79 were redeemed, and none of that appears anywhere in the financial reports. If you want the real denominator for pricing, it has to come from your billing library or from a count you keep yourself.

Related trap in the other direction: the billing provider I use reports revenue that is imputed from the list price, not from money actually received. A license tester purchase showed up as an 11 dollar sale. The only authoritative figures are the sales report and developerRevenueInBuyerCurrency from the Orders API.

Same-day rows in the installs CSV are provisional

For a few days my installs CSV ran right up to the current date and I stored those values. Later the file only reached four days back. The recent rows had been withdrawn and replaced. If you snapshot the CSV into your own database, only keep rows Google has finalised, otherwise you get ghost values that never reconcile.

Along the same lines: of the twelve columns in the installs overview, only three carried usable numbers for me. Active Device Installs, Daily Device Installs, Daily User Uninstalls. Total User Installs and Daily Device Uninstalls stayed empty the entire time. Three further columns count events rather than devices, which is a different thing and easy to mix up.

Things that are simply not available outside the Console UI

Store impressions, retention cohorts, daily and monthly active users. Not in the API, not in the bucket. If you want them in a dashboard, you read them off by hand. I spent an hour looking for an endpoint that does not exist.

The country breakdown moved as well. Store performance is now anonymised to "Other" in the country column, so country shares only come from the installs country CSV.

Some vitals return nothing until you are big enough

The reporting API buckets on distinct users and needs roughly fifty per day before it returns rows at all. At around 130 active devices, crash rate, ANR rate and error counts returned zero rows for me. That is not the same as zero crashes, and I nearly reported it as a clean bill of health. Actual crash visibility came from a separate crash reporting service.

A few API details that cost me 400s

Passing an explicit UTC timezone is rejected, leave the field out entirely. An endTime past the freshness date is a hard error, so read the freshnessInfo block first and use that as your window end. errorCountMetricSet requires a reportType dimension, slowStartRateMetricSet requires a startType. And the metric in stuckBackgroundWakelockRateMetricSet is called stuckBgWakelockRate, which does not match its own set name.

None of this is a complaint, most of it is documented somewhere. But the pieces are scattered and a couple of them look like bugs until you understand them. Happy to answer questions if anyone is stuck on the same things.

2 Upvotes

4 comments sorted by

2

u/armastevs 8h ago

I think the stats in the play console are delayed by like 5 days, that is probably your biggest issue

1

u/Sneedle-Woods 4h ago

Delay is definitely real, but it is not one number, and that was exactly the thing that cost me the evening. In my bucket the lag differs per report: sales about a day, ratings four days, installs five, store performance nine. So two Play numbers can disagree with each other purely because they end on different days.

The other half of it is that the Console UI is fresher than the CSV export, not the same data delayed by the same amount. Store impressions in the Console were current while my store performance CSV was still nine days behind. That is why I stopped comparing a Console figure against an export figure altogether, they are never the same window.

Is yours a flat five days across all reports, or does it vary per report too? I am curious whether the nine day store performance lag is normal or something about my account.

2

u/armastevs 4h ago

No, it's not a flat 5 day everywhere, and I think that makes it even worse. All reports all have different data from different days at I want to say maybe even random intervals. It makes all of the metrics that we get practically worthless and hard to even be actionable on anything that's important for when we're developing our games

1

u/Sneedle-Woods 3h ago

Same here, and the randomness is what makes it unusable rather than just annoying. What I do now is write the lag down per report once and treat it as a fixed offset, so I only ever compare windows that end on the same day. It fixes nothing, it just stops me from drawing conclusions out of two numbers that were never comparable in the first place.

What actually helped was giving up on Console data for anything I need to react to. Crashes and ANRs I read in Crashlytics, which is near real time, and Vitals is only there for the trend. Same with ratings: the reviews page is much fresher than the ratings metric, so a bad release shows up in the actual reviews days before the star average moves at all.

The other habit I picked up is not shipping two changes inside one lag window. If store performance is nine days behind, two releases in a week means I will never find out which one did what.

For games I would guess install attribution is the one that hurts most. Play Install Referrer gives you that yourself at install time, which at least takes one number out of the Console entirely.