Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Continuously hitting the GitHub secondary rate limit even after following the best practices?

In my application I am making authenticated requests to the GitHub search API with a token. I am making a request every 2s to stay within the primary rate limit of 30 reqs per minute (so not concurrently) and I am also validating every request with the GitHub rate limit API before I make the actual search API call.

Even in the rare case of accidental concurrent requests, they are not likely to be for the same token.

I seem to be following all the rules mentioned in the Primary and Secondary best practices documentation. Despite this my application keeps getting secondary rate limited and I have no idea why. Could anyone help me with why this may be happening?

EDIT:

Sample code:

const search = async function(query, token) {
    var limitResponse;
    try {
        limitResponse = JSON.parse(await rp({
            uri: "https://api.github.com/rate_limit",
            headers: {
                'User-Agent': 'Request-Promise',
                'Authorization': 'token ' + token
            },
            timeout: 20000
        }));
    } catch (e) {
        logger.error("error while fetching rate limit from github", token);
        throw new Error(Codes.INTERNAL_SERVER_ERROR);
    }
    if (limitResponse.resources.search.remaining === 0) {
        logger.error("github rate limit reached to zero");
        throw new Error(Codes.INTERNAL_SERVER_ERROR);
    }
    try {
        var result = JSON.parse(await rp({
            uri: "https://api.github.com/search/code",
            qs: {
                q: query,
                page: 1,
                per_page: 50
            },
            headers: {
                'User-Agent': 'Request-Promise',
                'Authorization': 'token ' + token
            },
            timeout: 20000
        }));
        logger.info("successfully fetched data from github", token);
        /// process response
    } catch (e) {
        logger.error("error while fetching data from github" token);
        throw new Error(Codes.INTERNAL_SERVER_ERROR);
    }
};

Sample Architecture:

A query string (from a list of query strings) and the appropriate token to make the API call with is inserted into a rabbitmq x-delayed queue, with a delay of index*2000s per message (hence they are spaced out by 2s) and the function above is the consumer for that queue. When the consumer throws an error, the message is nack'd and sent to a dead letter queue.

const { delayBetweenMessages } = require('../rmq/queue_registry').GITHUB_SEARCH;
await __.asyncForEach(queries, async (query, index) => {
    await rmqManager.publish(require('../rmq/queue_registry').GITHUB_SEARCH, query, {
            headers: { 'x-delay': index * delayBetweenMessages }
    })
})
like image 518
Soumik Sur Avatar asked Jan 19 '26 20:01

Soumik Sur


2 Answers

Looks like there is not an issue in your code. I was just surfing from my browser and was using github search bar, and I hit secondary rate limit from browser by just surfing. So, looks like search API is internally using concurrency. So, might be it is github's own bug.

like image 82
Munir Avatar answered Jan 22 '26 14:01

Munir


You hardcoded a sleep time of 2s, but, according to the documentation, when you trigger the secondary api rate limit you have to wait a time same as the one indicated in the Retry-After attribute of the response header.

like image 31
mrosa Avatar answered Jan 22 '26 14:01

mrosa



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!