diff --git a/dist/api_data.py b/dist/api_data.py
index 7cedda049a..5b37491d23 100755
--- a/dist/api_data.py
+++ b/dist/api_data.py
@@ -1591,6 +1591,12 @@ methods = {
             blocks only. This must be set on the primary backup cursor and it applies to all
             files for this backup''',
             type='boolean'),
+        Config('copy_pct', '0', r'''
+            percent of file needed for backup to indicate to copy the entire file
+            instead of changed blocks. If zero, then always do block copies when
+            possible. This must  be set on the primary backup cursor an it applies to all
+            files for this backup''',
+            min='0', max='100'),
         Config('enabled', 'false', r'''
             whether to configure this backup as the starting point for a subsequent incremental
             backup''',
diff --git a/src/cursor/cur_backup.c b/src/cursor/cur_backup.c
index 4722d33122..b4565080b9 100644
--- a/src/cursor/cur_backup.c
+++ b/src/cursor/cur_backup.c
@@ -583,6 +583,15 @@ __backup_config(WT_SESSION_IMPL *session, WT_CURSOR_BACKUP *cb, const char *cfg[
         incremental_config = true;
     }
 
+    WT_RET(__wt_config_gets(session, cfg, "incremental.copy_pct", &cval));
+    if (cval.val) {
+        if (is_dup)
+            WT_RET_MSG(session, EINVAL,
+              "Incremental copy_pct can only be specified on a primary backup cursor");
+        cb->copy_pct = (uint64_t)cval.val;
+        incremental_config = true;
+    }
+
     /*
      * Specifying an incremental file means we're opening a duplicate backup cursor.
      */
diff --git a/src/cursor/cur_backup_incr.c b/src/cursor/cur_backup_incr.c
index 21908dd89f..47148c7b86 100644
--- a/src/cursor/cur_backup_incr.c
+++ b/src/cursor/cur_backup_incr.c
@@ -23,6 +23,43 @@ __wt_backup_load_incr(
     return (0);
 }
 
+/*
+ * __curbackup_copy_compute --
+ *     Compute whether an incremental should just copy the entire file instead of blocks.
+ */
+static int
+__curbackup_copy_compute(WT_SESSION_IMPL *session, WT_CURSOR_BACKUP *cb, bool *copy_allp)
+{
+    wt_off_t file_sz;
+    uint64_t bit, chg_bits, end_bit, pct_bits;
+
+    *copy_allp = false;
+    /* If there is no threshold, always copy blocks. Nothing to compute. */
+    if (cb->copy_pct == 0)
+        return (0);
+
+    WT_RET(__wt_fs_size(session, cb->incr_file, &file_sz));
+    end_bit = (uint64_t)file_sz / cb->granularity;
+    if ((uint64_t)file_sz % cb->granularity != 0)
+        end_bit++;
+    /* Calculate the percentage based on granularity bits, not size. */
+    pct_bits = end_bit * cb->copy_pct / 100;
+
+    WT_ASSERT(session, end_bit <= cb->nbits);
+    bit = chg_bits = 0;
+    /* Count how many bits are set. Stop when we get to the end or have enough. */
+    while (bit < end_bit) {
+        if (__bit_test(cb->bitstring.mem, bit)) {
+            ++chg_bits;
+            if (chg_bits >= pct_bits) {
+                *copy_allp = true;
+                break;
+            }
+        }
+        ++bit;
+    }
+    return (0);
+}
 /*
  * __curbackup_incr_blkmod --
  *     Get the block modifications for a tree from its metadata and fill in the backup cursor's
@@ -36,6 +73,7 @@ __curbackup_incr_blkmod(WT_SESSION_IMPL *session, WT_BTREE *btree, WT_CURSOR_BAC
     WT_CONFIG_ITEM b, k, v;
     WT_DECL_RET;
     char *config;
+    bool copy_all;
 
     WT_ASSERT(session, btree != NULL);
     WT_ASSERT(session, btree->dhandle != NULL);
@@ -89,17 +127,23 @@ __curbackup_incr_blkmod(WT_SESSION_IMPL *session, WT_BTREE *btree, WT_CURSOR_BAC
             cb->nbits = 0;
             cb->offset = 0;
             cb->bit_offset = 0;
-            F_SET(cb, WT_CURBACKUP_RENAME);
+            F_SET(cb, WT_CURBACKUP_COPY_ALL);
         } else {
-            F_CLR(cb, WT_CURBACKUP_RENAME);
-
+            F_CLR(cb, WT_CURBACKUP_COPY_ALL);
             /*
              * We found a match. Load the block information into the cursor.
              */
             if ((ret = __wt_config_subgets(session, &v, "blocks", &b)) == 0) {
                 WT_ERR(__wt_backup_load_incr(session, &b, &cb->bitstring, cb->nbits));
                 cb->bit_offset = 0;
-                F_SET(cb, WT_CURBACKUP_INCR_INIT);
+                copy_all = false;
+                WT_ERR(__curbackup_copy_compute(session, cb, &copy_all));
+                if (copy_all) {
+                    __wt_buf_free(session, &cb->bitstring);
+                    cb->nbits = 0;
+                    F_SET(cb, WT_CURBACKUP_COPY_ALL);
+                } else
+                    F_SET(cb, WT_CURBACKUP_INCR_INIT);
             }
             WT_ERR_NOTFOUND_OK(ret, false);
         }
@@ -136,7 +180,7 @@ __curbackup_incr_next(WT_CURSOR *cursor)
     F_CLR(cursor, WT_CURSTD_RAW);
 
     if (!F_ISSET(cb, WT_CURBACKUP_INCR_INIT) &&
-      (btree == NULL || F_ISSET(cb, WT_CURBACKUP_FORCE_FULL | WT_CURBACKUP_RENAME))) {
+      (btree == NULL || F_ISSET(cb, WT_CURBACKUP_COPY_ALL | WT_CURBACKUP_FORCE_FULL))) {
         /*
          * We don't have this object's incremental information or it's a forced file copy. If this
          * is a log file, use the full pathname that may include the log path.
@@ -173,7 +217,8 @@ __curbackup_incr_next(WT_CURSOR *cursor)
              * There are several cases where we do not have block modification information for
              * the file. They are described and handled as follows:
              *
-             * 1. Renamed file. Always return the whole file information.
+             * 1. Renamed file or copy block percentage threshold met. Always return the whole
+             *    file information.
              * 2. Newly created file without checkpoint information. Return the whole
              *    file information.
              * 3. File created and checkpointed before incremental backups were configured.
@@ -181,9 +226,9 @@ __curbackup_incr_next(WT_CURSOR *cursor)
              * 4. File that has not been modified since the previous incremental backup.
              *    Return no file information as there is no new information.
              */
-            if (cb->bitstring.mem == NULL || F_ISSET(cb, WT_CURBACKUP_RENAME)) {
+            if (cb->bitstring.mem == NULL || F_ISSET(cb, WT_CURBACKUP_COPY_ALL)) {
                 F_SET(cb, WT_CURBACKUP_INCR_INIT);
-                if (F_ISSET(cb, WT_CURBACKUP_RENAME) ||
+                if (F_ISSET(cb, WT_CURBACKUP_COPY_ALL) ||
                   (F_ISSET(cb, WT_CURBACKUP_CKPT_FAKE) && F_ISSET(cb, WT_CURBACKUP_HAS_CB_INFO))) {
                     WT_ERR(__wt_fs_size(session, cb->incr_file, &size));
                     __wt_verbose_debug2(session, WT_VERB_BACKUP,
@@ -296,6 +341,7 @@ __wti_curbackup_open_incr(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *
     cursor->next = __curbackup_incr_next;
     cursor->get_key = __wt_cursor_get_key;
     cursor->get_value = __wti_cursor_get_value_notsup;
+    cb->copy_pct = other_cb->copy_pct;
     cb->incr_src = other_cb->incr_src;
 
     /* All WiredTiger owned files are full file copies. */
diff --git a/src/include/cursor.h b/src/include/cursor.h
index 1039e91578..289b0d91fe 100644
--- a/src/include/cursor.h
+++ b/src/include/cursor.h
@@ -68,6 +68,7 @@ struct __wt_cursor_backup {
 
     WT_CURSOR *incr_cursor; /* File cursor */
 
+    uint64_t copy_pct;    /* Percent of bitstring to invoke full copy */
     WT_ITEM bitstring;    /* List of modified blocks */
     uint64_t nbits;       /* Number of bits in bitstring */
     uint64_t offset;      /* Zero bit offset in bitstring */
@@ -78,16 +79,16 @@ struct __wt_cursor_backup {
 #define WT_CURBACKUP_CKPT_FAKE 0x0001u   /* Object has fake checkpoint */
 #define WT_CURBACKUP_COMPRESSED 0x0002u  /* Object uses compression */
 #define WT_CURBACKUP_CONSOLIDATE 0x0004u /* Consolidate returned info on this object */
-#define WT_CURBACKUP_DUP 0x0008u         /* Duplicated backup cursor */
-#define WT_CURBACKUP_EXPORT 0x0010u      /* Special backup cursor for export operation */
-#define WT_CURBACKUP_FORCE_FULL 0x0020u  /* Force full file copy for this cursor */
-#define WT_CURBACKUP_FORCE_STOP 0x0040u  /* Force stop incremental backup */
-#define WT_CURBACKUP_HAS_CB_INFO 0x0080u /* Object has checkpoint backup info */
-#define WT_CURBACKUP_INCR 0x0100u        /* Incremental backup cursor */
-#define WT_CURBACKUP_INCR_INIT 0x0200u   /* Cursor traversal initialized */
-#define WT_CURBACKUP_LOCKER 0x0400u      /* Hot-backup started */
-#define WT_CURBACKUP_QUERYID 0x0800u     /* Backup cursor for incremental ids */
-#define WT_CURBACKUP_RENAME 0x1000u      /* Object had a rename */
+#define WT_CURBACKUP_COPY_ALL 0x0008u    /* Object should be copied in full */
+#define WT_CURBACKUP_DUP 0x0010u         /* Duplicated backup cursor */
+#define WT_CURBACKUP_EXPORT 0x0020u      /* Special backup cursor for export operation */
+#define WT_CURBACKUP_FORCE_FULL 0x0040u  /* Force full file copy for this cursor */
+#define WT_CURBACKUP_FORCE_STOP 0x0080u  /* Force stop incremental backup */
+#define WT_CURBACKUP_HAS_CB_INFO 0x0100u /* Object has checkpoint backup info */
+#define WT_CURBACKUP_INCR 0x0200u        /* Incremental backup cursor */
+#define WT_CURBACKUP_INCR_INIT 0x0400u   /* Cursor traversal initialized */
+#define WT_CURBACKUP_LOCKER 0x0800u      /* Hot-backup started */
+#define WT_CURBACKUP_QUERYID 0x1000u     /* Backup cursor for incremental ids */
                                          /* AUTOMATIC FLAG VALUE GENERATION STOP 32 */
     uint32_t flags;
 };
diff --git a/test/utility/backup.c b/test/utility/backup.c
index dcadcf8f9e..cb4dc4fb83 100644
--- a/test/utility/backup.c
+++ b/test/utility/backup.c
@@ -59,7 +59,7 @@ testutil_backup_create_full(WT_CONNECTION *conn, const char *home_dir, int id, b
 
     /* Open the backup cursor to get the list of files to copy. */
     testutil_snprintf(buf, sizeof(buf),
-      "incremental=(granularity=%" PRIu32 "K,enabled=true,consolidate=%s,this_id=%s)",
+      "incremental=(copy_pct=90,granularity=%" PRIu32 "K,enabled=true,consolidate=%s,this_id=%s)",
       granularity_kb, consolidate ? "true" : "false", backup_id);
     testutil_check(session->open_cursor(session, "backup:", NULL, buf, &cursor));
 
@@ -125,7 +125,7 @@ testutil_backup_create_incremental(WT_CONNECTION *conn, const char *home_dir, in
 
     /* Open the backup cursor to get the list of files to copy. */
     testutil_snprintf(
-      buf, sizeof(buf), "incremental=(src_id=ID%d,this_id=ID%d)", source_id, backup_id);
+      buf, sizeof(buf), "incremental=(copy_pct=90,src_id=ID%d,this_id=ID%d)", source_id, backup_id);
     testutil_check(session->open_cursor(session, "backup:", NULL, buf, &cursor));
 
     /* Process the files. */
