- Google Play
- Ratings
- Analytics
- Mobile Apps
Google Play rating calculation: why your rating differs by country and device, and how to track it
Google Play rating calculation explained: recent ratings weigh more, each country and device type sees its own rating, and how to track it per country.
- Author
- Extenify Team
- Published
- Reading time
- 14 min read

On this page
The Google Play rating calculation is not the average of every star your app has ever received. Google weights recent ratings more heavily, and since 2021 the number a user sees depends on the country they are registered in and the type of device they browse on. That is why your Play Console shows one number, a colleague abroad sees another, and a week of bad ratings after a release can move the public rating more than years of good ones.
This guide explains what Google has actually published about how the rating is calculated, why the numbers in Play Console and on the store page disagree, which reports give you the raw data, and how to track the public rating per country with a short script. On October 17, 2026 we checked the public listings of two large apps in six countries to show how far apart those numbers can be.
Key takeaways
- The rating users see on Google Play is "weighted towards more recent ratings", in Google's words. The lifetime average is a separate number that only you see in Play Console.
- Users on phones see ratings from their registered country (since November 2021). Tablets, Chromebooks, Wear OS and Android Auto show ratings for that device type (since early 2022).
- In our check, Duolingo's public rating ranged from 4.54 in Japan to 4.86 in Brazil on the same day, while the rating count shown was the same worldwide.
- Google does not publish the exact formula. Track the number per country over time, and compare recent daily ratings with the lifetime average to see where it is heading.
- Ratings do not reset when you publish a new version on Google Play.
Google Play rating calculation: what Google has published
Google's Play Console Help article on viewing and analyzing ratings and reviews is the closest thing to an official definition. It says: "Currently, the rating that users see on Google Play is weighted towards more recent ratings to reflect changes and updates that you make to your app." The same page lists the numbers at the top of the Ratings page in Play Console:
| Play Console metric | What it is |
|---|---|
| Google Play rating | "Your app rating shown to users on Google Play. This is calculated based on your most recent ratings." |
| Lifetime average rating | "Your average rating from when you first launched your app." |
| Users | The number of users who have rated your app. Users can change their rating at any time. |
| Total ratings | All ratings received over the app's lifetime, shown once the app has five or more. |
What Google does not publish is the weighting itself: how much more a rating from last week counts than one from two years ago, or how quickly an old rating fades. Anyone who quotes an exact formula is guessing. What you can rely on is the direction: recent ratings dominate, so a good release lifts the public rating faster than the lifetime average, and a bad one drags it down faster.
Two more rules from the same Help article matter for planning:
- Ratings do not start over with a new version. "App ratings don't start over when you publish a new version of your app." The App Store lets you reset the summary rating when you release a version; Google Play does not, so recency weighting is what lets an app recover.
- Ratings cover all versions of the same package. A user who rated version 1.0 and never updated still counts until they change their rating.
Your rating is different in every country
In August 2021 Google announced the change that explains most "why is my rating different?" questions. The Android Developers Blog post Making ratings and reviews better for users and developers set out the plan:
- "From November 2021, users on phones will start to see ratings specific to their registered country." Google's example: "a user in Japan will see app ratings generated from those submitted by other Japanese users."
- "Early in 2022 users on other form-factors such as tablets, Chromebooks, and wearables will start to see ratings specific to the device that they're on," including "tablets and foldables, Chrome OS, Wear, or Auto."
Google's stated reason was fairness: a bug that only affects one country should not drag down the rating everywhere, and a great tablet experience should not be hidden by phone ratings. The same post notes that ratings "are taken into consideration for featuring and placement on Play Store", so the rating in each market affects visibility there, not just conversion.
What that looks like on real listings
We fetched the public Google Play listing pages for two large apps with the country parameter set to six markets, and read the rating from the structured data on each page:
Country (gl) |
Spotify | Duolingo |
|---|---|---|
| United States | 4.35 | 4.74 |
| United Kingdom | 4.25 | 4.70 |
| Germany | 4.18 | 4.65 |
| India | 4.17 | 4.59 |
| Brazil | 4.55 | 4.86 |
| Japan | 4.47 | 4.54 |
Two things stand out. First, the spread is real: Duolingo shows 4.54 to users in Japan and 4.86 to users in Brazil, which a store page rounds to 4.5 and 4.9. Second, the rating count did not change by country: every page reported about 36.5 million ratings for Spotify and about 51 million for Duolingo. The average is local, the count is global. Changing only the language (hl) while keeping the country the same did not change the rating, and a phone user agent returned the same value as a desktop one for the same country.
The App Store works differently. Apple's ratings and reviews overview says the product page shows "a single summary rating for your app for each country or region of the App Store", and the count is per country too: the same day, Apple's lookup endpoint returned 42.6 million ratings for Spotify in the United States and 5.1 million in Japan. Our guide to the iTunes Search API shows how to read those numbers for any app.
Why Play Console does not match what users see
When the number in Play Console and the number on your phone disagree, it is usually one of these:
- Country. Your phone shows the rating for the country your account is registered in. When you compare, use the Play Console country breakdown for that same market.
- Device type. On a tablet or Chromebook you see the rating from that device type, which can be higher or lower than on phones.
- Recency versus lifetime. If you are looking at the lifetime average, it will lag the public rating in both directions.
- Rounding. The store shows one decimal. A move from 4.36 to 4.34 changes the displayed rating from 4.4 to 4.3, while a move from 4.44 to 4.36 changes nothing. Track at two decimals or you will miss the trend until it crosses a rounding line.
- Changed ratings. Users can edit or update their rating, often after you reply to their review, so a rating that seemed fixed can move with no new reviews.
Which rating data Play Console gives you
Play Console has more rating data than most developers use. From the Help article and the reports documentation:
- Ratings page. The overview above, plus "Performance over time" charts with a CSV download, by day, 7 days or 28 days. You can show the average for each period or the rolling lifetime average up to each day.
- Ratings breakdown. Average rating and number of ratings by country or region, language, app version, Android version, device type, device model and operator, each compared with "peers' median" for apps in the same category. This is where you see that one country or one device model is the problem.
- Monthly reports. The Download and export monthly reports page documents ratings files in your report bucket named
ratings_[package_name]_yyyyMM_[dimension].csv, with dimensions such as country, app version, device and language, and two values per day: "Daily Average Rating" and "Total Average Rating". The same page warns that the CSV files are UTF-16, not UTF-8. - Reply to Reviews API. Useful for review alerts but not for ratings: Google's Reply to Reviews documentation says "the API shows only the reviews that include comments" and "You can retrieve only the reviews that users have created or modified within the last week."
If you want the full picture of the other Play Console numbers, our guide to Google Play Console statistics covers installs, active users and time zones.
See where your rating is heading
Since the formula is not public, the practical question is directional: are recent ratings in a country above or below what the app has earned so far? The monthly country report answers that. This script compares the last 28 daily averages with the latest lifetime average for each country:
// recent-vs-lifetime.mjs: compare recent daily ratings with the lifetime average,
// per country, from a Play Console monthly ratings report.
// Usage: node recent-vs-lifetime.mjs ratings_com.example.app_202610_country.csv
import { readFile } from 'node:fs/promises';
const RECENT_DAYS = 28;
const GAP_ALERT = 0.2; // stars
const raw = await readFile(process.argv[2]);
// Play reports are UTF-16; fall back to UTF-8 for files you re-saved.
const text = raw[0] === 0xff && raw[1] === 0xfe ? raw.toString('utf16le') : raw.toString('utf8');
const [header, ...lines] = text.replace(/^\uFEFF/, '').trim().split(/\r?\n/);
const cols = header.split(',').map((c) => c.trim().toLowerCase());
const iDate = cols.indexOf('date');
const iDaily = cols.indexOf('daily average rating');
const iTotal = cols.indexOf('total average rating');
const iDim = 2; // the dimension column: Country in a *_country.csv file
const byCountry = new Map();
for (const line of lines) {
const f = line.split(',');
const country = f[iDim];
if (!byCountry.has(country)) byCountry.set(country, []);
byCountry.get(country).push({ date: f[iDate], daily: Number.parseFloat(f[iDaily]), total: Number.parseFloat(f[iTotal]) });
}
for (const [country, rows] of byCountry) {
rows.sort((a, b) => a.date.localeCompare(b.date));
const recent = rows.slice(-RECENT_DAYS).filter((r) => Number.isFinite(r.daily));
const lifetime = rows.findLast((r) => Number.isFinite(r.total))?.total;
if (!recent.length || lifetime === undefined) continue;
const recentAvg = recent.reduce((sum, r) => sum + r.daily, 0) / recent.length;
const gap = recentAvg - lifetime;
const flag = gap <= -GAP_ALERT ? ' <- recent ratings are pulling this country down' : '';
console.log(`${country} lifetime ${lifetime.toFixed(2)} recent ${recentAvg.toFixed(2)} (${recent.length} days)${flag}`);
}
On a test file in the documented format, it printed:
US lifetime 4.50 recent 4.55 (25 days)
JP lifetime 4.40 recent 3.89 (25 days) <- recent ratings are pulling this country down
DE lifetime 4.30 recent 4.27 (25 days)
Treat the result as a direction, not a forecast. The report has no rating count per day, so a quiet day with one rating counts as much as a busy one, and days with no ratings are skipped. A country where recent ratings sit well below the lifetime average is a country where the public rating is likely to fall: check its reviews, app versions and devices before it does.
Track the public Google Play rating per country
Play Console only covers your own apps, and its country breakdown shows the average of the ratings received in a period, not the weighted rating a user in that country actually sees. To record that number, read it from the public listing. Each Google Play app page includes structured data with an aggregateRating, and the gl parameter selects the country:
// play-ratings-by-country.mjs: record the public Google Play rating per country
// and flag countries where it dropped since the last run.
// Usage: node play-ratings-by-country.mjs com.example.app
import { readFile, writeFile } from 'node:fs/promises';
const COUNTRIES = ['US', 'GB', 'DE', 'IN', 'BR', 'JP'];
const DROP_ALERT = 0.05; // stars, compared at two decimals
const pkg = process.argv[2];
if (!pkg) throw new Error('Pass a package name, for example com.example.app');
async function playRating(packageName, country) {
const url = new URL('https://play.google.com/store/apps/details');
url.searchParams.set('id', packageName);
url.searchParams.set('hl', 'en');
url.searchParams.set('gl', country);
const res = await fetch(url, { headers: { 'user-agent': 'Mozilla/5.0 (compatible; rating-monitor/1.0)' } });
if (!res.ok) throw new Error(`${country}: HTTP ${res.status}`);
const html = await res.text();
const blocks = html.matchAll(/<script[^>]*type="application\/ld\+json"[^>]*>([\s\S]*?)<\/script>/g);
for (const [, json] of blocks) {
const data = JSON.parse(json);
if (data.aggregateRating) {
return {
rating: Math.round(Number(data.aggregateRating.ratingValue) * 100) / 100,
ratingCount: Number(data.aggregateRating.ratingCount),
};
}
}
return null; // no rating shown, or the page layout changed
}
const file = `ratings-${pkg}.json`;
const previous = JSON.parse(await readFile(file, 'utf8').catch(() => '{}'));
const today = { capturedAt: new Date().toISOString(), countries: {} };
for (const country of COUNTRIES) {
try {
today.countries[country] = await playRating(pkg, country);
} catch (err) {
today.countries[country] = null; // a failed fetch is "unknown", never "zero"
console.error(err.message);
}
await new Promise((r) => setTimeout(r, 1500)); // stay polite
}
for (const [country, now] of Object.entries(today.countries)) {
const before = previous.countries?.[country];
const line = `${country} ${now ? now.rating.toFixed(2) : ' - '}`;
if (now && before && before.rating - now.rating >= DROP_ALERT) {
console.log(`${line} DROP from ${before.rating.toFixed(2)}`);
} else {
console.log(line);
}
}
await writeFile(file, JSON.stringify(today, null, 2));
Run it once a day from a scheduler on your server. On its first run for Duolingo it printed US 4.74, GB 4.70, DE 4.65, IN 4.59, BR 4.86 and JP 4.54. Some cautions before you rely on it:
- The page is not an API. Google can change its markup at any time, which is why the function returns
nullinstead of guessing when the structured data is missing. Keep the request volume low and respect Google Play's terms. - The country is the page's
glparameter, not your server's location. Pin it explicitly so results do not move when your server does. - A failed fetch is not a drop. Store it as unknown, and compare only countries that have a value on both days. Otherwise one timeout looks like a rating collapse.
- Keep the history. One JSON file is enough to compare with yesterday. For months of history and charts, use a table keyed by app, country and day, as in our guide to PostgreSQL time series for daily app and extension stats.
What actually moves a Google Play rating
Because recent ratings dominate, the rating responds to what happened in the last weeks, not the last years:
- Releases. A crash or a removed feature in one version shows up first in the ratings breakdown by app version. Compare the version's average with the previous one before you roll it out further.
- One market or one device. The breakdown by country and device type is the first place to look when a country's rating moves on its own, since that country now has a rating of its own.
- Replies to reviews. Users can update their rating at any time, and a reply that solves their problem gives them a reason to. Our guide to reading review and rating trends covers how to tell a real decline from noise, and app review analysis with an LLM shows how to label what reviewers complain about by version.
- Competitors. If every app in your category drops in the same week, it is likely a platform or store change. If only yours does, it is your release.
Get app store rating alerts with Extenify
Recording ratings every day, for your apps and your competitors, is the boring part, and it is what Extenify automates. It tracks the public listing of your apps on Google Play and the App Store, and your extensions on the Chrome Web Store, Edge Add-ons and Firefox Add-ons, every day: rating, rating count, reviews, installs and versions. It sends app store rating alerts in both directions, when a rating drops or recovers at the two decimals it is stored with, alongside new reviews and new versions, in a daily digest by email, Slack, Discord or Telegram. A failed fetch is treated as unknown, never as a drop. If you want each new review in Slack as it arrives, our guide to App Store and Google Play review alerts shows the setup. Every plan starts with a 7-day free trial, and the pricing page lists the plans.
Frequently asked questions
How is the Google Play rating calculated?
Google says the rating shown on Google Play is "weighted towards more recent ratings" and "calculated based on your most recent ratings". It is calculated separately for each country on phones, and for each device type such as tablets, Chromebooks, Wear OS and Android Auto. Google does not publish the exact weighting.
Why is my app rating different in another country?
Since November 2021, users on phones see a rating built from the ratings of users registered in the same country. An app can therefore show 4.5 in one country and 4.9 in another on the same day, as Duolingo did in our October 2026 check.
Why doesn't my Google Play rating go up after new 5-star reviews?
The public rating reflects recent ratings in the viewer's country and device type, and the store rounds to one decimal. A few 5-star ratings may come from other countries, may be outweighed by recent lower ratings, or may move the value without crossing a rounding line. Check the two-decimal value and the country breakdown in Play Console.
Does Google Play reset ratings with a new app version?
No. Google's Help Center states that app ratings "don't start over when you publish a new version of your app." Because recent ratings carry more weight, a better version still lifts the public rating over time.
Is the rating count also different per country on Google Play?
In our check it was not: each country page showed the same worldwide rating count while the average differed. The App Store is different, with a separate count for each country or region.
Summary
The Google Play rating calculation favors recent ratings, and since 2021 every phone user sees the rating from their own country, while tablets, Chromebooks, Wear OS and Android Auto have device-specific ratings. That explains why Play Console, your phone and a colleague abroad all show different numbers, and why the count is the same everywhere while the average is not. Use the Play Console breakdowns and monthly country reports to see where recent ratings are heading, record the public rating per country every day at two decimals, and treat a failed fetch as unknown rather than a drop.
Image credits
- Cover photo: World map at Mumbai airport by Meher Bala on the WordPress Photo Directory, CC0.


