Mass update stock levels in Magento - FAST

This isn't ground-breaking code, but rather just using some core code in a rather stripped out manner. As we're not big fans of Magento data flow here, we perform most of our stock and catalogue updates using external scripts to Mage::app. We have been trickling elements of these out to the wider world so you can also benefit from them.

Managing large catalogues and updating stock levels regularly can be mission impossible in Magento, but not any more. With this script - we processed 120,000 stock updates in the blink of an eye. Next time we'll teach you how to import products at 0.7 seconds each ...

  • Create a CSV with a minimum of 2 columns, the SKU and any of the following,


    Then save it to ./app/var/import/updateStockLevels.csv. For examples sake, we will use,

  • Copy the code below into a new file, ./quick_updateStock.php

    $count = 0;
    $file = fopen(MAGENTO . '/var/import/updateStockLevels.csv', 'r');
    while (($line = fgetcsv($file)) !== FALSE) {
        if ($count == 0) {
            foreach($line as $key => $value) {
                $cols[$value] = $key;
        if ($count == 1) continue;
        // Convert the lines to cols
        if ($count > 0) {
            foreach($cols as $col => $value) {
                unset($ {
                $ {
                } = $line[$value];
        // Check if SKU exists
        $product = Mage::getModel('catalog/product')->loadByAttribute('sku', $sku);
        if ($product) {
            $productId = $product->getId();
            $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productId);
            $stockItemId = $stockItem->getId();
            $stock = array();
            if (!$stockItemId) {
                $stockItem->setData('product_id', $product->getId());
                $stockItem->setData('stock_id', 1);
            else {
                $stock = $stockItem->getData();
            foreach($cols as $col => $value) {
                $stock[$col] = $line[$value];
            foreach($stock as $field => $value) {
                $stockItem->setData($field, $value ? $value : 0);
        echo "Stock updated $sku";
  • Visit the file above in your browser, or via command line. It runs very quickly (approx 0.03 seconds per product), so don't be too surprised if its over quickly!
  • Pingback: Mass update stock levels in Magento – FAST | Manchester Magento … | Magento News()

  • Tj

    This is great! I have a multiple website install with different B2B setups as well as retail site, all of which have different pricing structures.

    Perhaps you guys could do a post for fast updating of prices by store?

    • We certainly could do (in fact, have done), although for pricing - it does take a little longer for product saves, around 0.8s per product.

      • Hey Ben,
        could you post a link to the mass update price article? If I could simply create two columns, sku and price, and update all my existing prices, that would be awesome!


        • Hi Bukie,

          I don't think I've written one up yet, so I'll need to put a guide together for it.

      • I am looking to do this as well with product pricing. Currently magento dataflow takes 10.5 hoursto update pricing and i will need to to run it for 4000 products. I've tried on the current script to change the $stockItem = Mage::getModel('catalog/product')->loadByProduct($productId); But thatdoesn't seem to work. I would even pay to have this work, just not a ton as i know i'm close in my train of thought. Please let me know if you can assist

    • Perhaps we could, but we tend to only post code that has related to client work. By all means, get in touch for a quote - then we can do the work and post the code for the world to see!

  • sean

    Great information, thanks. Looking forward to your post on importing products quickly. I actually need to figure out that aspect of my site right away, but hopefully it will pop up while I work on some other things!

  • Ted

    Great Post guys. Thank You.
    Any idea when we can expect the mass products import script?

  • Anh Nguyen

    OMG, this is such a beautiful work. Magento's importing sucks. I have to spend hours for importing 1000 product stocks. Thank you so much!

  • N

    "Next time we’ll teach you how to import products at 0.7 seconds each …"

    Really looking forward to this...

    Great work on the above script!

  • Hi,

    I've been using your module with great succes. I only have a few problems. The stock check seems to slow down significantly when i have it running a longer period. I have a shop with about 18.000 products.

    When i start the import it does about 20 products per second, but by the time I reach the 8000th product it does only 1.5 products per second.

    I tried calling the Mage::reset() function and then Mage::app()->etc. but that doesn't matter.

    Do you have any solution for

  • Great script! Any chance you've done something similar to change the 'visibility' attribute to a group of products?

    Any help or guidance is greatly appreciated!

    Thanks - Siri

  • Great Script Thanks, updating the stock levels is not a nightmare now.

    @Paul - Have noticed in the past that emptying the cache can speed a script up again once running. maybe try this.

  • Jon

    Hi Guys,

    Thanks for the script. I am having some problems with it thought and I'm not sure if this has to do with CSV encoding on Mac. My CSV is formatted as above comma seperated enclosed in quotes.

    After: $cols[$value] = $key;
    I added: echo "Key: $key; Value: $valuen";
    and this is what I'm getting...

    Key: 0; Value: sku
    Key: 1; Value: qty "1"
    Key: 2; Value: 2 "2"
    Key: 3; Value: 3 "3"
    Key: 4; Value: 1 "4"
    Key: 5; Value: 1 "5"

    TIA for any help.

  • Jon

    Just an update I believe I have resolved the problem I just need to change the line endings from Mac CR to Unix LF and everything seems to be working!

    Thanks again for this incredibly useful script! Cheers, Jon

  • Earl Cristopher

    This is really fast, thanks for the code. When do you guys think finish the script for fast importing of products. I currently need to import 100K products, and it is really really slow.


  • Your "Blink of an eye" is a little slower than I blink. 120,00 products at .03s/product = 1 hour. That's more like a nap, not a blink. 😉

    Anyway, this script is awesome but I have one question. Would it be faster if we were using ID's directly instead of sku's? I can get the id easier than the sku (takes an extra db lookup) from our exports out of our inventory management system.

    • Blink/nap/hibernate ... what's the difference 😉

      Regarding loading by ID, perhaps. It wasn't suitable for us to load by ID as that is stored and generated server side rather than being also stored locally.

      Load by attribute does require an extra couple of joins - so you'd save some SQL running if you have the entity_id.

      You'll only really get the answer if you benchmark it I guess...

  • Mike

    Thanks for the script. Works for us but times out with the qty. to import being high. With such a large qty. it would seem that php wouldn't be the fastest way to update the stock level.

    I've tried to figure out the mysql JOIN and UPDATE to update the stock directly in the db but haven't had any luck. Any idea of how an sql query could do this when you have 50k+ skus?



  • HI Guys,

    Amazing script thanks alot, do you need to refresh any caches after running this??


  • Cheers ben,

    Mike i think thats a great idea for a large number of products, you would have to upload to a temp table then run the update sql. problem being the eav database architecture makes writing a query to run the update tricky.


  • Alex

    Thanks man! This worked great for me.

  • Mara

    In, I can't get it to work. I used 2 columns, sku and short_description, ran from the browser, and the script output raw code.

    I'm bummed, since it sounds like it works so well for everyone else.

  • marky


    I needed way to manage of store.

  • James

    This is a great piece of code.

    I am considering the need to flag stock status ( out of stock, in stock ) based on the stock value being greater than zero. Has anyone else done this already?


    • Hi James,

      It wouldn't be difficult to apply a little logic to it.

      • beu

        I need to do this also. If a product has a stock qty greater than 0 then is_in_stock = 1

        What code would I change for this?

  • Tim

    Completely amazing!!!! Wow the speed is so much better, thanks so much for this little script, has saved leaving the computer to run all night!


  • Pingback: Dagblastit » Blog Archive » Customizing Magento - Rants from a Web developer, musician, dad()

  • Sean

    Magento Datefloe, it's Glacial!

  • Hej iv found that importing the csv file to an array and then looping the array speeds up the process i go from 1300 rows handled to 7000 in 20 seconds.

    might be worth a look

    Daniel Knudsen

  • strike that, i forgot to save data 🙂

    its 1300 vs 1600 products, but i do get better performance on the loop if the csv is saved to an array, so it might remove som part of the bottleneck

  • Jason

    The code is awesome...

    Is there a version of this for Customer import? this is really fast..


    • Could probably put something together in a few hours, get in touch for a quote.

  • What if I wanted to change the values not by sku but by a different attribute? For example distributor_part_number? What would I need to change?

    I have this but it doesnt work

    // Check if distributor_part_number exists
    $product = Mage::getModel('catalog/product')->loadByAttribute('distributor_part_number',$distributor_part_number);

    if ( $product ) {

    $productId = $product->getIdBySku($distributor_part_number); loadByProduct($productId);
    $stockItemId = $stockItem->getId();
    $stock = array();

    • Just change


      To your attribute.

  • Peweh

    Thanks for this Script but it does not work: (Magento Version


  • Pippo

    Any news about Magento compatibility

    • We'll only update the code once a client asks for it 🙂 If you are looking for a quote, get in touch!

  • That´s a pity. I think the changes for Magento compatible should be minimal.

    • They probably are, but we have no reason to do the work unless someone asks us to 😉

  • icvu

    Just want to express my gratitude. Your posting helped ended my 3 days of agony. All the other postings I have found led me to dead ends. This really is a Christmas gift!

    Thank You

  • THANK YOU! This saves a ton of time when running regular qty updates.

  • Great script - If you want to update prices or any other atribute for that matter change
    $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productId);


    $stockItem = Mage::getSingleton("catalog/Product")->load($productId);

    It's slower, but does the trick 🙂

    • Jason

      Pete, do you see the behavior of the product special price etc getting corrupted if they are not explicitly set using
      $stockItem = Mage::getSingleton("catalog/Product")->load($productId);

      • nar

        I had this issue. Special prices were set to zero after modifying the script this way.

    • AMP

      I am not sure why you would do this anyway, as you can set other data utilising the $product object and you don't slow the script down any. (or am I missing something?)
      For example, change the product name:
      $product->setName("new product name");
      You do, of course, have to also save the $product object with:
      Works for me.

      • We're all aware of this, but we are not setting product data - we are setting product STOCK levels - its a different model.

        On a sidenote, loading and saving the product model has significant overheads - so whilst convenient and quick to code - its by far the slowest method to modify product attributes.

  • Kevin Giles

    Please could someone post an actual piece of XML which shows the layout for updating a single product stock qty. Not everyone uses PHP!
    I have this much but don't understand the sub-format for defining that I want to update qty field. Perhaps I have missed this in the magento on-line docs.
    I want to test the XML in SOAPUI.exe .

    • This method intentionally doesn't use Data Flow (which I am assuming you are referring to when talking about XML upload profiles) or Web Services. Data Flow is SLOW, hence the use of this script. If you are looking to change status by web services, look here

      It can be tweaked to use XML instead of CSV, its not really a large amount of work, get in touch if you are interested.

  • Kevin Giles

    Sorry - when I said "This much" I meant:-



    plus the normal header stuff.

  • Giuseppe Barbiero

    Hi guis and thanks for nice snippet

    this idea is very clear congratulations

    I have an only problem. Calling directly the file like you say to execute it I cannot bypass the magento router , so the file is not found

    I come from joomla where this problem doesn't exit. May you help me on how to call this file directly if it's saved inside same Magento Folder?


    • webstores

      is_in_stock is not getting updated.
      import file can be found here -

  • Hi I am an outcoming virtuemart user who want to pass to magento cart
    I am testing your snippet, and many many thanks for your effort, this is a nice functionality
    If I am right, the script to update stock should be placed in the same root folder of Magento.

    I am trying it on the 1.5.0 version and the result is it loops many many times until the max execution time is reached, and then it stops.

    The csv is made of one line only to test.

    Do you know why it may fails? I need thie feature so much (everyone I think they need ) as modiftying stock in magento is really tedious


  • Ok I found the error of the loop

    I put csv file inside app/var/import, but this is not correct, i should have put it inside the var folder

    Thanks and sorry to bother

  • Rachita

    Other than our agency updating the usual stuff on a Magento, can I update them at the back-end for some urgencies too?

    How much time does it take for an updation to reflect on the website - i. instant ii. is it time-consuming

    • Speed will be platform dependant, try it for yourself!

  • Awesome script. As I look at this, I think that Magento's API should be abandoned in favor of short scripts such as this. I take it this is your experience? I'm asking as I am new to Magento (not programming) and it is incredible how slow the API is!

  • This is the best solution by far if you also want to update is_in_stock so that out of stock items don't appear on your site. It's also very fast. Thanks

  • pepper

    I have the same problem with Tim Thurlow. The script updates quantities but not the "is_in_stock" parameter. That way the products are always available, even if the stock quantity is set to 0.

  • I've found that SOAP calls and Mage.php calls are noticeably slower than direct database updates. The downside, is that doing direct database updates also require an API-based re-index at the end. I usually just throw this in to the function destruct to re-index at the end.
    The database takes a little while to reverse engineer, but there are some capable tools out there.

    • We do a lot of direct DB queries for stock/product import etc., the overheads of using the native models are sometimes too much for big/frequent jobs.

  • Nope not working for me any help here, someone I can contact?
    Would be brilliant to get this working as we have a lot of skus at the moment and its taking about 8 hours yet we have far fewer then your quoted 120k

    • Sure you can, go to the contact page.

      Just remember, speed will be platform dependant, run it on a slow/poorly set up server - and it will be slow.

  • Does the CSV file need to have quotation marks for each field?

  • Don't worry got it to work with a couple of tweaks

  • Brilliant, exactly what I needed. Thanks !!!

  • André

    Hi, i have been using this with no problems, and its very very useful.

    Now that we have more than 6000 products to update, the server is timing out the function. Can i split the update into two functions until i do not find a better server? Can someone help me wiht that? Thank you.

    • 6,000 products shouldn't be an issue at all.

      Your time-outs are because your server hasn't been set up properly for Magento - get in touch with our team at for truly optimised Magento dedicated servers.

      • Bishar

        Great script! Just one request, can someone help me map the columns to different headings please? For eg. 'sku' = "Product Code"

  • Hi thanks for the script.

    I have a quick question. On my magento test server (shared hosting). This script runs very quick. On my live VPS however it crawls. At it's current rate it would of imported about a thousand records in an hour.

    From debugging your code; it seems the slow down on my live server is caused by this line -> $stockItem->save(); Taking this out and the script runs fine.

    Any ideas why this would cause such a slow down issue on the VPS?

    Many Thanks,

    • Its not much of a surprise. A VPS is a less than ideal environment for running Magento - you're trying to run all your services in a tiny set up (mysql/dns/web/email), whereas with shared, although contended, you're likely to have more in the way of "burstable" resources.

      Our shared hosting (, would outperform any VPS of similar price by quite a margin.

      • Thanks for the info. I will certainly bear you in mind once the hosting runs out for this year.

        I think, in this case it might be down to Google Shopping though. It saves to the database locally and then uses the Google Shopping API to update prices there.

        Also if I used the price update line
        $stockItem = Mage::getSingleton("catalog/Product")->load($productId);

        My price updates, but the categories my products are in get jumbled up. Not good on 2000 products 🙂 Any ideas why?

        I am using Magneto

  • After you run this script do you need to reindex the data, I have been experimenting with using MAGMI for stock updates but we have a very large catalog (up to 800K items) and a few people are saying reindexing after an update will take substantially longer than the update itself.

  • It's good to check that the script actually finds the stock file you feed it (if you put one in a different place as I did) so you can do this with an initial check, otherwise every value is NULL and nothing of course works :->

    $stockFile = '/home/inbox/updateStockLevels.csv';
    if (($file = fopen($stockFile, 'r')) !== FALSE) {
    ... rest of the code ...

  • Great script!, I have tested in my website and it works like a charm, I have a question, I get XML feed of all active products only , which I will convert to csv and store in var/import folder, as the daily feed contains only active products i need to update all products qty=0 and is_in_stock=0 before running the script.

    direct query to DB will do ?
    update cataloginventory_stock_item set qty=0, is_in_stock=0

    any help is appreciated

    Thank you

  • Tony

    Anyone have luck running this with v I had it running perfect on 1.5.1, when I upgraded to it will run but doesnt update the stock.

  • WELL DONE PEOPLE!!!!!!! thank you so so so so much for this! it's great, i have an website with over 20k products and with the standard magento import tools it took me over 12 hours to update the stock and price, but with this...when the updating day is coming there are no worries 🙂 . THANK YOU!

  • M van Dongen


  • Luc

    Well done! Integrated this code into my code that generates the stock outputfile from another back-office system. Much faster than the regular import capabilties of Magento.

  • Luc

    One question? Why not read the total file in memory and then do the update? Should increase the performance a bit more with al lot of products. Now lines are read and processed one by one....

  • drooped

    when im using this script for my price update all of empty field are changed to "0"
    can you help me for this?????

  • Does anyone know how to map the sku and qty to different headings within the csv since the stock update file comes from a third party each morning? Thanks!

  • It doesn't work for me in my store using magento 1.6.1 .


  • This works a treat and whilst there are some clues within the comments on how to update prices at the same time I don't quite have the knowledge to implement. Any chance of a bit more help / exmaple??? Thank you in advance!

  • Hello,
    I've try this and it works perfect for a while, but now I receive Fatal error: Maximum execution time of 30 seconds exceeded in...The hosting provider says that they didn't change anything, I didn't change anything, but the script does not work anymore (only 800 SKU's at a time) Can you please help?

    Thank you,

    • If it was working, and now its not - it'll be your host 🙂

      Try switching to a Magento hosting provider ... we are taking on new customers at the moment starting at £30 per month.

      • Alex

        @Benjamin - fantastic script, works perfectly on 1.6.1
        It would be fabulous if you could help us out with a similar script for bulk importing prices based only on two columns, sku and price.

  • Matt

    Thanks, works great in 1.6.1!

  • Rob


    I have multiple suppliers but do only sell a limited part of their product range and therfore want to update the stock quantity from multiple csv files. The csv files I want to update fram have more SKU's than I have in my store. Does the script return an error or does it match the SKU's in the store with the one it will find in the CSV fiels.

    Thank you in advance!

  • Thank you for this! It's working great on Magento I have to change the directory for the CSV file though because the suggested directory has been moved already. In my case, I just uploaded the CSV file in VAR directory. Thanks again!

  • Beu

    Has anyone worked out a way to set is_in_stock to 1 if the product qty is greater than 0?

  • Kevin

    I would love to use this code to sync my POS inventory stock with Magento. Currently, my POS does automatically make CSV file with sku, price, stock level.
    However, POS creates CSV file with ALL products in POS system which is around 4000 sku. We carry around 2000 SKU in Magento. 

    What would happen If I use CSV file from POS and try to import it into Magento?

    1. Will give me an error when SKU from CSV is not found in Magento DB.
    2. Will automaticall ski SKUs that are not in Magento and move on.

    I want #2 to happen.

  • Kevin

    Thank you for great script. Script works beautifully when I use test CSV file. 

    However, my POS program creates CSV file but the header is CSV file is different than what your script need them to be able to successfully import them into DB.

    Your script requires them to be


    my CSV is


    Is there a way to get around this in PHP ? There is no way to do this in POS so it will have to be done by PHP script.


  • Alex

    awesome script! have saved my day!

  • billybjr

    I've been using this script to update stock.  It works great.  I need to change the names of a group of my skus.    I put sku,name and all of the sku's names to change and ran the script.  It showed successful after it ran but names were not changed... any ideas to make this work?  Thanks

  • Kevin park

    Code is working for
    "sku","qty" but if I add any more fields after that like "is_in_stock" code does not import them into DB. It's only importing field right after "sku". Is there any way to fix that?

    I am working with latest magento 1.7.1


  • Dakshika Jayathilaka

    i need to add price and cost to this script.. please help me to add

  • Maurice

    And what aboout reindexing?

  • Use the following extension to import/export your product with images/attributes/categories/customoptions e.t.c

  • jeff

    We have been using stockupdater from - very easy to use, can even use with a barcode scanner, makes it pretty easy to add and remove inventory as you are checking in or out.

  • Alex

    We are using Advanced Admin Products Manager by Iksanika for any individual and bulk/mass products update activities, including stock managemet. Easy to use and much useful comparing to coding.

  • alan

    and what about magneto extensions? Do anybody use it for stock status?

    I use this one

    Now i can say that everything works perfect.

    maybe somebody can yell some words about others.

    It would be interested listen your opinion and experience

  • Magento Developer

    If you want an easier & faster approach for updating stock via csv then you can following the following ready made script for free:

  • Alex

    I'm using free Stock Inventory Manager extension for mass stock level and statuses update, it is helpful extension which save huge amount of my time. I think only one is better to Stock Invetory Manager it is Advanced Admin Products Manager, from description it is much powerfull solution, unfortunatelly paid one 🙂

  • Alex

    For people in conversation who would like to proceed products prices attributes update in bulk - you can look to extensions Mass Prices Updater. Hope it will help.

  • This script works great for updating qty, but it doesn't seem to be updating is_in_stock properly. 1 = yes 0 = no. Correct? or is this just out of date?

    • Cristian Vultur

      It doesn't because it assumes that you feed is_in_stock trough CSV on a third column. Else it should contain something conditional like (IF stock > 0 then is_in_stock = 1) or something like bellow (picked it up from another site)

      cataloginventory_stock_item item_stock,
      cataloginventory_stock_status status_stock

      item_stock.qty = '$new_quantity',
      item_stock.is_in_stock = IF('$new_quantity'>0, 1,0),
      status_stock.qty = '$new_quantity',
      status_stock.stock_status = IF('$new_quantity'>0, 1,0)
      item_stock.product_id = '$product_id' AND
      item_stock.product_id = status_stock.product_id

  • D. M.

    You don't have to insert a $product->save() in this script to work???

    The $product->save() is the most slow part on the script.. how this could work without $product->save???


    • Pearce Stephens

      It is there in the script: $stockItem->save();

  • Stefanie

    is_in_stock does not work for me either.

  • nav

    could anyone design a script like this for my loaded commerce site? if so let me know

  • Anna

    Did anyone ever find out how to make is_in_stock work?

  • shirtsofholland

    Is this still correct? Seems strange that the script starts with "setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);" and no mage::app() or something

  • Eric

    This is a great script, but it wasn't quite fast enough for me. In my case, I did the following:
    1) Create a MySQL table from your CSV, with index on the SKU column.
    1.1) For extra speed, INSERT in batches, using the insertArray() method.
    2) Let MySQL handle the "heavy lifting" for you, with a query like this
    UPDATE my_imported_inventory imported
    LEFT JOIN catalog_product_entity p
    ON p.sku = imported.sku
    LEFT JOIN cataloginventory_stock_item s
    ON s.product_id = p.entity_id
    SET s.`is_in_stock` = IF(imported.quantity > 0, 1, 0),
    s.qty = imported.quantity,
    s.use_config_manage_stock = 1
    3) Refresh the "Stock Status" index.
    3.1) In theory, your SQL query could update the index tables too, but I'm not sure if other indexes may be dependent on this. (Didn't try)

  • Abid H. Malik

    to make is_in_stock work you need to set is_in_stock_specified = true