diff --git a/lib/platform/github/gh-got-wrapper.js b/lib/platform/github/gh-got-wrapper.js
index 75e0a4b3abc80fe5582de843aa1e6a1a11060115..f799502e648b888683e07637e6286768b5c6d944 100644
--- a/lib/platform/github/gh-got-wrapper.js
+++ b/lib/platform/github/gh-got-wrapper.js
@@ -1,35 +1,28 @@
 const URL = require('url');
-const ghGot = require('gh-got');
 const delay = require('delay');
 const parseLinkHeader = require('parse-link-header');
 const pAll = require('p-all');
 
-const hostRules = require('../../util/host-rules');
+const got = require('../../util/got');
 const { maskToken } = require('../../util/mask');
 
-let cache = {};
 let stats = {};
 
-let endpoint = 'https://api.github.com/';
+const hostType = 'github';
+let baseUrl = 'https://api.github.com/';
 
 async function get(path, options, retries = 5) {
-  let url = URL.resolve(endpoint, path);
   const opts = {
-    // TODO: Move to configurable host rules, or use utils/got
-    timeout: 60 * 1000,
-    ...hostRules.find({ hostType: 'github', url }),
+    hostType,
+    baseUrl,
+    json: true,
     ...options,
   };
-  delete opts.endpoint;
   const method = opts.method || 'get';
-  const useCache = opts.useCache !== false;
+  let massagedPath = path;
   if (method.toLowerCase() === 'post' && path === 'graphql') {
     // GitHub Enterprise uses unversioned graphql path
-    url = url.replace('/v3/', '/');
-  }
-  if (method === 'get' && useCache && cache[path]) {
-    logger.trace({ path }, 'Returning cached result');
-    return cache[path];
+    massagedPath = massagedPath.replace('/v3/', '/');
   }
   logger.trace(`${method.toUpperCase()} ${path}`);
   stats.requests = (stats.requests || []).concat([
@@ -52,7 +45,7 @@ async function get(path, options, retries = 5) {
         opts.headers.accept = `${appAccept}, ${opts.headers.accept}`;
       }
     }
-    const res = await ghGot(url, opts);
+    const res = await got(massagedPath, opts);
     if (res && res.headers) {
       stats.rateLimit = res.headers['x-ratelimit-limit'];
       stats.rateLimitRemaining = res.headers['x-ratelimit-remaining'];
@@ -86,13 +79,6 @@ async function get(path, options, retries = 5) {
         );
       }
     }
-    if (
-      method === 'get' &&
-      (path.startsWith('repos/') ||
-        path.startsWith('https://api.github.com/repos/'))
-    ) {
-      cache[path] = res;
-    }
     // istanbul ignore if
     if (method === 'POST' && path === 'graphql') {
       const goodResult = '{"data":{';
@@ -171,12 +157,6 @@ async function get(path, options, retries = 5) {
     ) {
       logger.info({ err, headers: err.headers }, 'Rate limit exceeded');
       throw new Error('rate-limit-exceeded');
-    } else if (
-      err.statusCode === 403 &&
-      err.message &&
-      err.message.includes('blobs up to 1 MB in size')
-    ) {
-      throw err;
     } else if (
       err.statusCode === 403 &&
       err.message &&
@@ -229,8 +209,6 @@ get.setAppMode = function setAppMode() {
 };
 
 get.reset = function reset() {
-  cache = null;
-  cache = {};
   // istanbul ignore if
   if (stats.requests && stats.requests.length > 1) {
     logger.info(
@@ -247,8 +225,8 @@ get.reset = function reset() {
   }
 };
 
-get.setEndpoint = e => {
-  endpoint = e;
+get.setBaseUrl = u => {
+  baseUrl = u;
 };
 
 module.exports = get;
diff --git a/lib/platform/github/index.js b/lib/platform/github/index.js
index 0985de6ef53e787fb2d846b0166a802d259da559..98d0fc2f1f1b5050c675c3f4afa5b9331f888e2b 100644
--- a/lib/platform/github/index.js
+++ b/lib/platform/github/index.js
@@ -81,7 +81,7 @@ async function initPlatform({ endpoint, token }) {
   const res = {};
   if (endpoint) {
     defaults.endpoint = endpoint.replace(/\/?$/, '/'); // always add a trailing slash
-    get.setEndpoint(defaults.endpoint);
+    get.setBaseUrl(defaults.endpoint);
   } else {
     logger.info('Using default github endpoint: ' + defaults.endpoint);
   }
diff --git a/test/platform/github/__snapshots__/gh-got-wrapper.spec.js.snap b/test/platform/github/__snapshots__/gh-got-wrapper.spec.js.snap
deleted file mode 100644
index 0751c2e7956ec95a1a20e01624f76c86b9111649..0000000000000000000000000000000000000000
--- a/test/platform/github/__snapshots__/gh-got-wrapper.spec.js.snap
+++ /dev/null
@@ -1,8 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`platform/gh-got-wrapper should throw for blob size 1`] = `
-Object {
-  "message": "This API returns blobs up to 1 MB in size. The requested blob is too large to fetch via the API, but you can use the Git Data API to request blobs up to 100 MB in size. (403)",
-  "statusCode": 403,
-}
-`;
diff --git a/test/platform/github/gh-got-wrapper.spec.js b/test/platform/github/gh-got-wrapper.spec.js
index 85bf26650cd17a008f6c08c2bf98ae379803c451..9bbd2117f7045c8aa9a84be6521e9ae7b090f776 100644
--- a/test/platform/github/gh-got-wrapper.spec.js
+++ b/test/platform/github/gh-got-wrapper.spec.js
@@ -1,8 +1,8 @@
-const ghGot = require('gh-got');
 const delay = require('delay');
+const got = require('../../../lib/util/got');
 const get = require('../../../lib/platform/github/gh-got-wrapper');
 
-jest.mock('gh-got');
+jest.mock('../../../lib/util/got');
 jest.mock('delay');
 
 describe('platform/gh-got-wrapper', () => {
@@ -16,61 +16,61 @@ describe('platform/gh-got-wrapper', () => {
   it('supports app mode', async () => {
     global.appMode = true;
     await get('some-url', { headers: { accept: 'some-accept' } });
-    expect(ghGot.mock.calls[0][1].headers.accept).toBe(
+    expect(got.mock.calls[0][1].headers.accept).toBe(
       'application/vnd.github.machine-man-preview+json, some-accept'
     );
   });
   it('strips v3 for graphql', async () => {
-    ghGot.mockImplementationOnce(() => ({
+    got.mockImplementationOnce(() => ({
       body: '{"data":{',
     }));
-    get.setEndpoint('https://ghe.mycompany.com/api/v3/');
+    get.setBaseUrl('https://ghe.mycompany.com/api/v3/');
     await get.post('graphql', {
       body: 'abc',
     });
-    expect(ghGot.mock.calls[0][0].includes('/v3')).toBe(false);
+    expect(got.mock.calls[0][0].includes('/v3')).toBe(false);
   });
   it('paginates', async () => {
-    ghGot.mockReturnValueOnce({
+    got.mockReturnValueOnce({
       headers: {
         link:
           '<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=2>; rel="next", <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=3>; rel="last"',
       },
       body: ['a'],
     });
-    ghGot.mockReturnValueOnce({
+    got.mockReturnValueOnce({
       headers: {
         link:
           '<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=3>; rel="next", <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=3>; rel="last"',
       },
       body: ['b', 'c'],
     });
-    ghGot.mockReturnValueOnce({
+    got.mockReturnValueOnce({
       headers: {},
       body: ['d'],
     });
     const res = await get('some-url', { paginate: true });
     expect(res.body).toEqual(['a', 'b', 'c', 'd']);
-    expect(ghGot).toHaveBeenCalledTimes(3);
+    expect(got).toHaveBeenCalledTimes(3);
   });
   it('attempts to paginate', async () => {
-    ghGot.mockReturnValueOnce({
+    got.mockReturnValueOnce({
       headers: {
         link:
           '<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=34>; rel="last"',
       },
       body: ['a'],
     });
-    ghGot.mockReturnValueOnce({
+    got.mockReturnValueOnce({
       headers: {},
       body: ['b'],
     });
     const res = await get('some-url', { paginate: true });
     expect(res.body).toHaveLength(1);
-    expect(ghGot).toHaveBeenCalledTimes(1);
+    expect(got).toHaveBeenCalledTimes(1);
   });
   it('should throw rate limit exceeded', async () => {
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 403,
         message:
@@ -80,7 +80,7 @@ describe('platform/gh-got-wrapper', () => {
     await expect(get('some-url')).rejects.toThrow();
   });
   it('should throw Bad credentials', async () => {
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 401,
         message: 'Bad credentials. (401)',
@@ -96,7 +96,7 @@ describe('platform/gh-got-wrapper', () => {
     expect(e.message).toEqual('bad-credentials');
   });
   it('should throw platform failure', async () => {
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 401,
         message: 'Bad credentials. (401)',
@@ -115,7 +115,7 @@ describe('platform/gh-got-wrapper', () => {
     expect(e.message).toEqual('platform-failure');
   });
   it('should throw platform failure ENOTFOUND', async () => {
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         name: 'RequestError',
         code: 'ENOTFOUND',
@@ -131,7 +131,7 @@ describe('platform/gh-got-wrapper', () => {
     expect(e.message).toEqual('platform-failure');
   });
   it('should throw platform failure for 500', async () => {
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 500,
         message: 'Internal Server Error',
@@ -146,78 +146,61 @@ describe('platform/gh-got-wrapper', () => {
     expect(e).toBeDefined();
     expect(e.message).toEqual('platform-failure');
   });
-  it('should throw for blob size', async () => {
-    ghGot.mockImplementationOnce(() =>
-      Promise.reject({
-        statusCode: 403,
-        message:
-          'This API returns blobs up to 1 MB in size. The requested blob is too large to fetch via the API, but you can use the Git Data API to request blobs up to 100 MB in size. (403)',
-      })
-    );
-    let e;
-    try {
-      await get('some-url');
-    } catch (err) {
-      e = err;
-    }
-    expect(e).toBeDefined();
-    expect(e).toMatchSnapshot();
-  });
   it('should retry 502s', async () => {
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 502,
       })
     );
-    ghGot.mockImplementationOnce(() => ({
+    got.mockImplementationOnce(() => ({
       body,
     }));
     const res = await get('some-url');
     expect(res.body).toEqual(body);
   });
   it('should retry 502s until success', async () => {
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 502,
       })
     );
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 502,
       })
     );
-    ghGot.mockImplementationOnce(() => ({
+    got.mockImplementationOnce(() => ({
       body,
     }));
     const res = await get('some-url');
-    expect(ghGot).toHaveBeenCalledTimes(3);
+    expect(got).toHaveBeenCalledTimes(3);
     expect(res.body).toEqual(body);
   });
   it('should retry until failure', async () => {
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 502,
       })
     );
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 403,
         message: 'Bad bot.',
       })
     );
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 502,
       })
     );
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 403,
         message:
           'You have triggered an abuse detection mechanism. Please wait a few minutes before you try again.',
       })
     );
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 404,
       })
@@ -227,32 +210,32 @@ describe('platform/gh-got-wrapper', () => {
     });
   });
   it('should give up after 5 retries', async () => {
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 502,
       })
     );
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 502,
       })
     );
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 500,
       })
     );
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 500,
       })
     );
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 502,
       })
     );
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 403,
         message: 'Bad bot.',
@@ -264,28 +247,19 @@ describe('platform/gh-got-wrapper', () => {
     });
   });
   it('should retry posts', async () => {
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 502,
       })
     );
-    ghGot.mockImplementationOnce(() => ({
+    got.mockImplementationOnce(() => ({
       body,
     }));
     const res = await get.post('some-url');
     expect(res.body).toEqual(body);
   });
-  it('returns cached', async () => {
-    get.reset();
-    ghGot.mockReturnValueOnce({
-      body: {},
-    });
-    const res1 = await get('repos/foo');
-    const res2 = await get('repos/foo');
-    expect(res1).toEqual(res2);
-  });
   it('should throw platform failure ParseError', async () => {
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         name: 'ParseError',
       })
@@ -300,7 +274,7 @@ describe('platform/gh-got-wrapper', () => {
     expect(e.message).toEqual('platform-failure');
   });
   it('should throw for unauthorized integration', async () => {
-    ghGot.mockImplementationOnce(() =>
+    got.mockImplementationOnce(() =>
       Promise.reject({
         statusCode: 403,
         message: 'Resource not accessible by integration (403)',
diff --git a/test/platform/github/index.spec.js b/test/platform/github/index.spec.js
index e8ddb0eca598032ebdb72ac93efb3ca330c05858..e1c6aadae60e3ccc46992e709e2ccd6c3571ae7a 100644
--- a/test/platform/github/index.spec.js
+++ b/test/platform/github/index.spec.js
@@ -11,6 +11,7 @@ describe('platform/github', () => {
     jest.mock('delay');
     jest.mock('../../../lib/platform/github/gh-got-wrapper');
     jest.mock('../../../lib/util/host-rules');
+    jest.mock('../../../lib/util/got');
     get = require('../../../lib/platform/github/gh-got-wrapper');
     github = require('../../../lib/platform/github');
     hostRules = require('../../../lib/util/host-rules');
diff --git a/test/workers/pr/changelog/index.spec.js b/test/workers/pr/changelog/index.spec.js
index b94ecbed7abb76e838c75cbf95a70092435f5ea5..5dbca1c35bb17060277bd60b8279180e03d4081c 100644
--- a/test/workers/pr/changelog/index.spec.js
+++ b/test/workers/pr/changelog/index.spec.js
@@ -1,6 +1,6 @@
 jest.mock('../../../../lib/platform/github/gh-got-wrapper');
 jest.mock('../../../../lib/datasource/npm');
-jest.mock('got');
+jest.mock('../../../../lib/platform/github/gh-got-wrapper');
 
 const hostRules = require('../../../../lib/util/host-rules');
 const ghGot = require('../../../../lib/platform/github/gh-got-wrapper');
diff --git a/test/workers/pr/changelog/release-notes.spec.js b/test/workers/pr/changelog/release-notes.spec.js
index d8d1aa6a991e426aebbf7c5de11c7ae4d184e731..954b9735ea61c30ef6841c968f19c5edef02a12f 100644
--- a/test/workers/pr/changelog/release-notes.spec.js
+++ b/test/workers/pr/changelog/release-notes.spec.js
@@ -1,5 +1,5 @@
 const fs = require('fs-extra');
-const ghGot = require('gh-got');
+const ghGot = require('../../../../lib/util/got');
 const {
   addReleaseNotes,
   getReleaseNotes,
@@ -26,7 +26,7 @@ const contentsResponse = [
   { name: 'README.md' },
 ];
 
-jest.mock('gh-got');
+jest.mock('../../../../lib/util/got');
 
 describe('workers/pr/release-notes', () => {
   describe('addReleaseNotes()', () => {