A public Tumblr blog hands a plain HTTP client the full page on the first request from Germany and Japan: 4,505 and 4,421 words in 399,885 and 409,395 bytes, with the canonical, the h1 and an ItemList in JSON-LD. Rendering the same URL in a browser adds exactly zero words for 812,414 bytes. From a US exit the first plain request returns 2 words in 6,869 bytes and the second returns the full page. On Tumblr the setting is a residential exit outside the US, plain HTTP, and a retry budget of 2.
The search results for this keyword are fan fiction tagged "proxies", a privacy front end called Priviblur that reads Tumblr without JavaScript, and vendor pages that explain Windows proxy settings. The related searches are the honest signal: "view Tumblr without account", "Tumblr viewer", "Tumblr profile viewer". People want to read public blogs without logging in. We measured what that actually returns on 28 September 2026.
The blog is fully server-rendered, and the browser adds nothing
We audited staff.tumblr.com, Tumblr's own staff blog, through residential exits in three countries, once without JavaScript and once rendered in a browser.
| Exit country | Plain HTTP, first request | Rendered in a browser |
|---|---|---|
| Germany | 4,505 words, canonical, h1, ItemList JSON-LD | 4,505 words, identical |
| Japan | 4,421 words, canonical, h1, ItemList JSON-LD | 4,421 words, identical |
| United States | 2 words in 6,869 bytes; second request 7,665 words | 4,502 words |
Read the Germany and Japan rows first. The word count is the same with and without JavaScript, the title is the same, the canonical is the same. Tumblr blogs on their own subdomain are classic server-rendered HTML: every post, every reblog chain, every note count is in the response body before any script runs. The 84-word gap between Germany and Japan is the newest post appearing in one sample and not the other, not a geographic difference.
The rendered pass therefore buys nothing. We weighed it: 812,414 bytes and 11.7 seconds for 7,698 extractable words, against 399,885 bytes and 4.5 seconds for 7,668 words over plain HTTP. Twice the traffic, 30 more words of footer. On this platform the browser is a cost, not a tool.
The US exit needs a second request; three other exits do not
The United States row is the one that will confuse a naive crawler. The audit's plain pass from a US exit returned 6,869 bytes and 2 words. Our plain scrape from the same country, two minutes later, returned the full 386,280-byte page with 7,665 words on its second attempt, and every subsequent US request returned it on the first. Germany, Japan and the United Kingdom returned the full page on the first request every time: 399,885, 409,395 and 386,280 bytes.
So the pattern is per exit IP and it is short-lived: the first request from a fresh US residential address may get a 6,869-byte placeholder, and the second request from the same address gets the blog. The instruction is not "render" and it is not "avoid the US". It is: set a retry budget of 2 on a plain HTTP fetch, and if the response is under 10 KB with 2 words, request again before you conclude anything. Better still, pin a German, Japanese or British exit, where four out of four first requests returned the page.
The legacy v1 endpoint /api/read/json on the same blog returned the same 6,869-byte placeholder, so do not build on it; it is documented nowhere current and behaves like a page, not an API.
The same blog on www.tumblr.com is 4x heavier and changes language by country
Every blog has a second address: www.tumblr.com/<name>, the logged-in style view. We fetched www.tumblr.com/staff over plain HTTP from two exits. From the US it returned 1,698,998 bytes with the title @staff on Tumblr and the header x-tumblr-country: US. From Germany it returned 2,312,732 bytes with the title @staff auf Tumblr and x-tumblr-country: DE. Both carried 9,176 extractable words, the same posts, and the German version added a translated interface around them.
Two lessons in one fetch. First, the www view is 4.2 to 5.8 times the bytes of the subdomain view for the same posts, so read blogs on <name>.tumblr.com and only use www.tumblr.com/<name> for blogs that have disabled their subdomain. Second, the exit country rewrites the chrome: a parser keyed on the English title or on English UI strings silently breaks from a German exit. This is the same trap we documented on Facebook, where a follower count came back as 28,729,210 from the US and 28.729.208 from Germany. Pin the country for the duration of a job.
The RSS feed is the cheapest full-text read, and the API needs a key
Every Tumblr blog serves /rss. From both the US and German exits, staff.tumblr.com/rss returned 465,331 bytes of XML on the first request, with cache-control: max-age=600 and x-robots-tag: noindex. That is the full text of recent posts in a format you parse with a standard library, refreshed every ten minutes at the edge, and it did not show the US first-request placeholder. For monitoring a known set of blogs, the feed is the right surface.
The API v2 is the right surface for everything structured. We called api.tumblr.com/v2/blog/staff.tumblr.com/info without a key and received 143 bytes of JSON telling us to supply one. With an api_key, the blog and posts methods are documented and free. The documentation lists the limits, and they are the part that decides whether proxies help at all:
- 300 API calls per minute, per IP address; 18,000 per hour per IP; 432,000 per day per IP.
- 1,000 API calls per hour per consumer key; 5,000 per day per consumer key.
- The server answers 429 Limit Exceeded when any limit is hit, with the limit named in the error or headers.
Do the division. The per-IP hourly limit is 18 times the per-key hourly limit. A single consumer key exhausts its 1,000 calls per hour long before one IP address gets anywhere near 18,000. Adding proxies to a Tumblr API job does not add calls; it adds nothing until you have more keys, and keys are issued per registered application. Proxies matter for page and feed reads, which have no key; they do not matter for the API. That sentence is missing from every vendor page on this keyword.
The oEmbed endpoint at www.tumblr.com/oembed/1.0 is per post: pointed at a blog root it returned a 4,972-byte not-found page. Use it for embedding a known post URL, not for discovery.
What it costs, counting a gigabyte as one billion bytes
| How you fetch it | On-wire bytes | What you get | Per GB | Cost at $0.80/GB |
|---|---|---|---|---|
| Blog on its subdomain, plain HTTP | 399,885 | 4,505 words, full posts, canonical, JSON-LD ItemList | ~2,500 pages | $0.00032 |
| Same blog, rendered | 812,414 | Same 4,505 words, 11.7 seconds | ~1,231 pages | $0.00065 |
| Same blog on www.tumblr.com, plain HTTP, US exit | 1,698,998 | 9,176 words including interface strings | ~589 pages | $0.00136 |
| Same blog on www.tumblr.com, plain HTTP, DE exit | 2,312,732 | 9,176 words, German interface | ~432 pages | $0.00185 |
| Blog RSS feed | 465,331 | Full text of recent posts as XML | ~2,149 feeds | $0.00037 |
| API v2 blog/info, no key | 143 | An error until you pass api_key | n/a | n/a |
Refresh 20,000 public blogs a day for a month on their subdomains: about 240 GB over plain HTTP, about $192 at the residential Basic rate. Rendered, the same job moves about 487 GB and costs about $390 for the same words. On www.tumblr.com from a German exit it would be about 1,388 GB and about $1,110. The cheapest route is also the one with the most stable HTML, which is not a coincidence: the subdomain view is the one Tumblr has served to feed readers and search engines for fifteen years.
If you would rather not run the fetch layer, our web scraping API returns the subdomain page as Markdown for $0.0002 per page with no browser, and handles the second-request pattern for you. On Tumblr do not pay for the $0.001 rendered mode; the measurement above is the proof.
What Tumblr's own files permit, in one line each
The robots.txt is 3,452 bytes. For an unnamed client it disallows 20 paths (the dashboard, search with pagination, tagged pages with language or before parameters, likes, media files, the consent page) and sets Crawl-delay: 1. Blog subdomains, post permalinks and tag pages without parameters are not excluded. Fourteen crawlers are excluded from the whole site by name, among them CCBot, Google-Extended, Amazonbot, ClaudeBot, anthropic-ai, Applebot-Extended and meta-externalagent: Tumblr says no to AI training crawlers explicitly and to ordinary readers only on private surfaces.
The Terms of Service say more. Section 3 prohibits, without express prior written permission, accessing or searching the services by any means other than the currently available published interfaces or as permitted by robots.txt, and separately prohibits scraping the services and particularly scraping Content. That is the plain line: reading Tumblr at volume without written permission breaches its terms, and the published interfaces it points to are the API and the robots-permitted surfaces. Nothing in a proxy setting changes that.
What this is properly for: reading the public blogs of people and brands you already follow, checking that your own blog renders from the countries your readers live in, checking an embed through oEmbed, and social listening across a known list of tags at a pace the Crawl-delay permits. Users can also set their blog to be hidden from search and from tumblr.com; that setting is honoured by Tumblr's own pages, and a blog that returns nothing on its subdomain has usually opted out. Do not build multi-account tooling, do not automate likes or follows, which the API caps at 1,000 and 200 per user per day, and do not read private or password-protected blogs.
The setting that works on Tumblr
- Network: residential, Basic at $0.80/GB. Four residential exits in four countries read the blog over plain HTTP; nothing in twelve passes required more than a household address.
- Fetch mode: engine: tls, plain HTTP, retry budget 2. 4,505 words in 399,885 bytes from Germany; the render returns the same words for 812,414 bytes.
- Country to pin: Germany, Japan or the United Kingdom, where the first request returned the full page four times out of four. From the US the first request returned 2 words and the second returned 7,665.
- URL to read: <name>.tumblr.com, not www.tumblr.com/<name>, which is 4.2 to 5.8 times the bytes and changes language by exit country.
- For structure: the API v2 with an api_key, at 1,000 calls per hour per key; more proxies do not add calls. For full text at low cost, /rss at 465,331 bytes.
- When the proxy is not enough: the web scraping API at $0.0002 per page returns the subdomain page as Markdown with the retry handled; for cross-platform listening alongside Tumblr, the Reddit collector returns public posts as rows with no fetch layer on your side.
- Free tier: every account gets $2 of free API usage per month, which covers about 6,000 blog pages at the plain-HTTP rate.