title: How does npm handle lock files
body: <p>So I'm running <code>npm install xyz</code> inside a script that is called by the postinstall npm hook of another npm module. (Let's not get into why please but it has to do with optional dependencies that are not supported by npm)</p>
  
  <pre><code>npm install moduleA
    -&gt; installing moduleA
      -&gt; running postinstall hook (my script)
        -&gt; my script runs npm install xyz
  </code></pre>
  
  <p>When I run the script itself the npm install runs reasonably fast but when I install the module within the postinstall hook the script waits on a lock file for at least 1 min. (or so I assume)</p>
  
  <p>When I enable verbose loglevel in npm I get an output like below:</p>
  
  <pre><code>[a lot more lines above]
  npm verb addNamed "latest" is being treated as a dist-tag for invert-kv
  npm info addNameTag [ 'invert-kv', 'latest' ]
  npm verb addNameTag registry:https://registry.npmjs.org/invert-kv already in flight; waiting
  npm verb addNamed "1.0.0" is a plain semver version for invert-kv
  npm verb afterAdd /Users/path/.npm/invert-kv/1.0.0/package/package.json not in flight; writing
  npm verb correctMkdir /Users/path/.npm correctMkdir not in flight; initializing
  npm verb afterAdd /Users/path/.npm/invert-kv/1.0.0/package/package.json written
  npm verb cache add spec camelcase@^3.0.0
  npm verb addNamed "&gt;=3.0.0 &lt;4.0.0" is a valid semver range for camelcase
  npm verb addNameRange registry:https://registry.npmjs.org/camelcase not in flight; fetching
  npm verb get https://registry.npmjs.org/camelcase not expired, no request
  npm verb addNamed "3.0.0" is a plain semver version for camelcase
  npm verb afterAdd /Users/path/.npm/camelcase/3.0.0/package/package.json not in flight; writing
  npm verb correctMkdir /Users/path/.npm correctMkdir not in flight; initializing
  npm verb afterAdd /Users/path/.npm/camelcase/3.0.0/package/package.json written
  npm verb correctMkdir /Users/path/.npm/_locks correctMkdir not in flight; initializing
  </code></pre>
  
  <p>waits here for at least one minute</p>
  
  <pre><code>npm verb lock using /Users/path/.npm/_locks/staging-d21af557b41d4821.lock for /Users/path/Desktop/t/node_modules/.staging
  npm verb unbuild node_modules/.staging/abbrev-ac014442
  npm verb unbuild node_modules/.staging/ansi-regex-12e09986
  npm verb unbuild node_modules/.staging/ansi-styles-1359ba2f
  npm verb unbuild node_modules/.staging/aproba-d9971840
  npm verb unbuild node_modules/.staging/array-find-index-c1ddfc4c
  [a lot more lines below]
  </code></pre>
  
  <p>Now looking at the code of <a href="https://github.com/npm/npm/blob/latest/lib/utils/correct-mkdir.js" rel="nofollow noreferrer">correctMkdir</a> it seems that to just load all all files in <code>/Users/path/.npm/_locks</code> into memory and try to repair permission? Not sure.</p>
  
  <p><code>correctMkdir</code> is called by <a href="https://github.com/npm/npm/blob/d46015256941ddfff1463338e3e2f8f77624a1ff/lib/utils/locker.js#L21" rel="nofollow noreferrer">lock</a>. This seems to hash the file and some encryption? Also not sure.</p>
  
  <p>After reverse engineering some npm code I made progress by changing the config for <code>cache-lock-stale</code>, <code>cache-lock-wait</code> to 10ms. Unfortunately it still hangs for way too long before installing everything correctly. I suspect the changed config is not taken into account when changing right before and npm being inflight? Maybe? Maybe it's something entirely different? :)</p>
  
  <p>Anyone who can hint me the right direction? Is there something I can do to speed things up?</p>