diff --git a/dev-packages/node-integration-tests/suites/express/tracing/server.js b/dev-packages/node-integration-tests/suites/express/tracing/server.js
index f9b4ae24b339..0291ee656995 100644
--- a/dev-packages/node-integration-tests/suites/express/tracing/server.js
+++ b/dev-packages/node-integration-tests/suites/express/tracing/server.js
@@ -8,6 +8,16 @@ Sentry.init({
   tracePropagationTargets: [/^(?!.*test).*$/],
   tracesSampleRate: 1.0,
   transport: loggingTransport,
+  integrations: [
+    Sentry.httpIntegration({
+      ignoreIncomingRequestBody: (url) => {
+        if (url.includes('/test-post-ignore-body')) {
+          return true;
+        }
+        return false;
+      },
+    }),
+  ],
 });
 
 // express must be required after Sentry is initialized
@@ -43,6 +53,10 @@ app.post('/test-post', function (req, res) {
   res.send({ status: 'ok', body: req.body });
 });
 
+app.post('/test-post-ignore-body', function (req, res) {
+  res.send({ status: 'ok', body: req.body });
+});
+
 Sentry.setupExpressErrorHandler(app);
 
 startExpressServerAndSendPortToRunner(app);
diff --git a/dev-packages/node-integration-tests/suites/express/tracing/test.ts b/dev-packages/node-integration-tests/suites/express/tracing/test.ts
index ebf9977e722b..ebe710bdc0d0 100644
--- a/dev-packages/node-integration-tests/suites/express/tracing/test.ts
+++ b/dev-packages/node-integration-tests/suites/express/tracing/test.ts
@@ -1,5 +1,6 @@
 import { afterAll, describe, expect, test } from 'vitest';
 import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
+import { assertSentryTransaction } from '../../../utils/assertions';
 
 describe('express tracing', () => {
   afterAll(() => {
@@ -244,6 +245,34 @@ describe('express tracing', () => {
         });
         await runner.completed();
       });
+
+      test('correctly ignores request data', async () => {
+        const runner = createRunner(__dirname, 'server.js')
+          .expect({
+            transaction: e => {
+              assertSentryTransaction(e, {
+                transaction: 'POST /test-post-ignore-body',
+                request: {
+                  url: expect.stringMatching(/^http:\/\/localhost:(\d+)\/test-post-ignore-body$/),
+                  method: 'POST',
+                  headers: {
+                    'user-agent': expect.stringContaining(''),
+                    'content-type': 'application/octet-stream',
+                  },
+                },
+              });
+              // Ensure the request body has been ignored
+              expect(e).have.property('request').that.does.not.have.property('data');
+            },
+          })
+          .start();
+
+        runner.makeRequest('post', '/test-post-ignore-body', {
+          headers: { 'Content-Type': 'application/octet-stream' },
+          data: Buffer.from('some plain text in buffer'),
+        });
+        await runner.completed();
+      });
     });
   });
 });
diff --git a/packages/node/src/integrations/http/SentryHttpInstrumentation.ts b/packages/node/src/integrations/http/SentryHttpInstrumentation.ts
index aa1f0157f2cf..0e0502b6fd1f 100644
--- a/packages/node/src/integrations/http/SentryHttpInstrumentation.ts
+++ b/packages/node/src/integrations/http/SentryHttpInstrumentation.ts
@@ -58,6 +58,15 @@ export type SentryHttpInstrumentationOptions = InstrumentationConfig & {
    */
   ignoreOutgoingRequests?: (url: string, request: RequestOptions) => boolean;
 
+  /**
+   * Do not capture the request body for incoming HTTP requests to URLs where the given callback returns `true`.
+   * This can be useful for long running requests where the body is not needed and we want to avoid capturing it.
+   *
+   * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.
+   * @param request Contains the {@type RequestOptions} object used to make the outgoing request.
+   */
+  ignoreIncomingRequestBody?: (url: string, request: RequestOptions) => boolean;
+
   /**
    * Whether the integration should create [Sessions](https://docs.sentry.io/product/releases/health/#sessions) for incoming requests to track the health and crash-free rate of your releases in Sentry.
    * Read more about Release Health: https://docs.sentry.io/product/releases/health/
@@ -150,6 +159,7 @@ export class SentryHttpInstrumentation extends InstrumentationBase<SentryHttpIns
   ) => (this: unknown, event: string, ...args: unknown[]) => boolean {
     // eslint-disable-next-line @typescript-eslint/no-this-alias
     const instrumentation = this;
+    const { ignoreIncomingRequestBody } = instrumentation.getConfig();
 
     return (
       original: (event: string, ...args: unknown[]) => boolean,
@@ -171,7 +181,10 @@ export class SentryHttpInstrumentation extends InstrumentationBase<SentryHttpIns
         // request.ip is non-standard but some frameworks set this
         const ipAddress = (request as { ip?: string }).ip || request.socket?.remoteAddress;
 
-        patchRequestToCaptureBody(request, isolationScope);
+        const url = request.url || '/';
+        if (!ignoreIncomingRequestBody?.(url, request)) {
+          patchRequestToCaptureBody(request, isolationScope);
+        }
 
         // Update the isolation scope, isolate this request
         isolationScope.setSDKProcessingMetadata({ normalizedRequest, ipAddress });
@@ -180,7 +193,7 @@ export class SentryHttpInstrumentation extends InstrumentationBase<SentryHttpIns
         // Ideally, framework instrumentations coming after the HttpInstrumentation
         // update the transactionName once we get a parameterized route.
         const httpMethod = (request.method || 'GET').toUpperCase();
-        const httpTarget = stripUrlQueryAndFragment(request.url || '/');
+        const httpTarget = stripUrlQueryAndFragment(url);
 
         const bestEffortTransactionName = `${httpMethod} ${httpTarget}`;
 
diff --git a/packages/node/src/integrations/http/index.ts b/packages/node/src/integrations/http/index.ts
index c8ba11655dcb..f46724aa9b72 100644
--- a/packages/node/src/integrations/http/index.ts
+++ b/packages/node/src/integrations/http/index.ts
@@ -73,6 +73,15 @@ interface HttpOptions {
    */
   ignoreIncomingRequests?: (urlPath: string, request: IncomingMessage) => boolean;
 
+  /**
+   * Do not capture the request body for incoming HTTP requests to URLs where the given callback returns `true`.
+   * This can be useful for long running requests where the body is not needed and we want to avoid capturing it.
+   *
+   * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.
+   * @param request Contains the {@type RequestOptions} object used to make the outgoing request.
+   */
+  ignoreIncomingRequestBody?: (url: string, request: RequestOptions) => boolean;
+
   /**
    * If true, do not generate spans for incoming requests at all.
    * This is used by Remix to avoid generating spans for incoming requests, as it generates its own spans.