Intelligent rate limit handling for Feishu/Lark API. Avoid 429 errors and ensure batch operations complete successfully.
SituationActionAPI call fails with 429Parse Retry-After, wait, retry (max 3 times)Batch write operationsSplit into batches of 10, 1s interval per itemDocument API callsUse 2-3s interval (stricter limits)High call frequencyIncrease interval dynamicallyRate limit reachedWait 10s, then gradually reduce interval
Activate this skill when:
feishu_doc, feishu_bitable_*, feishu_drive, feishu_wiki, etc.)Limit TypeQuotaDescriptionPer minute100 calls/min/appApp-level minute limitPer day10,000 calls/day/appApp-level daily limitPer minute (per user)5 calls/min/user/appUser-level limit
API TypeSpecial LimitDocument writesStricter, recommend 2-3s intervalBitable batch write≤100 per batch, ≥1s intervalFile uploadsLarge files need longer intervals
Official Docs: https://open.feishu.cn/document/platform-notices/platform-updates-/custom-app-api-call-limit
text
Initial interval: 1 second
Minimum interval: 1 second
Maximum interval: 10 seconds
Warning threshold: 50 calls/minute
python
class FeishuRateLimiter:
"""Feishu API Rate Limiter"""
def __init__(self):
self.base_interval = 1.0 # Base interval 1s
self.current_interval = 1.0 # Current interval
self.max_interval = 10.0 # Max interval
self.recent_calls = [] # Recent call records
self.window_size = 60 # Stats window 60s
self.max_retries = 3 # Max retries
def before_call(self):
"""Wait before call"""
time.sleep(self.current_interval)
self.recent_calls.append(time.time())
self._adjust_interval()
def _adjust_interval(self):
"""Dynamically adjust interval based on recent call frequency"""
now = time.time()
# Count calls in last 60s
recent = [t for t in self.recent_calls if now - t < self.window_size]
self.recent_calls = recent
call_count = len(recent)
# Adjust interval based on frequency
if call_count > 50: # Near limit (100/min)
self.current_interval = min(self.current_interval * 1.5, self.max_interval)
elif call_count > 30:
self.current_interval = min(self.current_interval * 1.2, self.max_interval)
elif call_count < 10 and self.current_interval > self.base_interval:
# Reduce interval when calls are infrequent
self.current_interval = max(self.current_interval * 0.9, self.base_interval)
def on_rate_limit(self, retry_after=None):
"""Called when 429 error occurs"""
if retry_after:
wait_time = retry_after
else:
wait_time = self.current_interval * 2
self.current_interval = min(wait_time, self.max_interval)
time.sleep(self.current_interval)
def on_success(self):
"""Gradually restore normal interval after success"""
if self.current_interval > self.base_interval:
self.current_interval = max(self.current_interval * 0.8, self.base_interval)
text
When 429 error occurs:
1. Parse Retry-After header (if present)
2. Wait specified time OR current_interval × 2
3. Retry (max 3 times)
4. If still fails, log error and notify user
markdown
❌ Wrong approach:
Write 100 records at once
✅ Correct approach:
for batch in chunks(records, 10):
for record in batch:
feishu_bitable_create_record(record)
sleep(1) # 1s per record
sleep(5) # Extra 5s between batches
markdown
Priority:
1. Batch APIs (create_records, batch_update)
2. Single API + smart interval
3. Concurrent requests (reads only, use cautiously)
markdown
For frequently queried data:
- User info: Cache 24 hours
- Field definitions: Cache 1 hour
- Document structure: Cache 30 minutes
- Department list: Cache 2 hours
text
┌─────────────────┐
│ API Call │
└────────┬────────┘
▼
┌─────────────────┐
│ Check Response│
└────────┬────────┘
▼
┌────┴────┐
│ 429? │
└────┬────┘
│
┌────┴────────────────────────────┐
│ Yes │ No
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Check Retry-After│ │ Continue │
└────────┬────────┘ └─────────────────┘
▼
┌─────────────────┐
│ Wait specified │
│ OR interval×2 │
└────────┬────────┘
▼
┌─────────────────┐
│ Retries < 3? │
└────────┬────────┘
│
┌────┴────┐
│ Yes │ No
▼ ▼
┌─────────┐ ┌─────────────────┐
│ Retry │ │ Log error, notify│
└─────────┘ └─────────────────┘
yaml
feishu_rate_limit:
enabled: true
base_interval_ms: 1000 # Base interval 1s
max_interval_ms: 10000 # Max interval 10s
max_retries: 3 # Max retries
window_size_sec: 60 # Stats window 60s
warning_threshold: 50 # Warning threshold (calls/min)
batch_size: 10 # Batch size
batch_delay_ms: 5000 # Delay between batches
markdown
Task: Create 200 records
Strategy:
1. Split: 10 records per batch
2. Batch interval: 5 seconds
3. Record interval: 1 second
4. Estimated time: ~40 seconds
Implementation:
batch_1: 10 records → wait 5s
batch_2: 10 records → wait 5s
...
batch_20: 10 records → Done
markdown
Task: Write 50 paragraphs to document
Strategy:
1. Paragraph interval: 2-3s (Document API stricter)
2. Every 10 paragraphs: Extra 10s wait
3. Estimated time: ~3-4 minutes
Notes:
- Document API limits are stricter
- Double wait time on 429
markdown
Task: Read 100 records + update 50 records
Strategy:
1. Read operations: Can be concurrent
2. Update operations: Serial + 1s interval
3. Mixed: Wait after read before update
Recommendation:
- Batch read first (cacheable)
- Split updates into batches
PracticeDescriptionEstimate call volumeCalculate API calls before batch operationsBatch executionSplit large operations into multiple runsOff-peak callsAvoid peak hours (9-10am, 2-3pm) for intensive callsMonitor usageCheck Feishu backend API usage stats periodicallyGraceful degradationLog progress on limit, continue laterLog recordsTrack call count and duration for optimizationArchive errorsLog 429 errors to .learnings/ERRORS.md
Analysis:
Solution:
Analysis:
Solution:
SkillIntegrationproblem-solvingTrigger fix workflow on errorsfeishu-docApply rate limit to document operationsfeishu-archiveApply rate limit to archive operationsself-improving-agentLog rate limit events to learning journal
Version: 1.0.0
License: MIT