Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

How to get all inventory levels at a location quickly?

How to get all inventory levels at a location quickly?

Tim_Richardson
Shopify Partner
15 1 2

I am migrating some code from REST to GraphQL.
The REST API code queries inventory levels and uses the updated_at filter to find only levels which have changed since last time, and it is specific to a specific location
That is, it uses
url = self.shop_url + f"/inventory_levels.json" with the parameter 'updated_at_min' and "location_ids"

I have code which gets inventory levels by a query on inventoryItems : a fragment of my query (composed in python) is:

 

query($cursor: String)  {{
          inventoryItems(first: 250, after: $cursor) {{
            edges {{
              node {{
                id
                tracked
                sku
                inventoryLevel(locationId: "{location_filter}") {{
                  id
                  updatedAt
                  quantities(names:["available"]) {{
                    quantity
                    name

 


but I can't use updated_at with inventoryLevel here, and it visits every inventory item with no location filter.
This is way too slow.

What should I do?

 

Replies 5 (5)

Ablestar_Daniel
Shopify Partner
136 23 47

Hi @Tim_Richardson,

 

Like you mentioned there doesn't seem to be an GraphQL query that lets you filter inventory levels directly, you need to get there through the InventoryItem relationship. Having an inventoryLevels (similar to inventoryItems) GraphQL query would be helpful for us too.

 

I'm not sure of a perfect solution but here's two ideas I had (and one I tested that didn't work):

 

Bulk operations

One option would be running a bulk operation to export all the inventory levels at once. In short, you would:

  1. Create a bulk operation with the GraphQL data you wanted (InventoryItem + all their related InventoryLevels)
  2. Poll the API until the job completes (or get a webhook update)
  3. Download a JSON file with all the inventory levels

Then locally you could parse that filter and identify the inventory levels you need changed. You'd have to benchmark it to get an exact idea of how long it'd take but generally it should be faster than looping through all the data. One limitation though is that you can only have a single bulk operation running per store at a time.

 

Tracking updates with webhooks

If you subscribe to the inventory_levels/update webhook you'll get a JSON payload sent to your server each time an inventory level gets updated. You could store the inventory item ID, location ID, quantity in a database and then query that for when you needed find data changed within a certain time. This does require more work to get setup, especially if you're dealing with stores that could have thousands of inventory level updates in a short time.
 
What didn't work

One thing I tried that didn't work was to see if InventoryItem.updated_at changes when a linked inventory level changes. It wouldn't be perfect but you could filter out some of the InventoryItems that way. Unfortunately InventoryItem.updated_at doesn't change when an associated inventory level is updated. Just including this here to save any one time if they had the same thought.

 

Like I mentioned, I don't know of a perfect solution but I hope this helps some. Best,

Daniel

Founder @ Ablestar ✦
Manage product data, spreadsheets, Google Shopping data, and metafields with Ablestar Bulk Product Editor. Use previews, undos, and automations to be confident your product data is correct.
Please don't forget to Like and Mark Solution to the post that helped you. Thanks!
Tim_Richardson
Shopify Partner
15 1 2

Thanks for your reply. I also weighed up both of those options. Webhooks will be transactionally heavy I fear, but could potentially be interesting as a solution. It would be the solution with the least latency, which is very attractive.


I started coding a bulk query solution, since I figured I may as well learn about it. But it also seems like overkill for this. And the risk of getting stuck behind another job is not a risk I can take for this requirement.

 

However, in the short term I will do a hybrid: I will keep using the REST API for inventory levels, since it is much faster and very simple (I already have the code so I can't be any worse off by continuing to use it), and use graphql for updating stock (where it is the REST API which is stupidly inefficient, as far as I know how to use it). There is no notification of deprecation for this REST endpoint.

 

This is a big gap in the GraphQL API, in my opinion. So big I couldn't believe it, I thought I was doing something wrong, but you have confirmed it. Thanks for your thoughtful answer.

Ablestar_Daniel
Shopify Partner
136 23 47

Yeah, the GraphQL APIs for updating a bunch of inventory at once are really nice. A lot more efficient than doing them one by one with the REST API.

 

I didn't realize that the REST InventoryLevel APIs don't have the API deprecation header set in the responses, that's good to know, thanks! My guess is eventually they'll be deprecated in favor of GraphQL but that buys you a good bit more time (for example, if they announce the upcoming deprecation next year it'll probably be a year after that when it actually gets deprecated)

Founder @ Ablestar ✦
Manage product data, spreadsheets, Google Shopping data, and metafields with Ablestar Bulk Product Editor. Use previews, undos, and automations to be confident your product data is correct.
Please don't forget to Like and Mark Solution to the post that helped you. Thanks!

Eric-HAN
Shopify Partner
273 30 29

Hi ,there 

For use updated_ad as filter you could refer to this .

query GetInventoryItems {
  inventoryItems(first: 10, query: "updated_at:>'2024-08-01T00:00:00+00:00'") {
    edges {
      node {
        id
        sku
        updatedAt
        inventoryLevel(locationId: "gid://shopify/Location/xxx") {
          id
        }
      }
    }
  }
}

EricHAN_0-1724399240259.png

 

- Helpful? Please hit Like and mark it as a solution
Want to modify or custom changes on store? Let me help.
- Feel free to Email Me    Buy Me A Coffee
Tim_Richardson
Shopify Partner
15 1 2

Ah yes, but does an inventory level change cause a change in the inventoryItem updated_at? I assumed not, so it doesn't help.