diff --git a/swh/core/api/gunicorn_config.py b/swh/core/api/gunicorn_config.py
index 7de6bb7ac41332acacc2aef61a545b8fd2cd4ec5..1e2ffbea2019411c1ebc5189a8c9cb0d9debb4a0 100644
--- a/swh/core/api/gunicorn_config.py
+++ b/swh/core/api/gunicorn_config.py
@@ -11,6 +11,7 @@ and redefining functions and variables they want.
 May be imported by gunicorn using
 `--config 'python:swh.core.api.gunicorn_config'`."""
 
+from typing import Optional
 
 from ..sentry import init_sentry
 
@@ -24,6 +25,7 @@ def post_fork(
     sentry_integrations=None,
     extra_sentry_kwargs={},
     disable_logging_events=True,
+    traces_sample_rate: Optional[float] = None,
 ):
     # Initializes sentry as soon as possible in gunicorn's worker processes.
 
@@ -38,4 +40,5 @@ def post_fork(
         integrations=sentry_integrations,
         extra_kwargs=extra_sentry_kwargs,
         disable_logging_events=disable_logging_events,
+        traces_sample_rate=traces_sample_rate,
     )
diff --git a/swh/core/api/tests/test_gunicorn.py b/swh/core/api/tests/test_gunicorn.py
index c19d693af81814373e234aecb1440452579b9064..3a4b21a5c544cdf67bb8b72f39a142c04920e787 100644
--- a/swh/core/api/tests/test_gunicorn.py
+++ b/swh/core/api/tests/test_gunicorn.py
@@ -29,6 +29,7 @@ def test_post_fork_default(mocker):
         debug=False,
         release="0.0.0",
         environment=None,
+        traces_sample_rate=None,
     )
 
 
@@ -53,6 +54,7 @@ def test_post_fork_with_dsn_env(mocker):
         debug=False,
         release=None,
         environment=None,
+        traces_sample_rate=None,
     )
 
 
@@ -87,6 +89,7 @@ def test_post_fork_with_package_env(mocker):
         debug=False,
         release="swh.core@" + version,
         environment="tests",
+        traces_sample_rate=None,
     )
 
 
@@ -114,6 +117,7 @@ def test_post_fork_debug(mocker):
         debug=True,
         release=None,
         environment=None,
+        traces_sample_rate=None,
     )
 
 
@@ -134,6 +138,7 @@ def test_post_fork_no_flask(mocker):
         debug=False,
         release=None,
         environment=None,
+        traces_sample_rate=None,
     )
 
 
@@ -152,6 +157,7 @@ def test_post_fork_override_logging_events_envvar(mocker):
         debug=False,
         release=None,
         environment=None,
+        traces_sample_rate=None,
     )
 
 
@@ -178,4 +184,58 @@ def test_post_fork_extras(mocker):
         bar="baz",
         release=None,
         environment=None,
+        traces_sample_rate=None,
+    )
+
+
+def test_post_fork_traces_sample_rate(mocker):
+    flask_integration = object()  # unique object to check for equality
+    logging_integration = object()  # unique object to check for equality
+    mocker.patch(
+        "sentry_sdk.integrations.flask.FlaskIntegration", new=lambda: flask_integration
+    )
+    mocker.patch(
+        "sentry_sdk.integrations.logging.LoggingIntegration",
+        new=lambda event_level: logging_integration,
+    )
+    sentry_sdk_init = mocker.patch("sentry_sdk.init")
+    mocker.patch.dict(os.environ, {"SWH_SENTRY_DSN": "test_dsn"})
+
+    gunicorn_config.post_fork(None, None, traces_sample_rate=1.0)
+
+    sentry_sdk_init.assert_called_once_with(
+        dsn="test_dsn",
+        integrations=[flask_integration, logging_integration],
+        debug=False,
+        release=None,
+        environment=None,
+        traces_sample_rate=1.0,
+    )
+
+
+def test_post_fork_override_traces_sample_rate_envvar(mocker):
+    flask_integration = object()  # unique object to check for equality
+    logging_integration = object()  # unique object to check for equality
+    mocker.patch(
+        "sentry_sdk.integrations.flask.FlaskIntegration", new=lambda: flask_integration
+    )
+    mocker.patch(
+        "sentry_sdk.integrations.logging.LoggingIntegration",
+        new=lambda event_level: logging_integration,
+    )
+    sentry_sdk_init = mocker.patch("sentry_sdk.init")
+    mocker.patch.dict(
+        os.environ,
+        {"SWH_SENTRY_DSN": "test_dsn", "SWH_SENTRY_TRACES_SAMPLE_RATE": "0.999"},
+    )
+
+    gunicorn_config.post_fork(None, None)
+
+    sentry_sdk_init.assert_called_once_with(
+        dsn="test_dsn",
+        integrations=[flask_integration, logging_integration],
+        debug=False,
+        release=None,
+        environment=None,
+        traces_sample_rate=0.999,
     )
diff --git a/swh/core/sentry.py b/swh/core/sentry.py
index 6fd5b1bf8e177353436b79c35a233e56699df995..a0dd15546ccc680d50250afc56eafa3f4b4d050f 100644
--- a/swh/core/sentry.py
+++ b/swh/core/sentry.py
@@ -46,6 +46,37 @@ def override_with_bool_envvar(envvar: str, default: bool) -> bool:
         return default
 
 
+def override_with_float_envvar(
+    envvar: str, default: Optional[float]
+) -> Optional[float]:
+    """Override `default` with the environment variable `envvar` casted as a float.
+
+    `default` is returned if the environment variable `envvar` is missing or if
+    we're not able to cast it to a float.
+
+    Args:
+        envvar: the name of the environment variable
+        default: default value
+
+    Returns:
+        A float or `default`
+    """
+    envvalue = os.environ.get(envvar)
+    if envvalue is None:
+        return default
+    try:
+        return float(envvalue)
+    except ValueError:
+        logger.warning(
+            "Could not interpret environment variable %s=%r as float, "
+            "using default value %s",
+            envvar,
+            envvalue,
+            default,
+        )
+        return default
+
+
 def init_sentry(
     sentry_dsn: Optional[str] = None,
     *,
@@ -54,10 +85,11 @@ def init_sentry(
     debug: bool = False,
     disable_logging_events: bool = False,
     integrations: Optional[List] = None,
+    traces_sample_rate: Optional[float] = None,
     extra_kwargs: Optional[Dict] = None,
     deferred_init: bool = False,
-):
-    """Configure the sentry integration
+) -> None:
+    """Configure the sentry integration.
 
     Args:
       sentry_dsn: Sentry DSN; where sentry report will be sent. Overridden by
@@ -70,10 +102,12 @@ def init_sentry(
         log entries as Sentry events. Overridden by
         :envvar:`SWH_SENTRY_DISABLE_LOGGING_EVENTS`
       integrations: list of dedicated Sentry integrations to include
+      traces_sample_rate: a number between 0 and 1, controlling the percentage chance a
+        given transaction will be sent to Sentry. Overridden by
+        :envvar:`SWH_SENTRY_TRACES_SAMPLE_RATE`
       extra_kwargs: dict of additional parameters passed to :func:`sentry_sdk.init`
       deferred_init: indicates that sentry will be properly initialized in subsequent
         calls and that no warnings about missing DSN should be logged
-
     """
     if integrations is None:
         integrations = []
@@ -101,10 +135,17 @@ def init_sentry(
 
         integrations.append(LoggingIntegration(event_level=None))
 
+    # to completely disable tracing `traces_sample_rate` should be set to None instead
+    # of 0.0
+    traces_sample_rate = override_with_float_envvar(
+        "SWH_SENTRY_TRACES_SAMPLE_RATE", traces_sample_rate
+    )
+
     sentry_sdk.init(
         release=get_sentry_release(main_package, sentry_dsn),
         environment=environment,
         dsn=sentry_dsn,
+        traces_sample_rate=traces_sample_rate,
         integrations=integrations,
         debug=debug,
         **extra_kwargs,
diff --git a/swh/core/tests/test_cli.py b/swh/core/tests/test_cli.py
index cdd50e4aee8dc9cfd2121c7ce6fbc664ba4b7586..170cb1e1b841615c71c7c13e8ff005a4b141aa2a 100644
--- a/swh/core/tests/test_cli.py
+++ b/swh/core/tests/test_cli.py
@@ -124,6 +124,7 @@ def test_command(swhmain, mocker):
         integrations=[],
         release="0.0.0",
         environment=None,
+        traces_sample_rate=None,
     )
     assert_result(result)
     assert result.output.strip() == "Hello SWH!"
@@ -185,6 +186,7 @@ def test_sentry(swhmain, mocker):
         integrations=[],
         release=None,
         environment=None,
+        traces_sample_rate=None,
     )
 
 
@@ -207,6 +209,7 @@ def test_sentry_debug(swhmain, mocker):
         integrations=[],
         release=None,
         environment=None,
+        traces_sample_rate=None,
     )
 
 
@@ -231,6 +234,7 @@ def test_sentry_env(swhmain, mocker):
         integrations=[],
         release=None,
         environment=None,
+        traces_sample_rate=None,
     )
 
 
@@ -259,6 +263,7 @@ def test_sentry_env_main_package(swhmain, mocker):
         integrations=[],
         release="swh.core@" + version,
         environment="tests",
+        traces_sample_rate=None,
     )
 
 
diff --git a/swh/core/tests/test_sentry.py b/swh/core/tests/test_sentry.py
index 44ad156d02e494c6781df1acf585ffba6d2100db..a5405907bd78d753be810349052dec51dc92d763 100644
--- a/swh/core/tests/test_sentry.py
+++ b/swh/core/tests/test_sentry.py
@@ -9,7 +9,11 @@ import pytest
 import sentry_sdk
 from sentry_sdk import capture_exception, capture_message, set_tag
 
-from swh.core.sentry import init_sentry, override_with_bool_envvar
+from swh.core.sentry import (
+    init_sentry,
+    override_with_bool_envvar,
+    override_with_float_envvar,
+)
 
 SENTRY_DSN = "https://user@example.org/1234"
 
@@ -48,6 +52,31 @@ def test_override_with_bool_envvar_logging(monkeypatch, caplog):
         assert caplog.records[0].levelname == "WARNING"
 
 
+@pytest.mark.parametrize(
+    "envvalue,retval",
+    (("1.0", 1.0), ("0.0", 0.0), ("0", 0.0), ("a", None)),
+)
+def test_override_with_float_envvar(monkeypatch, envvalue: str, retval: bool):
+    envvar = "OVERRIDE_WITH_FLOAT_ENVVAR"
+    monkeypatch.setenv(envvar, envvalue)
+    assert override_with_float_envvar(envvar, None) == retval
+
+
+def test_override_with_float_envvar_logging(monkeypatch, caplog):
+    envvar = "OVERRIDE_WITH_FLOAT_ENVVAR"
+    monkeypatch.setenv(envvar, "not a float env value")
+    for default in (None, 1.0):
+        caplog.clear()
+        assert override_with_float_envvar(envvar, default) == default
+        assert len(caplog.records) == 1
+        assert (
+            "OVERRIDE_WITH_FLOAT_ENVVAR='not a float env value'"
+            in caplog.records[0].getMessage()
+        )
+        assert f"using default value {default}" in caplog.records[0].getMessage()
+        assert caplog.records[0].levelname == "WARNING"
+
+
 def test_sentry():
     reports = []
     init_sentry(SENTRY_DSN, extra_kwargs={"transport": reports.append})
@@ -160,3 +189,14 @@ def test_sentry_deferred_init(caplog, deferred_init):
         )
     else:
         assert not caplog.records
+
+
+@pytest.mark.parametrize("traces_sample_rate", [1.0, 0.0, None])
+def test_sentry_traces_sample_rate(caplog, traces_sample_rate):
+    init_sentry(None, traces_sample_rate=traces_sample_rate)
+    client = sentry_sdk.get_client()
+    if traces_sample_rate is not None:
+        assert client.options["traces_sample_rate"] == traces_sample_rate
+    else:
+        assert client.options["enable_tracing"] is None
+        assert client.options["traces_sample_rate"] is None