Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Bitfinex Rate Limiting
import { RateLimiter } from 'limiter';
import createDebug from 'debug';
const debug = createDebug('koh:bitfinex:limiter');
const LOWER_MAX_REQUESTS_PER_MINUTE = 10;
const UPPER_MAX_REQUESTS_PER_MINUTE = 90;
const MIN_TOKENS_PER_MINUTE = 1;
const MAX_TOKENS_PER_MINUTE = UPPER_MAX_REQUESTS_PER_MINUTE / LOWER_MAX_REQUESTS_PER_MINUTE;
const DEFAULT_TOKENS_PER_MINUTE = (MIN_TOKENS_PER_MINUTE + MAX_TOKENS_PER_MINUTE) / 2;
const REDUCE_TOKENS_INTERVAL = 1000 * 90;
// From https://docs.bitfinex.com/v1/docs
//
// If an IP address exceeds a certain number of requests per minute (between 10 and
// 90) to a specific REST API endpoint e.g., /ticker, the requesting IP address
// will be blocked for 10-60 seconds on that endpoint and the JSON response
// {"error": "ERR_RATE_LIMIT"} will be returned. Please note the exact logic
// and handling for such DDoS defenses may change over time to further
// improve reliability.
export default function createLimiter() {
debug(`Creating limiter with options: %O`, {
LOWER_MAX_REQUESTS_PER_MINUTE,
UPPER_MAX_REQUESTS_PER_MINUTE,
MIN_TOKENS_PER_MINUTE,
MAX_TOKENS_PER_MINUTE,
DEFAULT_TOKENS_PER_MINUTE,
});
let tokensPerRequest = DEFAULT_TOKENS_PER_MINUTE;
let reduceTokensTimer;
const bitfinexLimiter = new RateLimiter(LOWER_MAX_REQUESTS_PER_MINUTE, 'minute');
const waitForBitfinexLimiter = () => new Promise(resolve => bitfinexLimiter.removeTokens(tokensPerRequest, resolve));
const doubleTokensPerRequest = () => {
const prevTokensPerRequest = tokensPerRequest;
tokensPerRequest = Math.min(MAX_TOKENS_PER_MINUTE, tokensPerRequest * 1);
if (prevTokensPerRequest !== tokensPerRequest) {
debug(`Tokens per request increased to ${tokensPerRequest}`);
}
if (reduceTokensTimer) {
clearInterval(reduceTokensTimer);
reduceTokensTimer = null;
}
reduceTokensTimer = setInterval(() => {
const prevTokensPerRequest = tokensPerRequest;
tokensPerRequest = Math.max(MIN_TOKENS_PER_MINUTE, tokensPerRequest / 2);
if (prevTokensPerRequest !== tokensPerRequest) {
debug(`Tokens per request reduced to ${tokensPerRequest}`);
}
}, REDUCE_TOKENS_INTERVAL);
reduceTokensTimer.unref();
};
return {
waitForBitfinexLimiter,
doubleTokensPerRequest,
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.