Skip to content
Back

How to bypass the rate limit on the backend calls?

  • 0
  • Databases
  • Web
  • Cloud
martins4
13 May, 2026, 10:05

Once a month my app has a ton of usage and I always run into the Too many requests 429 error.

I am trying to optimize the queues and jobs to manage that, but as the platform is getting more and more users, I am not able to optimize it and running that in enough time.

I have seen I could use the dev api key, to bypass that limit.

Is that a good practice? Or what other options do I have?

Thanks

TL;DR
The user is experiencing rate limit errors on backend calls even though rate limits are supposed to apply to specific IPs or users. They are using API keys for server-side authentication and have ruled out JWT authentication. Possible causes are an issue with the API key implementation or hitting service abuse/concurrency limits. The solution suggested is to add a local queue broker like Redis/BullMQ or Bee-Queue to cap the concurrent execution rate. They are also advised to share a demo app to help identify the problem. The max RPS limit depends on the endpoint. The specific function causing rate limits is a membership renewal function making multiple collection updates and inserts.
martins4
13 May, 2026, 10:11

/**

  • Pace an Appwrite SDK call through the global token bucket. Retries on 429
  • with exponential backoff + jitter, respecting Retry-After / `X-RateLimit-
  • Reset` when present. Any non-429 error is rethrown immediately.
  • Usage:
  • const doc = await withAppwriteCall(() =>
  • TypeScript
    tablesDB.getRow({ databaseId, tableId, rowId })
    
  • )
  • Wrap at the REPO boundary, not at every call site โ€” see the repo files for
  • the canonical pattern. */ export async function withAppwriteCall<T>( fn: () => Promise<T>, opts: WithAppwriteCallOptions = {} ): Promise<T> { const maxRetries = opts.maxRetries ?? MAX_RETRIES const label = opts.label ?? 'appwrite' let attempt = 0

while (true) { const { waitedMs } = await acquireToken() stats.calls += 1 stats.totalWaitMs += waitedMs if (waitedMs > 0) stats.throttleWaits += 1

TypeScript
try {
  return await fn()
} catch (err) {
  if (!isRateLimitError(err)) throw err

  // 429 โ€” apply retry logic.
  stats.rateLimitHits += 1
  if (attempt >= maxRetries) {
    throw new AppwriteThrottleExhausted(
      `[${label}] giving up after ${attempt + 1} attempts on 429`,
      attempt + 1
    )
  }
  stats.retries += 1
  const explicit = readRetryAfter(err)
  const sleepMs = explicit ?? backoffMs(attempt)
  console.warn(
    `[throttle] ${label} 429 attempt=${attempt + 1}/${maxRetries + 1} sleep=${sleepMs}ms (${explicit ? 'retry-after' : 'exponential'})`
  )
  await sleep(sleepMs)
  attempt += 1
  // Loop continues; we'll acquire a fresh token and retry.
}

} } also tryied using this

martins4
14 May, 2026, 09:17

<@462046107556511744> Please need help

Arhan Ansari
14 May, 2026, 09:20

<@743532656767270934> any idea abt this?

Arhan Ansari
14 May, 2026, 09:21

Bro steven is not in core team anymore

Meldiron
14 May, 2026, 09:24

Hey ๐Ÿ‘‹

Rate limits should apply to specific IPs or users. I dont think spike of users active should cause rate limits.

Curious, do you use SSR capabilities without API key or session secret? Doing that might introduce global rate limit that you might be hitting.

As for dev keys, I would not recommend to use them on production, bad actor could use such dev key to harm your project.

martins4
14 May, 2026, 09:26

Checking it rn

martins4
14 May, 2026, 16:37

I have checked the codebase and not sure if i am using SSR capabilities

martins4
14 May, 2026, 16:40

I mean we are using API KEY for sure on the server side.

And we call that using the cron, with a valid key.

.setKey(env.APPWRITE_API_KEY), and every Appwrite SDK call goes through that wrapped handle. Per-user JWT calls in verifyJwt.ts:15 use .setJWT(jwt), which is also a valid auth path (per-user bucket).

martins4
14 May, 2026, 16:49

This being said, it should be impossible for me to be getting 429 errors in the cron runs from the server. I am using concurrent jobs, might that have anything to do?

martins4
14 May, 2026, 16:49

<@287294735054274560> need help to solve this please

martins4
14 May, 2026, 17:02

<@743532656767270934> any idea on this?

martins4
14 May, 2026, 17:14

Please, I really need to solve this

martins4
14 May, 2026, 17:30

<@1231860789355347971>

๐”ธ๐•๐•จ๐•’๐•ง๐•–๐Ÿ˜๐ŸŸ โœจ
14 May, 2026, 21:24

Use the Server SDK

๐”ธ๐•๐•จ๐•’๐•ง๐•–๐Ÿ˜๐ŸŸ โœจ
14 May, 2026, 21:24

It has no rate limits I believe

Devika
15 May, 2026, 04:07

Is there any possibility that this could be happening because some of the calls are using JWT auth instead of only API-key-based server calls?

martins4
15 May, 2026, 05:46

not from the server

martins4
15 May, 2026, 05:46

i mean the front defenitely uses authenticted calls

martins4
15 May, 2026, 05:47

But then the back is checking the jwt for calls comming from the front and then does whatever with the api key

martins4
15 May, 2026, 05:47

And of course the cron function is also using API KEY

Meldiron
15 May, 2026, 07:46

<@613275686060294145> Morning โ˜€๏ธ

Interesting indeed, can you share exact error message you are getting, and a piece of code that causes it? Alternatively, could you make a tiny demo app with just this concept?

I ask because once I can reproduce it, should be easily solvable

martins4
15 May, 2026, 07:51

Yes, I am on it

martins4
15 May, 2026, 07:53

Once I hit the rate limit this was the errors I was getting

martins4
15 May, 2026, 07:54

I guess the piece of code can not be shared because it is an entire queue/jobs structure working on 4000 pieces of data that needed to be treated, that treatment is absolute core for our platform

Reply

Reply to this thread by joining our Discord

Reply on Discord

Need support?

Join our Discord

Get community support by joining our Discord server.

Join Discord

Get premium support

Join Appwrite Pro and get email support from our team.

Learn more