diff --git a/.github/workflows/test-integration-17.yml b/.github/workflows/test-integration-17.yml
index 45394fc977fbf989845b061800d0c30a8be7c18a..ccec28fb8d8009f1915a318b868f61ed66ab3849 100644
--- a/.github/workflows/test-integration-17.yml
+++ b/.github/workflows/test-integration-17.yml
@@ -14,15 +14,6 @@ jobs:
       PAT_EXISTS: ${{ secrets.GH_PAT != '' }}
 
     services:
-      redis:
-        image: redis
-        options: >-
-          --health-cmd "redis-cli ping"
-          --health-interval 10s
-          --health-timeout 5s
-          --health-retries 5
-        ports:
-          - 6379:6379
       postgres:
         image: postgres
         env:
diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml
index d7e64678480bfa41f2f4e8de8a81de19b405924e..b86b9a43462faab374af3c25a1503ceddc4a1098 100644
--- a/.github/workflows/test-integration.yml
+++ b/.github/workflows/test-integration.yml
@@ -14,15 +14,6 @@ jobs:
       PAT_EXISTS: ${{ secrets.GH_PAT != '' }}
 
     services:
-      redis:
-        image: redis
-        options: >-
-          --health-cmd "redis-cli ping"
-          --health-interval 10s
-          --health-timeout 5s
-          --health-retries 5
-        ports:
-          - 6379:6379
       postgres:
         image: postgres
         env:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 549a3162c029d0039c11deff74e3db1f6d1625d5..9a610913f00c8db8d2f5759fff0fab504e3d5d6f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -134,12 +134,11 @@ Prettier before a commit by default.
 When adding or changing a service [please write tests][service-tests], and ensure the [title of your Pull Requests follows the required conventions](#running-service-tests-in-pull-requests) to ensure your tests are executed.
 When changing other code, please add unit tests.
 
-The integration tests are not run by default. For most contributions it is OK to skip these unless you're working directly on the code for storing the GitHub token pool in postgres/redis.
+The integration tests are not run by default. For most contributions it is OK to skip these unless you're working directly on the code for storing the GitHub token pool in postgres.
 
 To run the integration tests:
 
-- You must have Redis installed and in your PATH. Use `brew install redis`, `apt-get install redis`, etc. The test runner will start the server automatically.
-- You must also have PostgreSQL installed. Use `brew install postgresql`, `apt-get install postgresql`, etc.
+- You must have PostgreSQL installed. Use `brew install postgresql`, `apt-get install postgresql`, etc.
 - Set a connection string either with an env var `POSTGRES_URL=postgresql://user:pass@127.0.0.1:5432/db_name` or by using
   ```yaml
   private:
diff --git a/config/local-shields-io-production.template.yml b/config/local-shields-io-production.template.yml
index efb55146282ae1ab30ded57532b288eaff522c91..848039ad7a2ea91b7e27605ce3dc1962c8866de3 100644
--- a/config/local-shields-io-production.template.yml
+++ b/config/local-shields-io-production.template.yml
@@ -4,7 +4,6 @@ private:
   gh_client_id: ...
   gh_client_secret: ...
   gitlab_token: ...
-  redis_url: ...
   sentry_dsn: ...
   shields_secret: ...
   sl_insight_userUuid: ...
diff --git a/core/token-pooling/redis-token-persistence.integration.js b/core/token-pooling/redis-token-persistence.integration.js
deleted file mode 100644
index b11d9304bbff2715c087b2b797d9717cd5b2ad3c..0000000000000000000000000000000000000000
--- a/core/token-pooling/redis-token-persistence.integration.js
+++ /dev/null
@@ -1,94 +0,0 @@
-import RedisServer from 'redis-server'
-import Redis from 'ioredis'
-import { expect } from 'chai'
-import RedisTokenPersistence from './redis-token-persistence.js'
-
-describe('Redis token persistence', function () {
-  let server
-  // In CI, expect redis already to be running.
-  if (!process.env.CI) {
-    beforeEach(async function () {
-      server = new RedisServer({ config: { host: 'localhost' } })
-      await server.open()
-    })
-  }
-
-  const key = 'tokenPersistenceIntegrationTest'
-
-  let redis
-  beforeEach(async function () {
-    redis = new Redis()
-    await redis.del(key)
-  })
-  afterEach(async function () {
-    if (redis) {
-      await redis.quit()
-      redis = undefined
-    }
-  })
-
-  if (!process.env.CI) {
-    afterEach(async function () {
-      await server.close()
-      server = undefined
-    })
-  }
-
-  let persistence
-  beforeEach(function () {
-    persistence = new RedisTokenPersistence({ key })
-  })
-  afterEach(async function () {
-    if (persistence) {
-      await persistence.stop()
-      persistence = undefined
-    }
-  })
-
-  context('when the key does not exist', function () {
-    it('does nothing', async function () {
-      const tokens = await persistence.initialize()
-      expect(tokens).to.deep.equal([])
-    })
-  })
-
-  context('when the key exists', function () {
-    const initialTokens = ['a', 'b', 'c'].map(char => char.repeat(40))
-
-    beforeEach(async function () {
-      await redis.sadd(key, initialTokens)
-    })
-
-    it('loads the contents', async function () {
-      const tokens = await persistence.initialize()
-      expect(tokens.sort()).to.deep.equal(initialTokens)
-    })
-
-    context('when tokens are added', function () {
-      it('saves the change', async function () {
-        const newToken = 'e'.repeat(40)
-        const expected = initialTokens.slice()
-        expected.push(newToken)
-
-        await persistence.initialize()
-        await persistence.noteTokenAdded(newToken)
-
-        const savedTokens = await redis.smembers(key)
-        expect(savedTokens.sort()).to.deep.equal(expected)
-      })
-    })
-
-    context('when tokens are removed', function () {
-      it('saves the change', async function () {
-        const expected = Array.from(initialTokens)
-        const toRemove = expected.pop()
-
-        await persistence.initialize()
-        await persistence.noteTokenRemoved(toRemove)
-
-        const savedTokens = await redis.smembers(key)
-        expect(savedTokens.sort()).to.deep.equal(expected)
-      })
-    })
-  })
-})
diff --git a/core/token-pooling/redis-token-persistence.js b/core/token-pooling/redis-token-persistence.js
deleted file mode 100644
index dd0b6fb3067020aa12359845e58c9bbd55bdd706..0000000000000000000000000000000000000000
--- a/core/token-pooling/redis-token-persistence.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import { URL } from 'url'
-import Redis from 'ioredis'
-import log from '../server/log.js'
-
-export default class RedisTokenPersistence {
-  constructor({ url, key }) {
-    this.url = url
-    this.key = key
-    this.noteTokenAdded = this.noteTokenAdded.bind(this)
-    this.noteTokenRemoved = this.noteTokenRemoved.bind(this)
-  }
-
-  async initialize() {
-    const options =
-      this.url && this.url.startsWith('rediss:')
-        ? {
-            //  https://www.compose.com/articles/ssl-connections-arrive-for-redis-on-compose/
-            tls: { servername: new URL(this.url).hostname },
-          }
-        : undefined
-    this.redis = new Redis(this.url, options)
-    this.redis.on('error', e => {
-      log.error(e)
-    })
-
-    const tokens = await this.redis.smembers(this.key)
-    return tokens
-  }
-
-  async stop() {
-    await this.redis.quit()
-  }
-
-  async onTokenAdded(token) {
-    await this.redis.sadd(this.key, token)
-  }
-
-  async onTokenRemoved(token) {
-    await this.redis.srem(this.key, token)
-  }
-
-  async noteTokenAdded(token) {
-    try {
-      await this.onTokenAdded(token)
-    } catch (e) {
-      log.error(e)
-    }
-  }
-
-  async noteTokenRemoved(token) {
-    try {
-      await this.onTokenRemoved(token)
-    } catch (e) {
-      log.error(e)
-    }
-  }
-}
diff --git a/package-lock.json b/package-lock.json
index 2c78c4456f706861c65c32b89e7eef05611b825b..63e2991b0a0a99f024beed877ae726ad48e33b1c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -33,7 +33,6 @@
         "got": "^12.6.0",
         "graphql": "^15.6.1",
         "graphql-tag": "^2.12.6",
-        "ioredis": "5.3.1",
         "joi": "17.9.1",
         "joi-extension-semver": "5.0.0",
         "js-yaml": "^4.1.0",
@@ -144,7 +143,6 @@
         "react-pose": "^4.0.10",
         "react-select": "^4.3.1",
         "read-all-stdin-sync": "^1.0.5",
-        "redis-server": "^1.2.2",
         "rimraf": "^4.4.1",
         "sazerac": "^2.0.0",
         "simple-git-hooks": "^2.8.1",
@@ -3532,11 +3530,6 @@
       "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
       "dev": true
     },
-    "node_modules/@ioredis/commands": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.1.1.tgz",
-      "integrity": "sha512-fsR4P/ROllzf/7lXYyElUJCheWdTJVJvOTps8v9IWKFATxR61ANOlnoPqhH099xYLrJGpc2ZQ28B3rMeUt5VQg=="
-    },
     "node_modules/@istanbuljs/schema": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
@@ -9150,14 +9143,6 @@
         "range_check": "^1.4.0"
       }
     },
-    "node_modules/cluster-key-slot": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz",
-      "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/color": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz",
@@ -11023,14 +11008,6 @@
         "node": ">=0.4.0"
       }
     },
-    "node_modules/denque": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
-      "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
     "node_modules/depd": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@@ -18110,50 +18087,6 @@
         "loose-envify": "^1.0.0"
       }
     },
-    "node_modules/ioredis": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.1.tgz",
-      "integrity": "sha512-C+IBcMysM6v52pTLItYMeV4Hz7uriGtoJdz7SSBDX6u+zwSYGirLdQh3L7t/OItWITcw3gTFMjJReYUwS4zihg==",
-      "dependencies": {
-        "@ioredis/commands": "^1.1.1",
-        "cluster-key-slot": "^1.1.0",
-        "debug": "^4.3.4",
-        "denque": "^2.1.0",
-        "lodash.defaults": "^4.2.0",
-        "lodash.isarguments": "^3.1.0",
-        "redis-errors": "^1.2.0",
-        "redis-parser": "^3.0.0",
-        "standard-as-callback": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=12.22.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/ioredis"
-      }
-    },
-    "node_modules/ioredis/node_modules/debug": {
-      "version": "4.3.4",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
-      "dependencies": {
-        "ms": "2.1.2"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/ioredis/node_modules/ms": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
-    },
     "node_modules/ip6": {
       "version": "0.0.4",
       "resolved": "https://registry.npmjs.org/ip6/-/ip6-0.0.4.tgz",
@@ -20066,11 +19999,6 @@
       "integrity": "sha1-3bG7s+8HRYwBd7oH3hRCLLAz/5s=",
       "dev": true
     },
-    "node_modules/lodash.defaults": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
-      "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw="
-    },
     "node_modules/lodash.difference": {
       "version": "4.5.0",
       "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
@@ -20124,11 +20052,6 @@
       "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
       "dev": true
     },
-    "node_modules/lodash.isarguments": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
-      "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo="
-    },
     "node_modules/lodash.isfunction": {
       "version": "3.0.9",
       "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz",
@@ -24463,15 +24386,6 @@
       "integrity": "sha1-2chtPcTcLfkBboiUbe/Wm0m0EWI=",
       "dev": true
     },
-    "node_modules/promise-queue": {
-      "version": "2.2.5",
-      "resolved": "https://registry.npmjs.org/promise-queue/-/promise-queue-2.2.5.tgz",
-      "integrity": "sha1-L29ffA9tCBCelnZZx5uIqe1ek7Q=",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
     "node_modules/prompts": {
       "version": "2.4.2",
       "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
@@ -25538,37 +25452,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/redis-errors": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
-      "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=",
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/redis-parser": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
-      "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=",
-      "dependencies": {
-        "redis-errors": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/redis-server": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/redis-server/-/redis-server-1.2.2.tgz",
-      "integrity": "sha512-pOaSIeSMVFkEFIuaMtpQ3TOr3uI4sUmEHm4ofGks5vTPRseHUszxyIlC70IFjUR9qSeH8o/ARZEM8dqcJmgGJw==",
-      "dev": true,
-      "dependencies": {
-        "promise-queue": "^2.2.5"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
     "node_modules/redux": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz",
@@ -27596,11 +27479,6 @@
       "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
       "dev": true
     },
-    "node_modules/standard-as-callback": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
-      "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="
-    },
     "node_modules/start-server-and-test": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-2.0.0.tgz",
@@ -33448,11 +33326,6 @@
       "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
       "dev": true
     },
-    "@ioredis/commands": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.1.1.tgz",
-      "integrity": "sha512-fsR4P/ROllzf/7lXYyElUJCheWdTJVJvOTps8v9IWKFATxR61ANOlnoPqhH099xYLrJGpc2ZQ28B3rMeUt5VQg=="
-    },
     "@istanbuljs/schema": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
@@ -37697,11 +37570,6 @@
         "range_check": "^1.4.0"
       }
     },
-    "cluster-key-slot": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz",
-      "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw=="
-    },
     "color": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz",
@@ -39122,11 +38990,6 @@
       "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
       "dev": true
     },
-    "denque": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
-      "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="
-    },
     "depd": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@@ -44471,37 +44334,6 @@
         "loose-envify": "^1.0.0"
       }
     },
-    "ioredis": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.1.tgz",
-      "integrity": "sha512-C+IBcMysM6v52pTLItYMeV4Hz7uriGtoJdz7SSBDX6u+zwSYGirLdQh3L7t/OItWITcw3gTFMjJReYUwS4zihg==",
-      "requires": {
-        "@ioredis/commands": "^1.1.1",
-        "cluster-key-slot": "^1.1.0",
-        "debug": "^4.3.4",
-        "denque": "^2.1.0",
-        "lodash.defaults": "^4.2.0",
-        "lodash.isarguments": "^3.1.0",
-        "redis-errors": "^1.2.0",
-        "redis-parser": "^3.0.0",
-        "standard-as-callback": "^2.1.0"
-      },
-      "dependencies": {
-        "debug": {
-          "version": "4.3.4",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
-          "requires": {
-            "ms": "2.1.2"
-          }
-        },
-        "ms": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
-        }
-      }
-    },
     "ip6": {
       "version": "0.0.4",
       "resolved": "https://registry.npmjs.org/ip6/-/ip6-0.0.4.tgz",
@@ -45961,11 +45793,6 @@
       "integrity": "sha1-3bG7s+8HRYwBd7oH3hRCLLAz/5s=",
       "dev": true
     },
-    "lodash.defaults": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
-      "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw="
-    },
     "lodash.difference": {
       "version": "4.5.0",
       "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
@@ -46019,11 +45846,6 @@
       "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
       "dev": true
     },
-    "lodash.isarguments": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
-      "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo="
-    },
     "lodash.isfunction": {
       "version": "3.0.9",
       "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz",
@@ -49303,12 +49125,6 @@
       "integrity": "sha1-2chtPcTcLfkBboiUbe/Wm0m0EWI=",
       "dev": true
     },
-    "promise-queue": {
-      "version": "2.2.5",
-      "resolved": "https://registry.npmjs.org/promise-queue/-/promise-queue-2.2.5.tgz",
-      "integrity": "sha1-L29ffA9tCBCelnZZx5uIqe1ek7Q=",
-      "dev": true
-    },
     "prompts": {
       "version": "2.4.2",
       "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
@@ -50122,28 +49938,6 @@
         }
       }
     },
-    "redis-errors": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
-      "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60="
-    },
-    "redis-parser": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
-      "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=",
-      "requires": {
-        "redis-errors": "^1.0.0"
-      }
-    },
-    "redis-server": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/redis-server/-/redis-server-1.2.2.tgz",
-      "integrity": "sha512-pOaSIeSMVFkEFIuaMtpQ3TOr3uI4sUmEHm4ofGks5vTPRseHUszxyIlC70IFjUR9qSeH8o/ARZEM8dqcJmgGJw==",
-      "dev": true,
-      "requires": {
-        "promise-queue": "^2.2.5"
-      }
-    },
     "redux": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz",
@@ -51799,11 +51593,6 @@
       "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
       "dev": true
     },
-    "standard-as-callback": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
-      "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="
-    },
     "start-server-and-test": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-2.0.0.tgz",
diff --git a/package.json b/package.json
index c58e325fe586b7e3a470b8f1cfe4cfbdd1a7a21d..43aef1a5f7ed9106df9097b1b36f710fc6713a59 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,6 @@
     "got": "^12.6.0",
     "graphql": "^15.6.1",
     "graphql-tag": "^2.12.6",
-    "ioredis": "5.3.1",
     "joi": "17.9.1",
     "joi-extension-semver": "5.0.0",
     "js-yaml": "^4.1.0",
@@ -231,7 +230,6 @@
     "react-pose": "^4.0.10",
     "react-select": "^4.3.1",
     "read-all-stdin-sync": "^1.0.5",
-    "redis-server": "^1.2.2",
     "rimraf": "^4.4.1",
     "sazerac": "^2.0.0",
     "simple-git-hooks": "^2.8.1",
diff --git a/scripts/redis-connectivity-test.js b/scripts/redis-connectivity-test.js
deleted file mode 100644
index 5e61fd5cdf5d762aaf4f3961033aca6e32b9d77c..0000000000000000000000000000000000000000
--- a/scripts/redis-connectivity-test.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import config from 'config'
-import GithubConstellation from '../services/github/github-constellation.js'
-const objectConfig = config.util.toObject()
-console.log(objectConfig)
-
-const { persistence } = new GithubConstellation({
-  service: objectConfig.public.services.github,
-  private: objectConfig.private,
-})
-
-async function main() {
-  const tokens = await persistence.initialize()
-  console.log(`${tokens.length} tokens loaded`)
-  await persistence.stop()
-}
-
-;(async () => {
-  try {
-    await main()
-  } catch (e) {
-    console.error(e)
-    process.exit(1)
-  }
-})()
diff --git a/server.js b/server.js
index cc7b3684d08889d6e04157ca56dbb6f6d0415847..a339dc2679a27c9be8fae14f7b651ecd10e6a90e 100644
--- a/server.js
+++ b/server.js
@@ -43,12 +43,10 @@ if (fs.existsSync('.env')) {
 }
 
 if (config.private.redis_url != null) {
-  console.warn(
-    'RedisTokenPersistence is deprecated for token pooling and will be removed in a future release. Migrate to SqlTokenPersistence'
-  )
-  console.warn(
-    'See https://github.com/badges/shields/blob/master/CHANGELOG.md#server-2023-03-01 for more info'
+  console.error(
+    'RedisTokenPersistence has been removed. Migrate to SqlTokenPersistence'
   )
+  process.exit(1)
 }
 
 const legacySecretsPath = path.join(
diff --git a/services/github/github-constellation.js b/services/github/github-constellation.js
index f229185aa85aee4648206ec61267002dbf5a8c59..9e7b1a4a44926349333ab357df5f0d6b420e4652 100644
--- a/services/github/github-constellation.js
+++ b/services/github/github-constellation.js
@@ -1,5 +1,4 @@
 import { AuthHelper } from '../../core/base-service/auth-helper.js'
-import RedisTokenPersistence from '../../core/token-pooling/redis-token-persistence.js'
 import SqlTokenPersistence from '../../core/token-pooling/sql-token-persistence.js'
 import log from '../../core/server/log.js'
 import GithubApiProvider from './github-api-provider.js'
@@ -24,23 +23,13 @@ class GithubConstellation {
     this._debugEnabled = config.service.debug.enabled
     this._debugIntervalSeconds = config.service.debug.intervalSeconds
 
-    const {
-      postgres_url: pgUrl,
-      redis_url: redisUrl,
-      gh_token: globalToken,
-    } = config.private
+    const { postgres_url: pgUrl, gh_token: globalToken } = config.private
     if (pgUrl) {
       log.log('Token persistence configured with dbUrl')
       this.persistence = new SqlTokenPersistence({
         url: pgUrl,
         table: 'github_user_tokens',
       })
-    } else if (redisUrl) {
-      log.log('Token persistence configured with redisUrl')
-      this.persistence = new RedisTokenPersistence({
-        url: redisUrl,
-        key: 'githubUserTokens',
-      })
     }
 
     this.apiProvider = new GithubApiProvider({