Contentful logo

Contentful Community

Rate limit error even after adding ratelimit listner while creating CMAClient java

I am using cma sdk and java sdk maven dependencies in my project. I have added ratelimit listner while creating CMAClient. In the listner class, I check whether the hourly limit is reached. if yes then I wait for say 2mins. if hourly limit is not reached then I check whether seconds limit is reached and wait for secs which i get from reset. Even after adding this I am getting the ratelimit error after some point of time.

Code where I add rate limitListner while creating cma client.

CMAClient cmaClient = new CMAClient.Builder().setAccessToken(Info.getContentfulToken()).setSpaceId(Info.getSpaceId()).
			setRateLimitListener(new ContentfulRateLimitsListner(logger)).build();

Overriden method of RateLimitListner:

@Override
	public void onRateLimitHeaderReceived(RateLimits rateLimits) {
		if (rateLimits.getHourRemaining() != 0) {
			if (rateLimits.getReset() != 0) {
				try {
					Thread.sleep(rateLimits.getReset()*1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} else  if (rateLimits.getHourRemaining() == 0) {
			try {
				Thread.sleep(30*1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

Am I making any mistake. help would be really appreciated.

Hi there,

Do you have any concurrent requests being sent to our API? Rate limits are enforced on the basis of your space or organization, depending on what plan you’re on so other processes would surely also affect your API rate limit across your entity.

Bumping this. I can’t speak for OP, but I am running across rate limit issues even when I force a wait of 1.5 seconds per entry for any of the CRUD functions available in Contentful’s JS SDK. Aside from some possible very long roundtrip lag to your API, we do not have concurrent requests being sent to your API. We are under the Enterprise plan for a single space. We don’t have any users interacting in the space yet, so it’s just me hitting the API for that space.

Hi Lauren,

Could you send us a support ticket using this form?

With that, we can discuss in further detail your specific use case and perhaps discuss with a product expert a better way to structure your application and avoid these rate limit issues.

Hi gabriel,

Thanks for the quick reply. I have a different question now. Using the JS SDK, how do I read the response headers from your axois request to your API? I would like to use the rate limit ms amount in my code. If the promise resolves, then I only get back entry information. I can’t get my promise to reject, despite the console writing out the rate limit warning. Your API docs indicate that rate limits are errors, as they are over status code 300, but I can’t seem to catch these, nor view any response header information in general.

I’ve tried putting break points in the contentful-management > error-handler.js, but this doesn’t get hit either.

Regarding the previous issue I mentioned having, and why it is no longer an issue:
I am not a JS developer, and did not know about the messaging queue/event loop. Due to this, I had a faulty implementation (and misunderstanding) of setTimeout(). Details below for anyone else who’s struggling with setTimeout:

// using javascript
for (let i = 0; i < 10; ++i) {
setTimeout(function () { console.log(i) }, 1000) //setTimeout is not part of the JS spec. it’s part of JS runtime environment
}

This will not wait 1 second before running a console.log. setTimeout, while it will be put on the stack momentarily, before popping off to run itself, pushes the console.log function into the messaging queue after at least 1000ms. The messaging queue is not looked at, until the regular call stack is clear. So once the for loop finishes popping itself off the stack, the message queue will be checked, before re-pushing/popping off the stack each console.log.

What I needed instead, was setInterval(), which will run a function after every period of time. And yes, this function call nicely avoids the rate limit

My apologies.