Error 141 - Getting rate limited when I shouldn't be

We’re using the Web3API function getTokenTransfers to fetch transfers. It works fine for small wallets. For bigger ones, we’re hitting error 141. More precisely:

{
  code: 141,
  error: 'This Moralis Server is rate-limited because of the plan restrictions. See the details about the current rate and throttle limits: {"x-rate-limit-limit":"1500","x-rate-limit-remaining":"60","x-rate-limit-remaining-ttl":"60","x-rate-limit-throttle-limit":"60","x-rate-limit-throttle-remaining":"5","x-rate-limit-throttle-remaining-ttl":"5","x-rate-limit-throttle-used":"212","x-rate-limit-used":"26"}'
}

Here’s the sample code:

const Moralis = require('moralis/node');
const moralisConfig = {
  "appId": "",
  "masterKey": "",
  "serverUrl": ""
}
Moralis.start(moralisConfig);

const chain = 'bsc';
const address = '0xc2aeac4502c9a55ea5e229ac26d481e7300f2516';

const offsets = [0, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 5500, 6000, 6500, 7000, 7500];
(async () => {
  for (const offset of offsets) {
    await Moralis.Web3API.account
      .getTokenTransfers({
        chain,
        address,
        offset,
      }).then((res) => {
        console.log(`Done processing offset ${offset}, result length = ${res.result.length}`);
      }).catch(console.log);
  }
})();

This fails at the 7000 offset request. How is the rate limit processed in the backend? Is it really per minute? Or is it more per second, (for pro servers 5000/3600 => 1.38 req/s)? Adding a local rate limiter alleviates the problem, but we’re looking for a more concrete answer, if available.

A close look at the error code, there’s two separate variables being tracked. That’s the rate-limit-throttle and rate-limit, with ttl and remaining/used variants. We could guess what they mean, but again, any official word would be appreciated.

Thanks!

1 Like

https://docs.moralis.io/misc/rate-limit#rate-limits-when-calling-web3-api-using-http

in particular, when pagination is used (with endpoints that don’t support cursor now), a higher offset will have a bigger impact on the limit. You will have to add some sleep/delay between making those requests with a bigger offset.

1 Like

We are working on adding cursor pagination
These rate limits will be removed for high-offset queries when we have it

read more: NFT Endpoints Temporary Offset Rate Limit

should be in January

2 Likes

Thanks for the quick replies, folks. Loud and clear.

2 Likes

+1. I have upgraded to the Pro version because I thought it would fix this error, but no luck. This is a big deal for us. We are building an app for the hackathon that needs to retrieve ALL transactions. Without this feature, the app fails. Is there any ETA for a fix? Any suggestion for a workaround?

you could add a bigger delay between requests now

which endpoint exactly?
what error exactly do you see?

Moralis.Web3API.account.getTransactions
Moralis.Web3API.token.getTokenMetadata
Moralis.Web3API.account.getTokenTransfers

please post exact request with all params

if its high offset params - we don’t have a solution right now, but in january we will

can you explain your use-case - seems like you have a script copying a lot of data from API to your DB? maybe we can propose other solutions

We are trying to retrieve all transactions and erc20 transfers for this wallet on polygon: 0x704111eDBee29D79a92c4F21e70A5396AEDCc44a.

Here’s the transaction fetch code. Fails even with 1 sec between requests.

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function getTransactions(_chain, _tokenAddress, _toBlock) {
  let options = {
    chain: _chain,
    address: _tokenAddress,
    order: "desc",
    offset: 0,
  };
  if (_toBlock) options.to_block = _toBlock;
  try {
    const result = await Moralis.Web3API.account.getTransactions(options);
    if (Number(result.total) > 500) {
      let page = 1,
        txFunctions = [],
        mergeResult = result.result;
      while (page < Math.ceil(result.total / 500)) {
        await sleep(1000);
        options.offset = page * 500;
        txFunctions.push(Moralis.Web3API.account.getTransactions(options));
        if (page % 1 === 0) {
          await Promise.all(txFunctions)
            .then((results) => {
              results.map((each) => {
                mergeResult = mergeResult.concat(each.result);
              });
            })
            .catch((e) => console.log(e));
          txFunctions = [];
        }
        page++;
      }
      if (txFunctions.length) {
        await Promise.all(txFunctions)
          .then((results) => {
            results.map((each) => {
              mergeResult = mergeResult.concat(each.result);
            });
            return mergeResult;
          })
          .catch((e) => console.log(e));
      } else return mergeResult;
    } else return result.result;
    return result.result;
  } catch (e) {
    console.log("get transactions error", e);
    return null;
  }
}

Use Moralis Server to sync user https://docs.moralis.io/moralis-server/automatic-transaction-sync/historical-transactions#watch-address-from-code

it will appear in moralis DB


you see how much each request in the API uses by lookiing at x-rate-limit-used and you see how much you have left in the minute by looking at x-rate-limit-remaining

high offset queries to the API are temporarily expensive as we scale (ETA jan) NFT Endpoints Temporary Offset Rate Limit


For now - learn how to sync user transactions using the server

I tried this:

  const results2 = await Moralis.Cloud.run("watchMaticAddress", {
    address: data.wallet,
    sync_historical: true,
  });

and got this error

Error: Invalid function: "watchMaticAddress"
    at handleError (D:\cost_basis_ab\node_modules\moralis\lib\node\RESTController.js:423:17)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async getWalletCostBasis (D:\cost_basis_ab\server5.js:230:20) {message: 'Invalid function: "watchMaticAddress"', code: 141, stack: 'Error: Invalid function: "watchMaticAddress"
…iReturn Code\cost_basis_ab\server5.js:230:20)'}

I also added this address through the Moralis admin. It says it is “currently synching” but in the dashboard, only a few Eth transactions are showing up. No Polygon txs.

Also tried to run a job to sync the polygon txs:

Please create a new issue for this as it’s off topic from API rate limit - we will help there

thanks