Google returns HTTP 429 when pytrends exceeds an undocumented request threshold. The library documents sleep delays, proxy rotation, and retry backoff, but production teams still hit hard stops after roughly 100 to 1,400 queries. This page maps the failure modes, recovery protocols, and when managed APIs cost less than fighting the cap.
HTTP 429 is the most common production failure for pytrends pipelines. Google does not publish a quota. The library reverse-engineers the Trends web UI, so every request looks like browser traffic until it does not. When Google flags the session, the entire batch stalls.
For the broader developer comparison, see Trends MCP vs pytrends. For infrastructure and proxy TCO modeling, see pytrends production cost.
A blocked request surfaces as a urllib3 retry exhaustion, not a clean Python exception with a retry-after header:
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='trends.google.com', port=443):
Max retries exceeded with url: /trends/api/explore?... (Caused by ResponseError('too many 429 error responses'))
The failure can hit any pytrends method: interest_over_time(), interest_by_region(), related_queries(), trending_searches(), or build_payload(). One 429 during a batch often poisons the rest of the run unless the script catches the error and backs off per keyword.
Empty DataFrames are a separate problem. Google sometimes returns 200 with no data even for keywords that worked an hour earlier. A 429 is an explicit throttle. Treat them differently in retry logic.
Google does not document limits for the unofficial Trends interface. pytrends maintainers and GitHub issue reporters have collected rough ranges:
| Scenario | Approximate trigger | Recovery time cited |
|---|---|---|
| Single IP, no proxy, sequential queries | ~1,400 requests in 4 hours | Hours to 24 hours |
| Residential proxies, bulk keyword run | ~100 keywords before 429 | 2 hours minimum per maintainer |
| Aggressive cron (no sleep) | First dozen to few dozen queries | Immediate block on IP |
| After hard block with sleep=60 | Varies | 60 seconds between successful calls once unblocked |
These numbers are community-sourced, not guaranteed. Google's bot detection changes without notice. A pipeline that ran 500 keywords daily last month may hit 429 at 80 keywords today.
pytrends exposes several constructor arguments documented in the GitHub README. None eliminate 429. They reduce frequency.
from pytrends.request import TrendReq
pytrends = TrendReq(
hl='en-US',
tz=360,
timeout=(10, 25),
retries=2,
backoff_factor=0.1,
sleep=60,
proxies=['https://user:[email protected]:8080'],
requests_args={'verify': True}
)
sleep. Seconds to wait between API calls once rate-limited. The README suggests 60 after hitting the cap. Setting sleep proactively (for example 5 to 10 seconds between every query) slows throughput but delays the first 429.
retries and backoff_factor. urllib3 retries failed requests with exponential delay: {backoff_factor} * (2 ^ (retry_number - 1)) seconds. With backoff_factor=0.1, delays are 0.0s, 0.2s, 0.4s. Short backoff helps transient network errors. It does not bypass a hard Google IP block.
proxies. List of proxy URLs passed to requests. Rotating residential IPs spreads load. Cheap datacenter proxies often fail faster than direct connections because Google recognizes datacenter IP ranges. Issue #578 on the pytrends repo recommends superproxy providers where the exit IP rotates per request.
timeout. Tuple of connect and read timeouts. Prevents hung connections from blocking a worker pool. Does not affect rate limits.
Once a datacenter IP is blocked, the options are wait or rotate.
| Proxy approach | Typical monthly cost | Effective throughput |
|---|---|---|
| No proxy, sleep=60 after block | $0 proxy, high latency | Dozens of keywords per hour |
| Rotating residential (pay per GB) | $50 to $200 | Hundreds per day with tuning |
| Dedicated residential pool | $200 to $500+ | Thousands per day, still capped |
| Managed Google Trends API | $0 to $25+ at low volume | Published limits, no scraping |
A team running 4,000 keywords daily (reported in GitHub issue #578) hit 429 after ~100 keywords even with residential proxies. At that volume, proxy spend plus sleep delays often exceed SerpApi or Trends MCP subscription costs.
Teams that cannot abandon pytrends use a layered approach:
None of this is built into pytrends. Every layer is custom code that breaks when Google changes response shapes.
429 is a throttle. Parser breakage is a structural failure when Google changes the Trends frontend JSON format. Both stop pipelines overnight. The fix differs:
| Failure | Symptom | Fix |
|---|---|---|
| HTTP 429 | MaxRetryError, explicit throttle message | Wait, proxy rotate, reduce rate |
| Parser error | KeyError, empty response, unexpected JSON | Upgrade pytrends version, patch locally, wait for maintainer |
| Empty DataFrame | 200 OK, zero rows | Retry later, different geo, or accept gap |
A mature pipeline handles both. Most notebooks handle neither.
Personal research (20 keywords, weekly). Direct connection, no proxy, manual reruns on 429. Cost: $0. Time cost: acceptable.
Marketing dashboard (200 keywords, daily refresh). Requires sleep between queries or proxy rotation. At 10 seconds per keyword, 200 keywords take 33 minutes sequential. At 60 seconds post-block, one 429 event adds an hour.
SEO agency (2,000+ keywords, daily). Almost certainly needs proxy pool plus queue infrastructure. Expect multiple 429 events per run. Engineering maintenance is ongoing.
AI agent (ad hoc queries). Unpredictable burst pattern. A single agent session can fire 30 related_queries calls in minutes and trigger a block that affects other services on the same IP.
When 429 recovery costs more than the data:
| Volume | pytrends realistic cost | Managed option |
|---|---|---|
| 100 queries/month | $0 (with patience) | Trends MCP free: 100 req/month, $0 |
| 1,000 queries/month | $50 to $150 proxy + ops | SerpApi Starter: $25/month, 1,000 searches |
| 5,000 queries/month | $200+ proxy + engineering | Trends MCP Pro: $49/month, 5,000 requests |
| Multi-platform (Google + TikTok + Reddit) | Not available in pytrends | Trends MCP any paid tier |
Managed APIs publish limits. pytrends publishes a README note that the rate limit is "not publicly known."
Migration makes sense when:
For migration paths, see the pytrends alternative page. For how free options compare on limits and credit card requirements, see the free trends API comparison.
Trends MCP returns structured JSON via REST or MCP with published monthly request limits. No TrendReq constructor. No sleep parameter. No urllib3 retry loop against Google's bot detection.
FAQ