Depends on whether you want IP-based rate-limiting in which case I would add something like Cloudflare workers to the mix. If you want Identity-based rate-limiting you can implement that straight from FQL. That approach will incur reads but will reduce the amount of reads and discourage the user since they won’t receive data but will be blocked. If you only perform a get by reference then your reads are of course === 1 and then this approach would actually add reads. So if you are concerned about that I would add CF in the mix. All depends on whether you trust your users or not and can make them accountable for their actions.
These articles also talk about similar things:
Finally, an approach that I did not explore myself already but could work theoretically.
If you use third-party auth (of course, that’s a higher tier), I know for example that Auth0 has the capability to add geolocation (or IP?) to the token. You could opt to add that to the token and write a security role that blocks access after a few calls. Anything you do of course requires you to keep track of the amount of requests which requires some kind of write and read. So in your situation it’s probably not going to help. Single gets are already super cheap
I’m not sure how that works in Cloudflare, whether you would still pay a small fraction when users do a ddos attack which Cloudflare successfully blocks. Some process has to run so I assume there is always some kind of cost (but maybe Cloudflare takes that cost for them).