diff --git a/lib/manager/npm/post-update/__snapshots__/yarn.spec.ts.snap b/lib/manager/npm/post-update/__snapshots__/yarn.spec.ts.snap
index 54ef2abfc64f06111e31469c33894c0db673e4d0..48c858717f4c7e1f1a46cd422991efc1e263dbf0 100644
--- a/lib/manager/npm/post-update/__snapshots__/yarn.spec.ts.snap
+++ b/lib/manager/npm/post-update/__snapshots__/yarn.spec.ts.snap
@@ -112,6 +112,45 @@ Array [
 ]
 `;
 
+exports[`manager/npm/post-update/yarn performs lock file updates and full install using yarn v1.22.0 1`] = `
+Array [
+  Object {
+    "cmd": "yarn install --ignore-scripts --ignore-engines --ignore-platform",
+    "options": Object {
+      "cwd": "some-dir",
+      "encoding": "utf-8",
+      "env": Object {
+        "HOME": "/home/user",
+        "HTTPS_PROXY": "https://example.com",
+        "HTTP_PROXY": "http://example.com",
+        "LANG": "en_US.UTF-8",
+        "LC_ALL": "en_US",
+        "NO_PROXY": "localhost",
+        "PATH": "/tmp/path",
+      },
+      "timeout": 900000,
+    },
+  },
+  Object {
+    "cmd": "yarn upgrade some-dep --ignore-scripts --ignore-engines --ignore-platform",
+    "options": Object {
+      "cwd": "some-dir",
+      "encoding": "utf-8",
+      "env": Object {
+        "HOME": "/home/user",
+        "HTTPS_PROXY": "https://example.com",
+        "HTTP_PROXY": "http://example.com",
+        "LANG": "en_US.UTF-8",
+        "LC_ALL": "en_US",
+        "NO_PROXY": "localhost",
+        "PATH": "/tmp/path",
+      },
+      "timeout": 900000,
+    },
+  },
+]
+`;
+
 exports[`manager/npm/post-update/yarn performs lock file updates using yarn v1.22.0 1`] = `
 Array [
   Object {
diff --git a/lib/manager/npm/post-update/yarn.spec.ts b/lib/manager/npm/post-update/yarn.spec.ts
index 9cf127d643733140938068e0fb571a784659c3f8..05bfa1d34541406b1e39072f7c4c8bb39e6c04fb 100644
--- a/lib/manager/npm/post-update/yarn.spec.ts
+++ b/lib/manager/npm/post-update/yarn.spec.ts
@@ -35,13 +35,14 @@ describe(getName(__filename), () => {
         stdout: yarnVersion,
         stderr: '',
       });
-      fs.readFile = jest.fn(() => 'package-lock-contents') as never;
+      fs.readFile.mockResolvedValue(null); // .yarnrc
+      fs.readFile.mockResolvedValue('package-lock-contents' as never);
       const config = {
         dockerMapDotfiles: true,
         postUpdateOptions: ['yarnDedupeFewer', 'yarnDedupeHighest'],
       };
       const res = await yarnHelper.generateLockFile('some-dir', {}, config);
-      expect(fs.readFile).toHaveBeenCalledTimes(1);
+      expect(fs.readFile).toHaveBeenCalledTimes(2);
       expect(res.lockFile).toEqual('package-lock-contents');
       expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
     }
@@ -54,7 +55,30 @@ describe(getName(__filename), () => {
         stderr: '',
       });
 
-      fs.readFile = jest.fn(() => 'package-lock-contents') as never;
+      fs.readFile.mockResolvedValue(null); // .yarnrc
+      fs.readFile.mockResolvedValue('package-lock-contents' as never);
+      const res = await yarnHelper.generateLockFile('some-dir', {}, {}, [
+        {
+          depName: 'some-dep',
+          isLockfileUpdate: true,
+        },
+      ]);
+      expect(res.lockFile).toEqual('package-lock-contents');
+      expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
+    }
+  );
+  it.each([['1.22.0']])(
+    'performs lock file updates and full install using yarn v%s',
+    async (yarnVersion) => {
+      const execSnapshots = mockExecAll(exec, {
+        stdout: yarnVersion,
+        stderr: '',
+      });
+
+      fs.readFile.mockReturnValueOnce(
+        'yarn-offline-mirror ./npm-packages-offline-cache' as never
+      );
+      fs.readFile.mockReturnValueOnce('package-lock-contents' as never);
       const res = await yarnHelper.generateLockFile('some-dir', {}, {}, [
         {
           depName: 'some-dep',
@@ -70,11 +94,12 @@ describe(getName(__filename), () => {
       stdout: '1.9.4',
       stderr: 'some-error',
     });
-    fs.readFile = jest.fn(() => {
-      throw new Error('not found');
-    }) as never;
+    fs.readFile.mockImplementationOnce(() => null);
+    fs.readFile.mockImplementationOnce(() => {
+      throw new Error('not-found');
+    });
     const res = await yarnHelper.generateLockFile('some-dir');
-    expect(fs.readFile).toHaveBeenCalledTimes(1);
+    expect(fs.readFile).toHaveBeenCalledTimes(2);
     expect(res.error).toBe(true);
     expect(res.lockFile).not.toBeDefined();
     expect(fixSnapshots(execSnapshots)).toMatchSnapshot();
diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts
index 04129551b419efe8ee6efb641ee6f29ac009c5ad..e74bc1e40e0dac731d140fae0c0065ccfd042230 100644
--- a/lib/manager/npm/post-update/yarn.ts
+++ b/lib/manager/npm/post-update/yarn.ts
@@ -1,3 +1,4 @@
+import is from '@sindresorhus/is';
 import { readFile } from 'fs-extra';
 import { join } from 'upath';
 import { SYSTEM_INSUFFICIENT_DISK_SPACE } from '../../../constants/error-messages';
@@ -12,6 +13,19 @@ export interface GenerateLockFileResult {
   stderr?: string;
 }
 
+export async function hasYarnOfflineMirror(cwd: string): Promise<boolean> {
+  const yarnrc = await readFile(`${cwd}/.yarnrc`, 'utf8');
+  if (is.string(yarnrc)) {
+    const mirrorLine = yarnrc
+      .split('\n')
+      .find((line) => line.startsWith('yarn-offline-mirror '));
+    if (mirrorLine) {
+      return true;
+    }
+  }
+  return false;
+}
+
 export async function generateLockFile(
   cwd: string,
   env?: NodeJS.ProcessEnv,
@@ -22,6 +36,16 @@ export async function generateLockFile(
   let lockFile = null;
   try {
     const preCommands = ['npm i -g yarn'];
+    if (
+      config.skipInstalls !== false &&
+      (await hasYarnOfflineMirror(cwd)) === false
+    ) {
+      logger.debug('Updating yarn.lock only - skipping node_modules');
+      // The following change causes Yarn 1.x to exit gracefully after updating the lock file but without installing node_modules
+      preCommands.push(
+        "sed -i 's/ steps,/ steps.slice(0,1),/' /home/ubuntu/.npm-global/lib/node_modules/yarn/lib/cli.js"
+      );
+    }
     const commands = [];
     let cmdOptions = '';
     if (global.trustLevel !== 'high' || config.ignoreScripts) {