Skip to content

allan7yin/rate-limiter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SafetyGopher

GopherGate - Simple Rate Limiter in Go

A simple and reusable request rate-limiting microservice that protects external applications' endpoints.


Performance

This was designed to handle just under 1,000,000 requests per minute. To tune for this, the service is designed to handle ~16,667 requests per second. Maximum bucket size is how many requests that can be handled under bursty conditions, which this service sets as 5 seconds. So, refill rate set to 16,667 tokens per second, with a maximum bucket size of 83, 335 tokens.

To simulate these conditions in Jmeter, the following configuration was used:

  • 500 threads
  • 10 second ramp up time
  • 2000 loop count

The results of this are:

BaseMetric

Idea

This limiter uses Redis as a token bucket due to its performance in distributed settings. Below is a simple illustration of what the system is like:

const (
	MAX_BUCKET_SIZE float64 = 10
	REFILL_RATE     int     = 1
)

type TokenBucket struct {
	currentBucketSize   float64
	lastRefillTimestamp int64
}

func (tb *TokenBucket) allowRequest(tokens float64) bool {
	tb.refill()

	if tb.currentBucketSize >= tokens {
		tb.currentBucketSize -= tokens
		return true
	}

	return false
}

func getCurrentTimeInNanoseconds() int64 {
	return time.Now().UnixNano()
}

func (tb *TokenBucket) refill() {
	nowTime := getCurrentTimeInNanoseconds()
	elapsedTime := nowTime - tb.lastRefillTimestamp
	tokensToAdd := float64(elapsedTime) * float64(REFILL_RATE) / 1e9 * 2
	tb.currentBucketSize = math.Min(tb.currentBucketSize+tokensToAdd, MAX_BUCKET_SIZE)
	tb.lastRefillTimestamp = nowTime
}

About

Rate-Limiter With Token Bucket Algorithm

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages