Rate limiting
plans: { "a": { "limiters": { "burst": { "seconds": 30, "rate": 30 }, "minute": { "seconds": 120, "rate": 60, }, "day": { "seconds": 86400, "rate": 2000 }, "dailywrite": { "seconds": 86400, "rate": 10240000, "type": "quota" } } }, "b": { "limiters": { "burst": { "seconds": 30, "rate": 60 }, "minute": { "seconds": 120, "rate": 180 }, "day": { "seconds": 86400, "rate": 20000 }, "dailywrite": { "seconds": 86400, "rate": 102400000, "type": "quota" } } },
Each limiter consists of properties like this – this means that in a window of 120 seconds a maximum of 60 operations are allowed – in other words 1 every 2 seconds, or 30 a minute on average
"minute": { "seconds": 120, "rate": 60, },
Firestore slotlimit document
Getting a slot
return dbStore.getSlotLimit (accountId).then (pack=> {
next we get the current time
const nowSecs = new Date().getTime()/1000;
look through each rate being checked
const ob = Object.keys(plan.limiters) .reduce((p,name)=>{ const co = plan.limiters[name];
figure out the slot based on the current time and the measurement window
const slot = Math.floor(nowSecs/co.seconds);
update the slot if we’ve moved on to a new measurement window from the last operation
p[name] = currentOb[name]; if (!p[name] || p[name].slot !== slot) { p[name] = { used:0, slot:slot }; }
increment the slot with the volume (if it’s a quota type – for example no. of bytes written per day) or by one if it’s a rate limited operation, and report and error if the limit is exceeded
p[name].used += (co.type === "quota" ? volume : 1); manage.errify( p[name].used <= co.rate, "QUOTA", name + " quota/rate limit exceeded", pack );
finish off the loop
return p; },{});
If we get here without recording an error – we can go ahead and write the updated rate to firestore
dbStore.setSlotLimit (accountId,ob)
otherwise report a quota violation