{"action":"created","issue":{"url":"https://api.github.com/repos/Shopify/shopify_api/issues/51","repository_url":"https://api.github.com/repos/Shopify/shopify_api","labels_url":"https://api.github.com/repos/Shopify/shopify_api/issues/51/labels{/name}","comments_url":"https://api.github.com/repos/Shopify/shopify_api/issues/51/comments","events_url":"https://api.github.com/repos/Shopify/shopify_api/issues/51/events","html_url":"https://github.com/Shopify/shopify_api/issues/51","id":15099047,"number":51,"title":"API calls need to return the time that the api limit will reset","user":{"login":"lastobelus","id":25810,"avatar_url":"https://avatars1.githubusercontent.com/u/25810?v=3","gravatar_id":"","url":"https://api.github.com/users/lastobelus","html_url":"https://github.com/lastobelus","followers_url":"https://api.github.com/users/lastobelus/followers","following_url":"https://api.github.com/users/lastobelus/following{/other_user}","gists_url":"https://api.github.com/users/lastobelus/gists{/gist_id}","starred_url":"https://api.github.com/users/lastobelus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lastobelus/subscriptions","organizations_url":"https://api.github.com/users/lastobelus/orgs","repos_url":"https://api.github.com/users/lastobelus/repos","events_url":"https://api.github.com/users/lastobelus/events{/privacy}","received_events_url":"https://api.github.com/users/lastobelus/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2013-06-04T02:14:24Z","updated_at":"2017-04-25T01:39:56Z","closed_at":"2014-01-10T15:17:08Z","body":"# TLDR\n\nI want to be a good citizen with respect to API limit. Because my app has both internal and external concurrency, I can't unless I know when the api limit will reset.\n# Detailed description\n\nWithout knowing when the api limit will reset I can't avoid spamming you, in any customer-facing app functionality (example: shipping calculation)\n\nIf I'm making requests in a single threaded single user tool, I can keep track of API usage & timing and it will more or less work (although I'll still occasionally spam you when another app is using up calls)\n\nBut for the things like shipping rate calculation, I can't get away with sequential calls to the api, it adds too much latency to a process that already typically has 3-7 seconds latency. To be a good citizen I want to fire 1 api request, check the limit, then fire the rest in parallel. Thus my app has **internal concurrency** \n\nI used typhoeus/hydra to do this, setting the concurrency to 20 instead of the default 200 and adding an on-complete to each request to pause/cancel the hydra if any request hits the api limit.\n\nHowever, if there is not enough requests left, I have no idea how long to sleep. Even if I always bail on requests instead of sleeping and retrying, the web app itself still has however much **external concurrency** we buy on heroku -- the minimum is 3-4 for a free app, using unicorn. So if 2 or 3 requests overlap, some of them will end up spamming you (unless I wanted to make it so my whole web app stalls for 5 minutes whenever I bump against the api limit, which my clients would not be very happy with)\n\nIf you were to tell me in a header in each api response the time the api limit is going to reset, I could track that globally using memcached, and be a good citizen. All incoming requests to my app could check the api call headroom & the time when it will reset and decide whether to wait for the reset or bail. I would occasionally spam you when some other app bumped against the api limit, but usually with only 1 request in a 5 minute block (occasionally with a parallel block of requests when the other app used up the limit in between my checking and firing my parallel block of requests)\n\nMy clients (who are also your clients) would benefit, because the app will seem faster under load (requests only bail when they have to, and only stall as long as they need to)\n\nIf you add this header, I promise to package & publish on github my typhoeus-based client that uses it to be a good, mostly non-spamming fast api consumer.\n"},"comment":{"url":"https://api.github.com/repos/Shopify/shopify_api/issues/comments/296867361","html_url":"https://github.com/Shopify/shopify_api/issues/51#issuecomment-296867361","issue_url":"https://api.github.com/repos/Shopify/shopify_api/issues/51","id":296867361,"user":{"login":"jamiemtdwyer","id":16005948,"avatar_url":"https://avatars3.githubusercontent.com/u/16005948?v=3","gravatar_id":"","url":"https://api.github.com/users/jamiemtdwyer","html_url":"https://github.com/jamiemtdwyer","followers_url":"https://api.github.com/users/jamiemtdwyer/followers","following_url":"https://api.github.com/users/jamiemtdwyer/following{/other_user}","gists_url":"https://api.github.com/users/jamiemtdwyer/gists{/gist_id}","starred_url":"https://api.github.com/users/jamiemtdwyer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamiemtdwyer/subscriptions","organizations_url":"https://api.github.com/users/jamiemtdwyer/orgs","repos_url":"https://api.github.com/users/jamiemtdwyer/repos","events_url":"https://api.github.com/users/jamiemtdwyer/events{/privacy}","received_events_url":"https://api.github.com/users/jamiemtdwyer/received_events","type":"User","site_admin":false},"created_at":"2017-04-25T01:39:56Z","updated_at":"2017-04-25T01:39:56Z","body":"The API call limit is a leaky bucket algorithm with a bucket size of 40 and a leak rate of 2/sec. The number of calls remaining are represented in an HTTP header value."}}
{"actor":{"display_login":"jamiemtdwyer"}}