diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
index ddb6ecbe83126e33b1a2d31d9888b102e986120d..a9585c17454fbad2df3690ac715fca5f2b93e51e 100644
--- a/.github/workflows/unit-tests.yml
+++ b/.github/workflows/unit-tests.yml
@@ -388,8 +388,6 @@ jobs:
 
       - name: Run Tests
         uses: ./.github/actions/run-tests
-        env:
-          PYTHON_GIL: 0
 
   # NOTE: this job must be kept in sync with the Pyodide build job in wheels.yml
   emscripten:
diff --git a/meson.build b/meson.build
index 06623a305ab5446163525f3d2b4dac1aa447d0c4..efe543b7a267c2e00197076335f9f43b01828807 100644
--- a/meson.build
+++ b/meson.build
@@ -44,6 +44,11 @@ else
     meson.add_dist_script(py, versioneer, '-o', '_version_meson.py')
 endif
 
+cy = meson.get_compiler('cython')
+if cy.version().version_compare('>=3.1.0')
+  add_project_arguments('-Xfreethreading_compatible=true', language : 'cython')
+endif
+
 # Needed by pandas.test() when it looks for the pytest ini options
 py.install_sources(
     'pyproject.toml',
diff --git a/pandas/_libs/src/vendored/ujson/python/ujson.c b/pandas/_libs/src/vendored/ujson/python/ujson.c
index 075411a23b075763dd91f5cc9b4da4d764dd6005..f369d122a3dbe3aad58ab596be6f2da03057c590 100644
--- a/pandas/_libs/src/vendored/ujson/python/ujson.c
+++ b/pandas/_libs/src/vendored/ujson/python/ujson.c
@@ -384,6 +384,10 @@ PyMODINIT_FUNC PyInit_json(void) {
     return NULL;
   }
 
+#ifdef Py_GIL_DISABLED
+  PyUnstable_Module_SetGIL(module, Py_MOD_GIL_NOT_USED);
+#endif
+
 #ifndef PYPY_VERSION
   PyObject *mod_decimal = PyImport_ImportModule("decimal");
   if (mod_decimal) {