Skip to content

Conversation

@JonPurvis
Copy link
Contributor

Fixes saloonphp/saloon#392

This PR fixes a bug with the Memory Store which was causing all requests that run through it, to have their own store which was then causing rate limits to not work correctly. If you execute 50 requests, for example, then each of them creates a new MemoryStore instance.

The HasRateLimits trait caches the store per request:

public function rateLimitStore(): RateLimitStore
{
    return $this->rateLimitStore ??= $this->resolveRateLimitStore();
}

But when you do return new MemoryStore;, each request instance gets a different MemoryStore object, each with its own isolated $store array and because of this, they can't share the rate limit.

The solution is to change $store to a static property so all instances share the same storage. This makes the rate limit work across multiple request instances.

You can see below the rate limit code I had in my connector and then a before and after of my results running the exact same test:

protected function resolveLimits(): array
{
    return [
        Limit::allow(1)->everySeconds(1)->sleep()
    ];
}

protected function resolveRateLimitStore(): RateLimitStore
{
    return new MemoryStore;
}
Before After
Screenshot 2025-12-02 at 21 02 19 Screenshot 2025-12-02 at 21 04 21

@Sammyjo20 Sammyjo20 merged commit 67e82ca into saloonphp:v2 Dec 9, 2025
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rate Limit Plugin: Issue with 'allow(1)->everySeconds(1)->sleep()' Exceeding One Request per Second

2 participants