Back to notes

June 16, 2026 · 5 min read

An API Rate Limit We Didn't Know Existed Took Down Reporting

A documented rate limit we'd read and planned around wasn't the one that hurt us. The undocumented one was.

PostmortemEngineering

We'd carefully engineered our ad platform API integration around the published rate limits — requests per minute, documented and respected with backoff logic to spare. Reporting still went dark for six hours one Tuesday, because the limit that actually hit us wasn't in the documentation at all.

What actually happened

The platform enforced a separate, undocumented concurrent-connection limit distinct from the requests-per-minute limit we'd engineered around. Our pipeline was well under the published rate limit the entire time, but a batch job that fanned out into parallel requests for faster processing tripped the concurrency ceiling, and every request started returning a generic error that our error handling didn't distinguish from a transient network blip.

We respected every limit the vendor documented. The one that took us down was the one they didn't bother to write down.

How we found it

Not from the vendor's error messages, which were uselessly generic. We found it by trial and error — manually reducing our concurrency in steps until the errors stopped, then confirming the threshold by testing just above and below it. Only after reproducing it reliably did vendor support confirm, almost as an afterthought, that yes, there's a concurrency cap, it's not published, and it varies by account tier.

  • Generic error responses from a third-party API should be treated as a potential rate limit until proven otherwise, not just retried blindly.
  • We added explicit concurrency throttling independent of request-rate throttling, since the two limits turned out to be enforced completely separately.
  • We now ask vendors directly about concurrency limits during integration scoping, since published rate-limit docs frequently don't mention them.
  • Retry-with-backoff logic that doesn't distinguish failure types can mask a systemic limit as a series of unrelated transient errors, which delayed our diagnosis by hours.

The fix was simple once we found the real constraint. The expensive part was the six hours spent debugging against documentation that described a different limit than the one actually enforced, which is a reminder that a vendor's docs describe their intentions, not necessarily their infrastructure's actual behavior.