diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/Constants.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/Constants.java
index f8af3be62f9c..19bece899ad0 100644
--- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/Constants.java
+++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/Constants.java
@@ -425,6 +425,25 @@ public final class Constants {
 	@API(status = EXPERIMENTAL, since = "5.5")
 	public static final String DEFAULT_AFTER_ALL_METHOD_TIMEOUT_PROPERTY_NAME = JupiterConfiguration.DEFAULT_AFTER_ALL_METHOD_TIMEOUT_PROPERTY_NAME;
 
+	/**
+	 * Property used to determine if timeouts are applied to tests: {@value}.
+	 *
+	 * 
The value of this property will be used to toggle whether
+	 * {@link org.junit.jupiter.api.Timeout @Timeout} is applied to tests.
+	 *
+	 * Examples
+	 *
+	 * 
+	 * - {@code enabled}: enables timeouts.
+	 * 
- {@code disabled}: disables timeouts.
+	 * 
- {@code disabled_on_debug}: disables timeouts while debugging.
+	 * 
+	 *
+	 * @since 5.6
+	 */
+	@API(status = EXPERIMENTAL, since = "5.6")
+	public static final String TIMEOUT_MODE_PROPERTY_NAME = JupiterConfiguration.TIMEOUT_MODE_PROPERTY_NAME;
+
 	private Constants() {
 		/* no-op */
 	}
diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/config/JupiterConfiguration.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/config/JupiterConfiguration.java
index 67b31bebbcf4..c9a14c5bcb25 100644
--- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/config/JupiterConfiguration.java
+++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/config/JupiterConfiguration.java
@@ -46,6 +46,7 @@ public interface JupiterConfiguration {
 	String DEFAULT_BEFORE_EACH_METHOD_TIMEOUT_PROPERTY_NAME = "junit.jupiter.execution.timeout.beforeeach.method.default";
 	String DEFAULT_AFTER_EACH_METHOD_TIMEOUT_PROPERTY_NAME = "junit.jupiter.execution.timeout.aftereach.method.default";
 	String DEFAULT_AFTER_ALL_METHOD_TIMEOUT_PROPERTY_NAME = "junit.jupiter.execution.timeout.afterall.method.default";
+	String TIMEOUT_MODE_PROPERTY_NAME = "junit.jupiter.execution.timeout.mode";
 
 	Optional getRawConfigurationParameter(String key);
 
diff --git a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TimeoutExtension.java b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TimeoutExtension.java
index b75b5b044904..6b7e36abdb20 100644
--- a/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TimeoutExtension.java
+++ b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TimeoutExtension.java
@@ -10,6 +10,8 @@
 
 package org.junit.jupiter.engine.extension;
 
+import static org.junit.jupiter.engine.config.JupiterConfiguration.TIMEOUT_MODE_PROPERTY_NAME;
+
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Method;
 import java.util.Optional;
@@ -21,6 +23,7 @@
 import org.junit.jupiter.api.Timeout;
 import org.junit.jupiter.api.extension.BeforeAllCallback;
 import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionConfigurationException;
 import org.junit.jupiter.api.extension.ExtensionContext;
 import org.junit.jupiter.api.extension.ExtensionContext.Store.CloseableResource;
 import org.junit.jupiter.api.extension.InvocationInterceptor;
@@ -29,6 +32,7 @@
 import org.junit.platform.commons.support.AnnotationSupport;
 import org.junit.platform.commons.util.ClassUtils;
 import org.junit.platform.commons.util.ReflectionUtils;
+import org.junit.platform.commons.util.RuntimeUtils;
 
 /**
  * @since 5.5
@@ -38,6 +42,9 @@ class TimeoutExtension implements BeforeAllCallback, BeforeEachCallback, Invocat
 	private static final ExtensionContext.Namespace NAMESPACE = ExtensionContext.Namespace.create(Timeout.class);
 	private static final String TESTABLE_METHOD_TIMEOUT_KEY = "testable_method_timeout_from_annotation";
 	private static final String GLOBAL_TIMEOUT_CONFIG_KEY = "global_timeout_config";
+	public static final String ENABLED_MODE_VALUE = "enabled";
+	public static final String DISABLED_MODE_VALUE = "disabled";
+	public static final String DISABLED_ON_DEBUG_MODE_VALUE = "disabled_on_debug";
 
 	@Override
 	public void beforeAll(ExtensionContext context) {
@@ -145,7 +152,7 @@ private TimeoutConfiguration getGlobalTimeoutConfiguration(ExtensionContext exte
 
 	private  Invocation decorate(Invocation invocation, ReflectiveInvocationContext invocationContext,
 			ExtensionContext extensionContext, TimeoutDuration timeout) {
-		if (timeout == null) {
+		if (timeout == null || isModeIndicatingDisabled(extensionContext)) {
 			return invocation;
 		}
 		return new TimeoutInvocation<>(invocation, timeout, getExecutor(extensionContext),
@@ -165,6 +172,24 @@ private ScheduledExecutorService getExecutor(ExtensionContext extensionContext)
 		return extensionContext.getRoot().getStore(NAMESPACE).getOrComputeIfAbsent(ExecutorResource.class).get();
 	}
 
+	private boolean isModeIndicatingDisabled(ExtensionContext extensionContext) {
+		Optional mode = extensionContext.getConfigurationParameter(TIMEOUT_MODE_PROPERTY_NAME);
+		return mode.filter(this::isDisabled).isPresent();
+	}
+
+	private boolean isDisabled(String mode) {
+		if (mode.equals(ENABLED_MODE_VALUE)) {
+			return false;
+		}
+		if (mode.equals(DISABLED_MODE_VALUE)) {
+			return true;
+		}
+		if (mode.equals(DISABLED_ON_DEBUG_MODE_VALUE)) {
+			return RuntimeUtils.isDebug();
+		}
+		throw new ExtensionConfigurationException("Unsupported timeout extension mode: " + mode);
+	}
+
 	@FunctionalInterface
 	private interface TimeoutProvider extends Function> {
 	}
diff --git a/junit-jupiter-engine/src/test/java/org/junit/jupiter/engine/extension/TimeoutExtensionTests.java b/junit-jupiter-engine/src/test/java/org/junit/jupiter/engine/extension/TimeoutExtensionTests.java
index d85650564bb8..ceef9e8d8200 100644
--- a/junit-jupiter-engine/src/test/java/org/junit/jupiter/engine/extension/TimeoutExtensionTests.java
+++ b/junit-jupiter-engine/src/test/java/org/junit/jupiter/engine/extension/TimeoutExtensionTests.java
@@ -23,6 +23,7 @@
 import static org.junit.jupiter.engine.Constants.DEFAULT_TEST_FACTORY_METHOD_TIMEOUT_PROPERTY_NAME;
 import static org.junit.jupiter.engine.Constants.DEFAULT_TEST_METHOD_TIMEOUT_PROPERTY_NAME;
 import static org.junit.jupiter.engine.Constants.DEFAULT_TEST_TEMPLATE_METHOD_TIMEOUT_PROPERTY_NAME;
+import static org.junit.jupiter.engine.Constants.TIMEOUT_MODE_PROPERTY_NAME;
 import static org.junit.platform.commons.util.CollectionUtils.getOnlyElement;
 import static org.junit.platform.engine.TestExecutionResult.Status.FAILED;
 import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
@@ -47,6 +48,7 @@
 import org.junit.jupiter.api.Timeout;
 import org.junit.jupiter.engine.AbstractJupiterTestEngineTests;
 import org.junit.platform.commons.PreconditionViolationException;
+import org.junit.platform.commons.util.RuntimeUtils;
 import org.junit.platform.testkit.engine.EngineExecutionResults;
 import org.junit.platform.testkit.engine.Events;
 import org.junit.platform.testkit.engine.Execution;
@@ -74,6 +76,46 @@ void appliesTimeoutOnAnnotatedTestMethods() {
 				.hasMessage("testMethod() timed out after 10 milliseconds");
 	}
 
+	@Test
+	@DisplayName("is not applied on annotated @Test methods using timeout mode: disabled")
+	void doesNotApplyTimeoutOnAnnotatedTestMethodsUsingDisabledTimeoutMode() {
+		EngineExecutionResults results = executeTests(request() //
+				.selectors(selectMethod(TimeoutAnnotatedTestMethodTestCase.class, "testMethod")) //
+				.configurationParameter(DEFAULT_TEST_METHOD_TIMEOUT_PROPERTY_NAME, "42ns") //
+				.configurationParameter(TIMEOUT_MODE_PROPERTY_NAME, "disabled").build());
+
+		Execution execution = findExecution(results.testEvents(), "testMethod()");
+		assertThat(execution.getTerminationInfo().getExecutionResult().getThrowable()) //
+				.isEmpty();
+	}
+
+	@Test
+	@DisplayName("is not applied on annotated @Test methods using timeout mode: disabled")
+	void applyTimeoutOnAnnotatedTestMethodsUsingDisabledOnDebugTimeoutMode() {
+		EngineExecutionResults results = executeTests(request() //
+				.selectors(selectMethod(TimeoutAnnotatedTestMethodTestCase.class, "testMethod")) //
+				.configurationParameter(DEFAULT_TEST_METHOD_TIMEOUT_PROPERTY_NAME, "42ns") //
+				.configurationParameter(TIMEOUT_MODE_PROPERTY_NAME, "disabled_on_debug").build());
+
+		Execution execution = findExecution(results.testEvents(), "testMethod()");
+
+		assertThat(execution.getDuration()) //
+				.isGreaterThanOrEqualTo(Duration.ofMillis(10)) //
+				// The check to see if debugging is pushing the timer just above 1 second
+				.isLessThan(Duration.ofSeconds(2));
+
+		// Should we test if we're debugging? This test will fail if we are debugging.
+		if (RuntimeUtils.isDebug()) {
+			assertThat(execution.getTerminationInfo().getExecutionResult().getThrowable()) //
+					.isEmpty();
+		}
+		else {
+			assertThat(execution.getTerminationInfo().getExecutionResult().getThrowable().orElseThrow()) //
+					.isInstanceOf(TimeoutException.class) //
+					.hasMessage("testMethod() timed out after 10 milliseconds");
+		}
+	}
+
 	@Test
 	@DisplayName("is applied on annotated @TestTemplate methods")
 	void appliesTimeoutOnAnnotatedTestTemplateMethods() {
diff --git a/junit-platform-commons/src/main/java/org/junit/platform/commons/util/RuntimeUtils.java b/junit-platform-commons/src/main/java/org/junit/platform/commons/util/RuntimeUtils.java
new file mode 100644
index 000000000000..0fd9579c79aa
--- /dev/null
+++ b/junit-platform-commons/src/main/java/org/junit/platform/commons/util/RuntimeUtils.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2015-2019 the original author or authors.
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v2.0 which
+ * accompanies this distribution and is available at
+ *
+ * https://www.eclipse.org/legal/epl-v20.html
+ */
+
+package org.junit.platform.commons.util;
+
+import static org.apiguardian.api.API.Status.INTERNAL;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.apiguardian.api.API;
+
+/**
+ * Collection of utilities for working with {@link Runtime},
+ * {@link java.lang.management.RuntimeMXBean}, etc.
+ *
+ *DISCLAIMER
+ *
+ * These utilities are intended solely for usage within the JUnit framework
+ * itself. Any usage by external parties is not supported.
+ * Use at your own risk!
+ *
+ * @since 1.6
+ */
+@API(status = INTERNAL, since = "1.6")
+public final class RuntimeUtils {
+
+	private RuntimeUtils() {
+		/* no-op */
+	}
+
+	/**
+	 * Try to get the input arguments the VM was started with.
+	 */
+	public static Optional> getInputArguments() {
+		Optional> managementFactoryClass = ReflectionUtils.tryToLoadClass(
+			"java.lang.management.ManagementFactory").toOptional();
+		if (!managementFactoryClass.isPresent()) {
+			return Optional.empty();
+		}
+		// Can't use "java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments()"
+		// directly as module "java.management" might not be available and/or the current platform
+		// doesn't support the Java Management Extensions (JMX) API (like Android?).
+		// See https://github.com/junit-team/junit4/pull/1187
+		try {
+			Object bean = managementFactoryClass.get().getMethod("getRuntimeMXBean").invoke(null);
+			Class> mx = ReflectionUtils.tryToLoadClass("java.lang.management.RuntimeMXBean").get();
+			@SuppressWarnings("unchecked")
+			List args = (List) mx.getMethod("getInputArguments").invoke(bean);
+			return Optional.of(args);
+		}
+		catch (Exception e) {
+			return Optional.empty();
+		}
+	}
+
+	/**
+	 * Try to determine whether the VM was started in debug mode or not.
+	 */
+	public static boolean isDebug() {
+		Optional> optionalArguments = getInputArguments();
+		if (!optionalArguments.isPresent()) {
+			return false;
+		}
+		for (String argument : optionalArguments.get()) {
+			if (argument.startsWith("-agentlib:jdwp")) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+}
diff --git a/junit-platform-commons/src/module/org.junit.platform.commons/module-info.java b/junit-platform-commons/src/module/org.junit.platform.commons/module-info.java
index 39b82ecee720..6086a63e4aee 100644
--- a/junit-platform-commons/src/module/org.junit.platform.commons/module-info.java
+++ b/junit-platform-commons/src/module/org.junit.platform.commons/module-info.java
@@ -9,7 +9,8 @@
  */
 
 module org.junit.platform.commons {
-	requires java.logging; // TODO Is "requires transitive java.logging" needed here?
+	requires java.logging;
+	requires java.management; // needed by RuntimeUtils to determine input arguments
 	requires transitive org.apiguardian.api;
 
 	exports org.junit.platform.commons;
diff --git a/platform-tests/src/test/java/org/junit/platform/commons/util/RuntimeUtilsTests.java b/platform-tests/src/test/java/org/junit/platform/commons/util/RuntimeUtilsTests.java
new file mode 100644
index 000000000000..b30dde8d719e
--- /dev/null
+++ b/platform-tests/src/test/java/org/junit/platform/commons/util/RuntimeUtilsTests.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2015-2019 the original author or authors.
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v2.0 which
+ * accompanies this distribution and is available at
+ *
+ * https://www.eclipse.org/legal/epl-v20.html
+ */
+
+package org.junit.platform.commons.util;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit tests for {@link RuntimeUtils}.
+ *
+ * @since 1.6
+ */
+class RuntimeUtilsTests {
+
+	@Test
+	void jmxIsAvailableAndInputArgumentsAreReturned() {
+		var optionalArguments = RuntimeUtils.getInputArguments();
+		assertTrue(optionalArguments.isPresent(), "JMX not available or something else happened...");
+		var arguments = optionalArguments.get();
+		assertNotNull(arguments);
+	}
+
+}
diff --git a/platform-tooling-support-tests/projects/jar-describe-module/junit-platform-commons.expected.txt b/platform-tooling-support-tests/projects/jar-describe-module/junit-platform-commons.expected.txt
index 543a7ccb8090..e157f1dc7ebf 100644
--- a/platform-tooling-support-tests/projects/jar-describe-module/junit-platform-commons.expected.txt
+++ b/platform-tooling-support-tests/projects/jar-describe-module/junit-platform-commons.expected.txt
@@ -5,6 +5,7 @@ exports org.junit.platform.commons.function
 exports org.junit.platform.commons.support
 requires java.base mandated
 requires java.logging
+requires java.management
 requires org.apiguardian.api transitive
 qualified exports org.junit.platform.commons.logging to org.junit.jupiter.api org.junit.jupiter.engine org.junit.jupiter.migrationsupport org.junit.jupiter.params org.junit.platform.console org.junit.platform.engine org.junit.platform.launcher org.junit.platform.reporting org.junit.platform.runner org.junit.platform.suite.api org.junit.platform.testkit org.junit.vintage.engine
 qualified exports org.junit.platform.commons.util to org.junit.jupiter.api org.junit.jupiter.engine org.junit.jupiter.migrationsupport org.junit.jupiter.params org.junit.platform.console org.junit.platform.engine org.junit.platform.launcher org.junit.platform.reporting org.junit.platform.runner org.junit.platform.suite.api org.junit.platform.testkit org.junit.vintage.engine
\ No newline at end of file