Word count and translation volume

WordPress word count and translation volume calculator.

Enter a WordPress site. Get every published word by content type, then the volume, time and cost of translating it into each language you add.

Try a public site:

The short answer: to count the words on a WordPress site, read its public REST API at /wp-json/wp/v2/ in batches of 100 items, strip the HTML and shortcodes, and add up the title and body of every published post, page and custom post type. Translation volume is that total multiplied by the number of languages you add: 8,000 words into 3 languages is 24,000 words to translate.

Junaid KhalidBy Updated Benchmarks checked the same day

How do you count the words on a WordPress site?

You count the words on a WordPress site by reading each published item from its REST API and adding up the text. WordPress has shipped that API in core since version 4.7, and it answers at /wp-json/ on most sites with no login. The counter above does five things, in this order:

  1. Finds the API. It reads robots.txt and the home page, follows redirects (www, https, a subdirectory install such as /blog/), and looks for the API address WordPress advertises.
  2. Lists the content types. /wp/v2/types names every post type the site publishes in the API: posts, pages, WooCommerce products and custom types. Menus, templates and media are skipped.
  3. Asks each type for its size. One small request per type returns the X-WP-Total header, the number of published items.
  4. Reads 100 items at a time. WordPress caps a page of results at 100 records. Each batch is stripped of HTML, block comments and shortcodes, counted, and thrown away.
  5. Multiplies by your languages. The total becomes a translation volume, with time and list-price cost for each language.

“per_page is capped at 100 records”

Large sites: a sample first, then every item if you want it

A blog with 100,000 posts needs 1,000 requests to read in full. So any content type with more than 2,000 items starts as a sample: 10 batches of 100, spaced evenly from the newest item to the oldest, 1,000 items in all. The result is labelled an estimate and carries a 95% margin of error worked out from how much the batches differ. When that margin is wider than 10% and the rest of the type fits in 80 more batches, the counter reads every item on its own, so you get an exact figure. Otherwise one button reads every remaining batch. Progress is saved in your browser, so a long count can be paused and picked up later.

Some hosts do not serve a list all the way down. One large publisher in our tests answered with an empty list past roughly its newest 10,000 posts. The counter notices this, spreads its sample over the part it can read, and says plainly that older posts were assumed to be about as long.

What is counted, and what is left out

The count covers the title and rendered body of every published item the REST API lists, once each. That is the text a translator would be handed, without the theme around it.

Counted

  • Titles and body text of published posts and pages
  • Public custom post types, including WooCommerce products (title, description, short description)
  • Text inside blocks, page-builder layouts and shortcodes that WordPress renders into the body
  • Category and tag names and descriptions, when you tick them
  • Image alt text, shown as its own figure and kept out of the total

Left out

  • Drafts, private and password-protected items
  • Menus, widgets, headers, footers and other theme text
  • Plugin interface text, such as checkout labels and form messages
  • SEO titles and meta descriptions, custom fields and comments
  • Product attributes, variations and reviews

A word is a run of characters between spaces that holds at least one letter or digit, so a lone dash or bullet is not a word. Hyphenated terms such as state-of-the-art count once, the way a word processor counts them.

How are Chinese, Japanese, Korean and Thai words counted?

Chinese and Japanese are counted one character as one word, and Thai, Lao, Khmer and Burmese are split into words with a dictionary. Splitting on spaces fails for all of them, because they are written without spaces between words. Korean, Arabic, Hebrew, Hindi and Russian put spaces between words and are counted like English.

“reliable detection of word boundaries in languages such as Thai, Lao, Chinese, or Japanese requires the use of dictionary lookup or other mechanisms”

  • Chinese and Japanese: each Han character, hiragana and katakana counts as 1. A page that mixes Japanese with English product names gets both rules at once.
  • Thai, Lao, Khmer, Burmese: words come from the browser and server's built-in Intl.Segmenter, which MDN documents for text that “does not use whitespaces between words”.
  • Character count: shown beside every word count, because machine translation APIs bill by the character.

WordPress's own editor counts Chinese and Japanese by the character too. Its count type is a setting inside each language pack, read by wp_get_word_count_type(), and the packs on translate.wordpress.org set it like this:

WordPress word count setting by language pack
WordPress languageCount typeWhat it means
English, German, French, Korean, ThaiwordsSplit on spaces
Chinese (China, Taiwan, Hong Kong)characters_excluding_spacesEvery character is one unit
Japanesecharacters_including_spacesEvery character, spaces too
Khmercharacters_excluding_spacesEvery character is one unit

Translation vendors bill these scripts by the character too. Gengo prices Japanese, Chinese and Korean sources per character, and WPML converts with total characters x 0.55, so 1,000,000 Chinese characters are billed as 550,000 words.

How is translation volume calculated?

Translation volume is the source word count multiplied by the number of languages you are adding. A site of 50,000 words going into Spanish, French and German has 150,000 words to translate. Agencies quote on source words, and word-metered plugins bill on the same sum.

“if your original website has 8,000 words, and you want to translate it into 3 languages [...] you will have approximately 3 x 8,000 = 24,000 translated words”

For each language you pick, the calculator then shows:

  • Words after translation. Text changes length. 1,000 English words become about 1,062 in French and 692 in Korean, by the per-language figures in Brysbaert's 2019 reading-rate study.
  • Working days. For one translator at 2,000 to 3,000 words a day, and for machine translation with a full human edit at 5,600 to 7,000 words a day.
  • Reading time. The floor for a human review: reading every translated word once at 238 words a minute, or the published rate for that language.
  • List-price cost. The raw machine translation API bill by the character, and human translation at published per-word prices.

If the site already runs in several languages, the counter reads the language of each item from its language field or URL prefix and lets you pick the one you translate from, so existing translations are not counted twice.

Benchmarks used, with sources

A professional translator delivers 2,000 to 3,000 words a day, post-editing machine translation runs at 5,600 to 7,000 words a day, and adults read 238 words a minute in silence. Those are the benchmarks behind the calculator. Every time and cost figure in it is a published number, opened and checked on October 8, 2026. Where a language has no published figure, the calculator shows none for it.

Translation and reading benchmarks used by the calculator
BenchmarkFigureDetailSource
Human translation, no machine help2,000 to 3,000 words a dayOne professional translator. Translated quotes a standard pace of about 2,500 words a day.Slator, citing Acolad (2022)
Machine translation with a full human edit5,600 to 7,000 words a day700 words an hour for full post-editing over an 8-hour day, up to the 7,000 a day that memoQ reports.Slator (2022) and memoQ
Silent reading, English non-fiction238 words a minuteAverage across 190 studies. The same paper gives a rate for 11 more languages, used here when the language has one.Brysbaert (2019)
Words after translation from English692 to 1,062 per 1,000 English wordsKorean 692, Finnish 764, Arabic 822, German 975, Spanish 1,025, French 1,062.Brysbaert (2019), table 5
Azure AI Translator, list price$10 per million charactersStandard text translation (S1): $10 per million characters.Azure AI Translator pricing
Amazon Translate, list price$15 per million charactersStandard text translation: $15.00 per million characters.Amazon Translate pricing
Google Cloud Translation, list price$20 per million charactersNeural machine translation: $20 per million characters after the first 500,000 characters each month.Google Cloud Translation pricing
Human translation from English, list price$0.09 to $0.21 a wordGengo's published prices: $0.09 to $0.12 for Standard and $0.18 to $0.21 for Advanced, by language.Gengo pricing by language

Machine translation prices are the pay-as-you-go list rates in US dollars, before the monthly allowances each vendor gives (Google's first 500,000 characters a month, for example). Google also bills the markup: it counts <p>こんにちは</p> as 12 characters, not 5. This tool counts visible characters only.

How do WordPress translation plugins meter words?

Of the six WordPress translation plugins below, four meter by the word, and each one counts differently. That is why the same site gets a different number from each vendor's calculator, and why a neutral count is worth having before you compare plans.

How WordPress translation plugins meter words
PluginWhat is meteredPublished detail
WeglotTranslated words across all languagesPlans run from 10,000 words in 1 language to 5,000,000 words in 20. The count is of unique words and includes SEO metadata.
TranslatePressAI translated words per licence yearLicences include 50,000, 200,000 or 500,000 AI translated words, refilled at each renewal.
WPMLSource words, once per language22,500 AI translation words come with Multilingual CMS and 45,000 with Agency. Chinese, Japanese and Korean are converted at characters x 0.55.
ConveyThisWords shown to visitorsPlans start at 10,000 words in 1 language. Words count when translated content is shown to a visitor, and up to 30,000 source words per page are supported.
GTranslateNo word meterEvery listed plan says unlimited words and pageviews.
Polylang ProNo word meter of its ownMachine translation runs on your own DeepL API key, so DeepL bills the characters.

Vendor counters crawl rendered pages, which is slow on a big blog. Kevin Muldoon ran one on his own blog for a WinningWP review:

“When I analysed my personal blog, the word count tool reached around 740,000 words before timing out”

Reading the REST API avoids that. A blog of that size at 1,500 words a post is about 500 posts, which is 5 requests of 100 items. For the translation itself, Hydori's WordPress plugin translates posts from inside WP admin and writes the hreflang tags, and the FAQ covers how it handles languages.

What if the WordPress REST API is closed?

If a site hides its REST API, you can still get the number four ways: a sitemap sample, an export file, a WP-CLI command or one SQL query. Security plugins and some hosts close the API to visitors, and the WordPress handbook documents how: sites “can require authentication for all REST API requests” with the rest_authentication_errors filter. The counter detects this and tells you which case it found.

1. Check whether the API is open

Run this from any terminal. A line such as x-wp-total: 137 means the API is open and the site has 137 published posts.

Terminal: is the REST API open?
curl -sI "https://yoursite.com/wp-json/wp/v2/posts?per_page=1" | grep -i "x-wp-total"

2. Estimate from the sitemap

The counter reads /wp-sitemap.xml (in core since WordPress 5.5) or a Yoast-style /sitemap_index.xml, opens a spread sample of 30 pages per sitemap, and counts each page's main content area. It is an estimate, labelled as one, and it only reads pages that robots.txt allows.

3. Upload a WordPress export file

In WP admin, go to Tools, then Export, choose All content and download the file. Drop it on the Export file tab above. The file is parsed in your browser, drafts and private items are left out, and nothing is uploaded.

4. Count on the server with WP-CLI or SQL

With shell access, this WP-CLI command counts published posts and pages with WordPress's own tag and shortcode stripping:

WP-CLI: words in published posts and pages
wp eval '
$total = 0;
$ids = get_posts(["post_type" => ["post", "page"], "post_status" => "publish", "numberposts" => -1, "fields" => "ids"]);
foreach ($ids as $id) {
  $post = get_post($id);
  $text = wp_strip_all_tags(strip_shortcodes($post->post_title . " " . $post->post_content));
  $total += count(preg_split("/\\s+/u", trim($text), -1, PREG_SPLIT_NO_EMPTY));
}
echo count($ids) . " items, " . $total . " words" . PHP_EOL;
'

With database access only, this query gives the count per post type. It needs MySQL 8.0 or MariaDB 10.0.5 or later for REGEXP_REPLACE. Change wp_posts if your table prefix is different.

SQL: words per post type
SELECT post_type,
       COUNT(*) AS items,
       SUM(IF(txt = '', 0, LENGTH(txt) - LENGTH(REPLACE(txt, ' ', '')) + 1)) AS words
FROM (
  SELECT post_type,
         TRIM(REGEXP_REPLACE(
           REGEXP_REPLACE(CONCAT(post_title, ' ', post_content), '<[^>]+>', ' '),
           '[[:space:]]+', ' ')) AS txt
  FROM wp_posts
  WHERE post_status = 'publish'
    AND post_type IN ('post', 'page')
) t
GROUP BY post_type;

Both read the raw post content, so block comments are stripped as tags but shortcode output and page-builder text stored outside the post body are not included. Expect them to land a little under the REST figure on sites that lean on shortcodes.

Tested on live WordPress sites

We ran the counter against 15 public sites on October 8, 2026: small and large, stores, non-Latin scripts, a closed API and a site that is not WordPress at all. These are the results it returned. Times are from typing the address to the finished number.

Results from running the counter on live sites
SiteKindItemsWordsResult
mjunaidkhalid.comOur own blog, 6 languages147312,902Exact in 14 seconds. A separate Python script counting the same API data got 312,940: 38 words apart, or 0.012%.
developer.wordpress.org/newsSmall blog in a subdirectory182355,264Exact in 20 seconds. Posts, pages and 2 custom post types.
wordpress.org/newsBlog with a podcast post type1,198948,979Exact. Paused, reloaded and resumed mid-count: same total as an uninterrupted run.
blog.mozilla.orgWPML site, address redirects2,1261,197,206Exact in 14 seconds. Followed the redirect to /en/ and flagged WPML.
nalgene.comWooCommerce store232113,906Exact. 101 products counted with their short descriptions. One run took 221 seconds because the site was slow, a later one 8 seconds.
polylang.proStore with 5 custom post types261120,971Exact in 13 seconds across 7 content types.
translatepress.comTranslatePress site, slow API481635,657Exact in 99 seconds. Batches timed out at 100 items, so the counter split them into smaller ones.
ja.wordpress.orgJapanese723835,778Exact in 38 seconds. Each kanji and kana character counts as one word.
ar.wordpress.orgArabic5844,969Exact in 15 seconds.
ma.ttPersonal blog, 5,718 posts5,745563,646The first sample said 573,679 with a ±42% margin. That was too wide, so every post was read: exact in 102 seconds. The sample had been 1.8% high.
www.nasa.govPublisher, 13 content types112,401about 54 millionEstimate with a ±14% margin from 5,885 items, in 128 seconds.
9to5mac.comPublisher, 90,129 posts90,511about 46 millionEstimate with no margin. The API returned nothing past about its newest 10,000 posts, and the result says so.
www.whitehouse.govREST API closed5,587 pagesabout 1.9 millionThe API asked for a login. The sitemap route read 351 pages and gave an estimate with a ±24% margin in just under 4 minutes.
techcrunch.comrobots.txt closes the API to crawlersnot countednot countedThe counter stopped and asked whether we had permission. We did not, so it went no further.
example.comNot WordPressnonenoneSaid so in under a second and offered the sitemap, export file and paste routes.

How the counter treats the sites it reads

The counter makes plain, identified requests for public pages and nothing else. A WordPress site does not let other websites read its API from a browser, so the requests go through our server, which follows these rules:

  • It says who it is. Every request carries the user agent HydoriWordCount/1.0 (+https://hydori.io/tools/wordpress-word-count; counts public words at a visitor's request).
  • It follows robots.txt. A rule that names the tool is always obeyed. A general rule against the API path stops the count until you confirm the site is yours or you have permission. The sitemap route never overrides robots.txt.
  • It goes slowly. At most 2 requests at a time from your browser, 2,400 requests an hour to any one site across all visitors, and 1,500 an hour per visitor. If a site answers that it is getting too many requests (HTTP 429), the count pauses for as long as the site asks and then carries on.
  • It says what it could not check. If a content type does not answer, or the site has more than 14 of them, the result is labelled a partial count and names what is missing.
  • It keeps nothing. Each batch is counted and discarded. Only the counts, public URLs and titles come back to your browser.
  • It only reads the public web. Private, local and internal network addresses are refused, on the first request and on every redirect.

Site owners who want it kept out can add User-agent: HydoriWordCount and Disallow: / to robots.txt.

Frequently asked questions

How do I see how many words are on a WordPress site?

Enter the site address in the counter above. It reads the site's public REST API in batches of 100 items, strips the HTML, and adds up the published words for posts, pages and each public custom post type. A site with a few hundred posts takes under a minute.

Does WordPress show a word count for the whole site?

No. The WordPress editor shows a count for the post you have open, and nothing in core adds those up across the site. A site total needs a plugin, a WP-CLI or SQL command run on the server, or an outside counter that reads the REST API, which is what this page does.

Is the count exact or an estimate?

Content types with up to 2,000 items are read in full, so the figure is exact for what the REST API publishes. Larger types are first estimated from 10 batches of 100 items spread from the newest to the oldest, and shown with a 95% margin of error. If that margin is wider than 10% and the type needs 80 more batches or fewer, every item is read automatically. Otherwise one click counts every item for an exact figure.

How long does it take to translate 1,000 words?

About 3 to 4 working hours for a professional translator. Translators deliver 2,000 to 3,000 words in a working day, as Slator reports from Acolad, so 1,000 words is a third to a half of a day. A study in Frontiers in Digital Humanities measured 503 words an hour for literary text translated from scratch.

How long does it take to translate 20,000 words?

7 to 10 working days for one translator at 2,000 to 3,000 words a day. With machine translation and a full human edit, at 5,600 to 7,000 words a day, the same 20,000 words take about 3 to 4 working days.

How much do translators charge per 1,000 words?

Published list prices run from $90 to $210 per 1,000 words from English. Gengo lists $0.09 to $0.12 a word for its Standard level and $0.18 to $0.21 for Advanced, and Translated gives an average of $0.10 a word, which is $100 per 1,000 words.

Why is this count different from a crawler-based word counter?

A crawler opens every page and counts what it renders, so menus, footers, sidebars and cookie banners are counted again on each page. This tool counts the title and body of each item from the WordPress API, once. Crawlers also see theme and plugin text that the API does not publish.

Does it work on WooCommerce stores and custom post types?

Yes, for any post type the site publishes in its REST API. WooCommerce products are counted from their title, description and short description. Attributes, variations and reviews are not in the public API, so they are left out.

What does the tool do if a site blocks the REST API?

It says so in plain words and offers three other routes: an estimate from a sample of pages in the XML sitemap, an exact count from a WordPress export file read in your browser, or pasted text. Site owners can also run the WP-CLI or SQL command on this page.

Is the content of my site stored?

No. Each batch is fetched, counted and discarded in the same request. The server keeps counts for rate limiting only. Your progress is saved in your own browser so a long count can resume, and an export file or pasted text never leaves your device.

Sources

  1. WordPress REST API handbook: Pagination (per_page cap, X-WP-Total and X-WP-TotalPages headers)
  2. WordPress REST API reference: Post Types (the /wp/v2/types route)
  3. WordPress REST API handbook: FAQ (requiring authentication for all requests)
  4. wp_get_word_count_type() (count type per language pack)
  5. WordPress 5.5 XML sitemaps (/wp-sitemap.xml)
  6. Unicode Standard Annex #29: Text Segmentation
  7. MDN: Intl.Segmenter
  8. Brysbaert, M. (2019). How many words do we read per minute? Journal of Memory and Language, 109, 104047. Open preprint
  9. Slator: How Fast Can You Post-Edit Machine Translation? (December 12, 2022)
  10. memoQ: machine translation vs post-editing
  11. Translated: translation rates
  12. Toral, Wieling and Way (2018). Post-editing effort of a novel with statistical and neural machine translation. Frontiers in Digital Humanities
  13. Gengo: pricing by language
  14. Google Cloud Translation pricing, Amazon Translate pricing, Azure AI Translator pricing
  15. Weglot help: total number of translated words and Weglot pricing
  16. WinningWP: Weglot Review by Kevin Muldoon (updated July 13, 2024)
Junaid Khalid
Written and tested by
Junaid Khalid

Multilingual SEO Specialist. Runs SEO for 14 sites, with 3,600+ articles under his byline and 50M+ organic impressions. He ran this counter against 15 live sites, his own blog included, before publishing it. Last updated .

Counted the words. Now translate them.

Hydori translates WordPress posts from inside WP admin, keeps your formatting and brand terms, and writes the hreflang tags for every language.