Rate limiting layers
The tool uses both proactive rate limiting (preventing issues) and reactive retry logic (handling errors).Layer 1: Proactive rate limiting
Before each API request, the analyzer enforces a minimum time interval between consecutive calls.src/analyzer.py
Layer 2: Retry with exponential backoff
When rate limit errors occur despite proactive limiting, the@retry_with_backoff decorator automatically retries the request.
src/analyzer.py
Configuration
Environment variable
Set the rate limit interval in your.env file:
.env
The
RATE_LIMIT_SECONDS setting controls the minimum time between consecutive API calls. The actual time may be longer depending on API response times.Configuration file
Alternatively, modifysrc/config.py directly:
src/config.py
Retry behavior
The retry mechanism handles transient failures with intelligent backoff.Retryable errors
The following error types trigger automatic retries:- Timeout errors: Network timeout or API timeout
- Connection errors: Failed to establish connection
- Rate limit errors: 429 (Too Many Requests)
- Quota errors: API quota exceeded
- Service errors: 503 (Service Unavailable)
- Temporary unavailability: Transient service issues
src/analyzer.py
Non-retryable errors
These errors fail immediately without retry:- Authentication errors: Invalid API key
- Validation errors: Malformed request
- Parse errors: Invalid response format
- Application logic errors: Internal bugs
Exponential backoff algorithm
Retry delays increase exponentially with each attempt to avoid overwhelming the API.src/analyzer.py
Backoff calculation
Withinitial_delay=1.0 and max_retries=3:
| Attempt | Formula | Sleep Time (approx) |
|---|---|---|
| 1st retry | 1.0 * (2^0) + jitter | ~1 second |
| 2nd retry | 1.0 * (2^1) + jitter | ~2 seconds |
| 3rd retry | 1.0 * (2^2) + jitter | ~4 seconds |
The
jitter component (time.time() % 1) adds randomness to prevent thundering herd issues when multiple processes retry simultaneously.Customizing retry behavior
To adjust retry parameters, modify the decorator insrc/analyzer.py:
src/analyzer.py
Recommended configurations
Monitoring rate limits
Watch the logs to understand rate limit behavior:Handling API quota limits
Gemini API free tier limits
- Requests per minute: 15
- Requests per day: 1,500
Calculating processing time
For a given archive size and rate limit:- 1,000 tweets at 1.0 sec/tweet = ~17 minutes
- 5,000 tweets at 2.0 sec/tweet = ~167 minutes (~3 hours)
- 10,000 tweets at 4.0 sec/tweet = ~667 minutes (~11 hours)
Multi-day processing
For large archives exceeding daily quotas:The tool saves progress after each batch, so you can stop and resume at any time without losing work.
Best practices
- Start conservative: Use
RATE_LIMIT_SECONDS=2.0for your first run - Monitor logs: Check for 429 errors indicating you’re hitting limits
- Adjust gradually: Decrease the interval only if you see no rate limit errors
- Consider batch size: Smaller batches (see batch processing) provide more frequent checkpoints
- Plan for quotas: If you have 10,000+ tweets, expect multi-day processing on free tier
Troubleshooting
”Rate limit exceeded” errors persist
Symptom: Even after retries, you see 429 errors Solution: IncreaseRATE_LIMIT_SECONDS to 4.0 or higher:
.env
Processing is too slow
Symptom: Analysis is taking longer than expected Solution: DecreaseRATE_LIMIT_SECONDS if you’re on a paid tier:
.env
Intermittent timeout errors
Symptom: Occasional timeout errors but retries succeed Solution: This is normal. The retry mechanism handles transient network issues automatically. No action needed unless errors are frequent.”Max retries exceeded” error
Symptom: Analysis fails with “max retries exceeded” Solution: Either:- Check your internet connection
- Verify your API key is valid
- Increase
max_retriesinsrc/analyzer.py - Contact Google if the Gemini API is experiencing outages