diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a9043a8071ce0767b5894479259257bcba477885..647b71c8bd0213a62d26da02820ebaea5bc24d61 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -70,10 +70,6 @@ containers:
           ${script} --help;
       done
 
-basic-3.9:
-  <<: *test-python
-  image: python:3.9
-
 basic-3.10:
   <<: *test-python
   image: python:3.10
@@ -89,10 +85,6 @@ basic-3.11:
     - *list-env
     - pytest test/test_samplers_import.py -v
 
-import-samplers-3.9:
-  <<: *test-samplers-import
-  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python39
-
 import-samplers-3.10:
   <<: *test-samplers-import
   image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
@@ -138,11 +130,6 @@ install:
 
     - pytest --cov=bilby --durations 10
 
-python-3.9:
-  <<: *unit-test
-  needs: ["basic-3.9"]
-  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python39
-
 python-3.10:
   <<: *unit-test
   needs: ["basic-3.10", "precommits-py3.10"]
@@ -172,11 +159,6 @@ python-3.11:
     - *list-env
     - pytest test/integration/sampler_run_test.py --durations 10 -v
 
-python-3.9-samplers:
-  <<: *test-sampler
-  needs: ["basic-3.9"]
-  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python39
-
 python-3.10-samplers:
   <<: *test-sampler
   needs: ["basic-3.10", "precommits-py3.10"]
@@ -208,11 +190,6 @@ integration-tests-python-3.10:
     - *list-env
     - pytest test/gw/plot_test.py
 
-plotting-python-3.9:
-  <<: *plotting
-  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python39
-  needs: ["basic-3.9"]
-
 plotting-python-3.10:
   <<: *plotting
   image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
@@ -280,11 +257,6 @@ pages:
     - docker image tag v3-bilby-$PYVERSION containers.ligo.org/lscsoft/bilby/v2-bilby-$PYVERSION:latest
     - docker image push containers.ligo.org/lscsoft/bilby/v2-bilby-$PYVERSION:latest
 
-build-python39-container:
-  <<: *build-container
-  variables:
-    PYVERSION: "python39"
-
 build-python310-container:
   <<: *build-container
   variables:
diff --git a/containers/v3-dockerfile-test-suite-python39 b/containers/v3-dockerfile-test-suite-python39
deleted file mode 100644
index 9c1d5a04c4e70181911aad76a70592cca63e0d43..0000000000000000000000000000000000000000
--- a/containers/v3-dockerfile-test-suite-python39
+++ /dev/null
@@ -1,27 +0,0 @@
-# This dockerfile is written automatically and should not be modified by hand.
-
-FROM containers.ligo.org/docker/base:conda
-LABEL name="bilby CI testing" \
-maintainer="Gregory Ashton <gregory.ashton@ligo.org>, Colm Talbot <colm.talbot@ligo.org>"
-
-COPY env-template.yml env.yml
-RUN echo "  - python=3.9" >> env.yml
-ENV conda_env python39
-
-RUN mamba env create -f env.yml -n ${conda_env}
-RUN echo "source activate ${conda_env}" > ~/.bashrc
-ENV PATH /opt/conda/envs/${conda_env}/bin:$PATH
-RUN /bin/bash -c "source activate ${conda_env}"
-RUN mamba info
-RUN python --version
-
-# Add the ROQ data to the image
-RUN mkdir roq_basis \
-    && cd roq_basis \
-    && wget https://git.ligo.org/lscsoft/ROQ_data/raw/master/IMRPhenomPv2/4s/B_linear.npy \
-    && wget https://git.ligo.org/lscsoft/ROQ_data/raw/master/IMRPhenomPv2/4s/B_quadratic.npy \
-    && wget https://git.ligo.org/lscsoft/ROQ_data/raw/master/IMRPhenomPv2/4s/fnodes_linear.npy \
-    && wget https://git.ligo.org/lscsoft/ROQ_data/raw/master/IMRPhenomPv2/4s/fnodes_quadratic.npy \
-    && wget https://git.ligo.org/lscsoft/ROQ_data/raw/master/IMRPhenomPv2/4s/params.dat \
-    && wget https://git.ligo.org/soichiro.morisaki/roq_basis/raw/main/IMRPhenomD/16s_nospins/basis_addcal.hdf5 \
-    && wget https://git.ligo.org/soichiro.morisaki/roq_basis/raw/main/IMRPhenomD/16s_nospins/basis_multiband_addcal.hdf5
diff --git a/containers/write_dockerfiles.py b/containers/write_dockerfiles.py
index f12c071ef711ac76ec4c5f6093073b4875e25bdf..1ca29f98fb09e495b2c91cda033e41d16e9fdb65 100644
--- a/containers/write_dockerfiles.py
+++ b/containers/write_dockerfiles.py
@@ -3,7 +3,7 @@ from datetime import date
 with open("dockerfile-template", "r") as ff:
     template = ff.read()
 
-python_versions = [(3, 9), (3, 10), (3, 11)]
+python_versions = [(3, 10), (3, 11)]
 today = date.today().strftime("%Y%m%d")
 
 for python_major_version, python_minor_version in python_versions:
diff --git a/docs/installation.txt b/docs/installation.txt
index adfbe199922830b868fa7df23634b83085b13a03..378ee65f8f97c12b3c55989403183e05d53108d3 100644
--- a/docs/installation.txt
+++ b/docs/installation.txt
@@ -10,7 +10,7 @@ Installation
 
           $ conda install -c conda-forge bilby
 
-      Supported python versions: 3.9-3.11.
+      Supported python versions: 3.10-3.11.
 
    .. tab:: Pip
 
@@ -18,7 +18,7 @@ Installation
 
           $ pip install bilby
 
-      Supported python versions: 3.9-3.11.
+      Supported python versions: 3.10-3.11.
 
 
 This will install all requirements for running :code:`bilby` for general
@@ -47,7 +47,7 @@ wave inference, please additionally run the following commands.
 Install bilby from source
 -------------------------
 
-:code:`bilby` is developed and tested with Python 3.9-3.11. In the
+:code:`bilby` is developed and tested with Python 3.10-3.11. In the
 following, we assume you have a working python installation, `python pip
 <https://packaging.python.org/tutorials/installing-packages/#use-pip-for-installing)>`_,
 and `git <https://git-scm.com/>`_. See :ref:`installing-python` for our
diff --git a/setup.py b/setup.py
index 353e92ee443d1e6e90eb104e07c15ec063229020..5b6191203c79f13720fd436a90dc33161f4f5088 100644
--- a/setup.py
+++ b/setup.py
@@ -5,8 +5,8 @@ import sys
 import os
 
 python_version = sys.version_info
-if python_version < (3, 9):
-    sys.exit("Python < 3.9 is not supported, aborting setup")
+if python_version < (3, 10):
+    sys.exit("Python < 3.10 is not supported, aborting setup")
 
 
 def get_long_description():
@@ -66,7 +66,7 @@ setup(
         "bilby.gw.detector": ["noise_curves/*.txt", "detectors/*"],
         "bilby.gw.eos": ["eos_tables/*.dat"],
     },
-    python_requires=">=3.9",
+    python_requires=">=3.10",
     install_requires=get_requirements(),
     extras_require={
         "gw": get_requirements("gw"),
@@ -104,7 +104,6 @@ setup(
         ],
     },
     classifiers=[
-        "Programming Language :: Python :: 3.9",
         "Programming Language :: Python :: 3.10",
         "Programming Language :: Python :: 3.11",
         "License :: OSI Approved :: MIT License",