diff --git a/src/btree/bt_debug.c b/src/btree/bt_debug.c
index d4babb1df..dc7a7da82 100644
--- a/src/btree/bt_debug.c
+++ b/src/btree/bt_debug.c
@@ -1191,7 +1191,8 @@ __debug_update(WT_DBG *ds, WT_UPDATE *upd, bool hexbyte)
         if (upd->txnid == WT_TXN_ABORTED)
             WT_RET(ds->f(ds,
               "\t"
-              "txn id aborted"));
+              "txn id aborted (was %" PRIu64 " 0x%" PRIx64 ")",
+              upd->orig_txnid & 0x00ffffffffffffffL, upd->orig_txnid));
         else
             WT_RET(ds->f(ds,
               "\t"
diff --git a/src/btree/bt_delete.c b/src/btree/bt_delete.c
index 4686c206c..12efd5a1c 100644
--- a/src/btree/bt_delete.c
+++ b/src/btree/bt_delete.c
@@ -204,8 +204,10 @@ __wt_delete_page_rollback(WT_SESSION_IMPL *session, WT_REF *ref)
     if (current_state == WT_REF_DELETED)
         current_state = ref->page_del->previous_state;
     else if ((updp = ref->page_del->update_list) != NULL)
-        for (; *updp != NULL; ++updp)
+        for (; *updp != NULL; ++updp) {
+            (*updp)->orig_txnid = (*updp)->txnid | 0x0100000000000000L;
             (*updp)->txnid = WT_TXN_ABORTED;
+        }
 
     /* Finally mark the truncate aborted */
     ref->page_del->txnid = WT_TXN_ABORTED;
diff --git a/src/btree/bt_read.c b/src/btree/bt_read.c
index 81adc9de7..2a64f50f9 100644
--- a/src/btree/bt_read.c
+++ b/src/btree/bt_read.c
@@ -175,6 +175,22 @@ __las_page_instantiate(WT_SESSION_IMPL *session, WT_REF *ref)
         /* Allocate the WT_UPDATE structure. */
         WT_ERR(cursor->get_value(cursor, &las_txnid, &las_timestamp, &durable_timestamp,
           &prepare_state, &upd_type, &las_value));
+        if (upd_type != WT_UPDATE_BIRTHMARK && las_value.size == 0) {
+            __wt_verbose(session, WT_VERB_TEMPORARY,
+              "LAS_PAGE: read key pageid %" PRIu64 " btree_id %" PRIu32 " las_counter %" PRIu64
+              " KEY: %.*s",
+              las_pageid, las_id, las_counter, las_key.size, las_key.data);
+            if (las_value.size == 0)
+                __wt_verbose(session, WT_VERB_TEMPORARY,
+                  "LAS_PAGE: got zero value txnid %" PRIu64 " timestamp %" PRIu64 " type %" PRIu8
+                  " VALUE: {}",
+                  las_txnid, las_timestamp, upd_type);
+            else
+                __wt_verbose(session, WT_VERB_TEMPORARY,
+                  "LAS_PAGE: got value txnid %" PRIu64 " timestamp %" PRIu64 " type %" PRIu8
+                  " VALUE: %.*s",
+                  las_txnid, las_timestamp, upd_type, las_value.size, las_value.data);
+        }
         WT_ERR(__wt_update_alloc(session, &las_value, &upd, &incr, upd_type));
         total_incr += incr;
         upd->txnid = las_txnid;
diff --git a/src/btree/row_modify.c b/src/btree/row_modify.c
index 30f27b190..4fcf384c4 100644
--- a/src/btree/row_modify.c
+++ b/src/btree/row_modify.c
@@ -93,6 +93,10 @@ __wt_row_modify(WT_CURSOR_BTREE *cbt, const WT_ITEM *key, const WT_ITEM *value,
             /* Allocate a WT_UPDATE structure and transaction ID. */
             WT_ERR(__wt_update_alloc(session, value, &upd, &upd_size, modify_type));
             WT_ERR(__wt_txn_modify(session, upd));
+            if (modify_type != WT_UPDATE_BIRTHMARK && value->size == 0)
+                __wt_verbose(session, WT_VERB_TEMPORARY,
+                  "ROW_MODIFY: zero value key %.s txnid %" PRIu64 " type %" PRIu8 " VALUE: {}",
+                  key->size, key->data, session->txn.id, modify_type);
             logged = true;
 
             /* Avoid WT_CURSOR.update data copy. */
@@ -154,6 +158,10 @@ __wt_row_modify(WT_CURSOR_BTREE *cbt, const WT_ITEM *key, const WT_ITEM *value,
         if (upd_arg == NULL) {
             WT_ERR(__wt_update_alloc(session, value, &upd, &upd_size, modify_type));
             WT_ERR(__wt_txn_modify(session, upd));
+            if (modify_type != WT_UPDATE_BIRTHMARK && value->size == 0)
+                __wt_verbose(session, WT_VERB_TEMPORARY,
+                  "ROW_MODIFY2: zero value key %.s txnid %" PRIu64 " type %" PRIu8 " VALUE: {}",
+                  key->size, key->data, session->txn.id, modify_type);
             logged = true;
 
             /* Avoid WT_CURSOR.update data copy. */
diff --git a/src/cache/cache_las.c b/src/cache/cache_las.c
index 2cacc57e6..9767b10cf 100644
--- a/src/cache/cache_las.c
+++ b/src/cache/cache_las.c
@@ -733,6 +733,22 @@ __wt_las_insert_block(
 
             cursor->set_key(cursor, las_pageid, btree_id, ++las_counter, key);
 
+            if (upd->type != WT_UPDATE_BIRTHMARK) {
+                __wt_verbose(session, WT_VERB_TEMPORARY,
+                  "LAS_INSERT: zero key pageid %" PRIu64 " btree_id %" PRIu32
+                  " las_counter %" PRIu64 " KEY: %.*s",
+                  las_pageid, btree_id, las_counter, key->size, key->data);
+                if (las_value.size == 0)
+                    __wt_verbose(session, WT_VERB_TEMPORARY,
+                      "LAS_PAGE: got zero value txnid %" PRIu64 " timestamp %" PRIu64
+                      " type %" PRIu8 " VALUE: {}",
+                      upd->txnid, upd->start_ts, upd->type);
+                else
+                    __wt_verbose(session, WT_VERB_TEMPORARY,
+                      "LAS_PAGE: got value txnid %" PRIu64 " timestamp %" PRIu64 " type %" PRIu8
+                      " VALUE: %.*s",
+                      upd->txnid, upd->start_ts, upd->type, las_value.size, las_value.data);
+            }
             /*
              * If saving a non-zero length value on the page, save a birthmark instead of
              * duplicating it in the lookaside table. (We check the length because row-store doesn't
@@ -1139,6 +1155,22 @@ __wt_las_sweep(WT_SESSION_IMPL *session)
          */
         WT_ERR(cursor->get_value(cursor, &las_txnid, &las_timestamp, &durable_timestamp,
           &prepare_state, &upd_type, &las_value));
+        if (upd_type != WT_UPDATE_BIRTHMARK) {
+            __wt_verbose(session, WT_VERB_TEMPORARY,
+              "LAS_SWEEP: got key pageid %" PRIu64 " btree_id %" PRIu32 " las_counter %" PRIu64
+              " KEY: %.*s",
+              las_pageid, las_id, las_counter, las_key.size, las_key.data);
+            if (las_value.size == 0)
+                __wt_verbose(session, WT_VERB_TEMPORARY,
+                  "LAS_PAGE: got zero value txnid %" PRIu64 " timestamp %" PRIu64 " type %" PRIu8
+                  " VALUE: {}",
+                  las_txnid, las_timestamp, upd_type);
+            else
+                __wt_verbose(session, WT_VERB_TEMPORARY,
+                  "LAS_PAGE: got value txnid %" PRIu64 " timestamp %" PRIu64 " type %" PRIu8
+                  " VALUE: %.*s",
+                  las_txnid, las_timestamp, upd_type, las_value.size, las_value.data);
+        }
 
         /*
          * Check to see if the page or key has changed this iteration, and if they have, setup
diff --git a/src/include/btmem.h b/src/include/btmem.h
index 2997fb064..10cec6f6b 100644
--- a/src/include/btmem.h
+++ b/src/include/btmem.h
@@ -1069,7 +1069,8 @@ struct __wt_ikey {
  *	formed into a forward-linked list.
  */
 struct __wt_update {
-    volatile uint64_t txnid; /* transaction ID */
+    volatile uint64_t txnid;      /* transaction ID */
+    volatile uint64_t orig_txnid; /* transaction ID */
 
     wt_timestamp_t durable_ts; /* timestamps */
     wt_timestamp_t start_ts;
@@ -1107,7 +1108,11 @@ struct __wt_update {
  * WT_UPDATE_SIZE is the expected structure size excluding the payload data -- we verify the build
  * to ensure the compiler hasn't inserted padding.
  */
+#if 0
 #define WT_UPDATE_SIZE 38
+#else
+#define WT_UPDATE_SIZE 46
+#endif
 
 /*
  * The memory size of an update: include some padding because this is such a common case that
diff --git a/src/include/session.h b/src/include/session.h
index f4b82b8f5..55ea76ba5 100644
--- a/src/include/session.h
+++ b/src/include/session.h
@@ -47,6 +47,14 @@ typedef TAILQ_HEAD(__wt_cursor_list, __wt_cursor) WT_CURSOR_LIST;
 
 /* Maximum number of buckets to visit during cursor sweep. */
 #define WT_SESSION_CURSOR_SWEEP_MAX 32
+struct __sess_dbg {
+    uint64_t oldest_id;
+    uint64_t id;
+    uint64_t pinned_ts;
+    uint64_t ts;
+    bool ret;
+};
+
 /*
  * WT_SESSION_IMPL --
  *	Implementation of WT_SESSION.
@@ -135,6 +143,9 @@ struct __wt_session_impl {
 #define WT_SESSION_BG_SYNC_MSEC 1200000
     WT_LSN bg_sync_lsn; /* Background sync operation LSN. */
     u_int ncursors;     /* Count of active file cursors. */
+#define WT_SESS_DBG 128
+    struct __sess_dbg dbg[WT_SESS_DBG];
+    u_int dbg_i;
 
     void *block_manager; /* Block-manager support */
     int (*block_manager_cleanup)(WT_SESSION_IMPL *);
diff --git a/src/include/txn.i b/src/include/txn.i
index 757627dff..9dba27cea 100644
--- a/src/include/txn.i
+++ b/src/include/txn.i
@@ -517,6 +517,7 @@ __txn_visible_all_id(WT_SESSION_IMPL *session, uint64_t id)
     uint64_t oldest_id;
 
     oldest_id = __wt_txn_oldest_id(session);
+    session->dbg[session->dbg_i % WT_SESS_DBG].oldest_id = oldest_id;
 
     return (WT_TXNID_LT(id, oldest_id));
 }
@@ -538,19 +539,28 @@ __wt_txn_visible_all(WT_SESSION_IMPL *session, uint64_t id, wt_timestamp_t times
     if (F_ISSET(S2C(session), WT_CONN_CLOSING))
         return (true);
 
-    if (!__txn_visible_all_id(session, id))
+    session->dbg[++session->dbg_i % WT_SESS_DBG].id = id;
+    if (!__txn_visible_all_id(session, id)) {
+        session->dbg[session->dbg_i % WT_SESS_DBG].ret = false;
         return (false);
+    }
 
     /* Timestamp check. */
-    if (timestamp == WT_TS_NONE)
+    if (timestamp == WT_TS_NONE) {
+        session->dbg[session->dbg_i % WT_SESS_DBG].ret = true;
         return (true);
+    }
 
+    session->dbg[session->dbg_i % WT_SESS_DBG].ts = timestamp;
     /* If no oldest timestamp has been supplied, updates have to stay in cache. */
     if (S2C(session)->txn_global.has_pinned_timestamp) {
         __wt_txn_pinned_timestamp(session, &pinned_ts);
+        session->dbg[session->dbg_i % WT_SESS_DBG].pinned_ts = pinned_ts;
+        session->dbg[session->dbg_i % WT_SESS_DBG].ret = (timestamp <= pinned_ts);
         return (timestamp <= pinned_ts);
     }
 
+    session->dbg[session->dbg_i % WT_SESS_DBG].ret = false;
     return (false);
 }
 
diff --git a/src/reconcile/rec_visibility.c b/src/reconcile/rec_visibility.c
index 451d4f2fa..683b3dcb1 100644
--- a/src/reconcile/rec_visibility.c
+++ b/src/reconcile/rec_visibility.c
@@ -104,6 +104,7 @@ __rec_append_orig_value(
 
     if (upd->type == WT_UPDATE_BIRTHMARK) {
         upd->type = WT_UPDATE_STANDARD;
+        upd->orig_txnid = upd->txnid | 0x0200000000000000L;
         upd->txnid = WT_TXN_ABORTED;
     }
 
diff --git a/src/txn/txn.c b/src/txn/txn.c
index e8e97b2df..a5aec40ee 100644
--- a/src/txn/txn.c
+++ b/src/txn/txn.c
@@ -687,6 +687,7 @@ __txn_resolve_prepared_op(WT_SESSION_IMPL *session, WT_TXN_OP *op, bool commit)
             break;
 
         if (!commit) {
+            upd->orig_txnid = upd->txnid | 0x0300000000000000L;
             upd->txnid = WT_TXN_ABORTED;
             continue;
         }
@@ -1015,6 +1016,7 @@ __wt_txn_commit(WT_SESSION_IMPL *session, const char *cfg[])
                  * Switch reserved operations to abort to simplify obsolete update list truncation.
                  */
                 if (upd->type == WT_UPDATE_RESERVE) {
+                    upd->orig_txnid = upd->txnid | 0x0400000000000000L;
                     upd->txnid = WT_TXN_ABORTED;
                     break;
                 }
@@ -1181,6 +1183,7 @@ __wt_txn_prepare(WT_SESSION_IMPL *session, const char *cfg[])
              * again: it can be discarded.
              */
             if (upd->type == WT_UPDATE_RESERVE) {
+                upd->orig_txnid = upd->txnid | 0x0500000000000000L;
                 upd->txnid = WT_TXN_ABORTED;
                 __wt_txn_op_free(session, op);
                 break;
@@ -1277,6 +1280,7 @@ __wt_txn_rollback(WT_SESSION_IMPL *session, const char *cfg[])
 
             if (!prepare) {
                 WT_ASSERT(session, upd->txnid == txn->id || upd->txnid == WT_TXN_ABORTED);
+                upd->orig_txnid = upd->txnid | 0x0600000000000000L;
                 upd->txnid = WT_TXN_ABORTED;
             } else {
                 /*
diff --git a/src/txn/txn_rollback_to_stable.c b/src/txn/txn_rollback_to_stable.c
index d3d9c2b4d..f7303b0e8 100644
--- a/src/txn/txn_rollback_to_stable.c
+++ b/src/txn/txn_rollback_to_stable.c
@@ -115,6 +115,7 @@ __txn_abort_newer_update(
                 upd == first_upd);
             first_upd = upd->next;
 
+            upd->orig_txnid = upd->txnid | 0x0700000000000000L;
             upd->txnid = WT_TXN_ABORTED;
             WT_STAT_CONN_INCR(session, txn_rollback_upd_aborted);
             upd->durable_ts = upd->start_ts = WT_TS_NONE;
diff --git a/test/format/format.h b/test/format/format.h
index 38755e475..6cf3e8690 100644
--- a/test/format/format.h
+++ b/test/format/format.h
@@ -279,6 +279,8 @@ typedef struct {
     void *vdata; /* If not a delete, the value */
     size_t vsize;
     size_t vmemsize;
+
+    struct timespec commit_time;
 } SNAP_OPS;
 
 typedef struct {
@@ -301,6 +303,7 @@ typedef struct {
 
     WT_SESSION *session; /* WiredTiger session */
     WT_CURSOR *cursor;   /* WiredTiger cursor */
+    struct timespec start_time;
 
     uint64_t keyno;     /* key */
     WT_ITEM *key, _key; /* key, value */
@@ -357,7 +360,7 @@ void snap_init(TINFO *, uint64_t, bool);
 void snap_repeat_single(WT_CURSOR *, TINFO *);
 int snap_repeat_txn(WT_CURSOR *, TINFO *);
 void snap_repeat_update(TINFO *, bool);
-void snap_track(TINFO *, thread_op);
+void snap_track(WT_CURSOR *, TINFO *, thread_op);
 WT_THREAD_RET timestamp(void *);
 void timestamp_once(void);
 void track(const char *, uint64_t, TINFO *);
diff --git a/test/format/ops.c b/test/format/ops.c
index 2b4ae05cc..94ca52cfd 100644
--- a/test/format/ops.c
+++ b/test/format/ops.c
@@ -465,6 +465,7 @@ commit_transaction(TINFO *tinfo, bool prepared)
         testutil_check(pthread_rwlock_unlock(&g.ts_lock));
     }
     testutil_check(session->commit_transaction(session, NULL));
+    __wt_epoch(NULL, &tinfo->snap_first->commit_time);
 
     /* Remember our oldest commit timestamp. */
     tinfo->commit_ts = ts;
@@ -562,7 +563,7 @@ prepare_transaction(TINFO *tinfo)
 #define SNAP_TRACK(tinfo, op)                                          \
     do {                                                               \
         if (intxn && !ckpt_handle && iso_config == ISOLATION_SNAPSHOT) \
-            snap_track(tinfo, op);                                     \
+            snap_track(cursor, tinfo, op);                             \
     } while (0)
 
 /*
diff --git a/test/format/snap.c b/test/format/snap.c
index b304faa73..d2de45bb1 100644
--- a/test/format/snap.c
+++ b/test/format/snap.c
@@ -35,21 +35,25 @@
 void
 snap_init(TINFO *tinfo, uint64_t read_ts, bool repeatable_reads)
 {
+
     ++tinfo->opid;
 
     tinfo->snap_first = tinfo->snap;
 
+    __wt_epoch(NULL, &tinfo->start_time);
     tinfo->read_ts = read_ts;
     tinfo->repeatable_reads = repeatable_reads;
     tinfo->repeatable_wrap = false;
 }
 
+static int snap_verify(WT_CURSOR *cursor, TINFO *tinfo, SNAP_OPS *snap);
+
 /*
  * snap_track --
  *     Add a single snapshot isolation returned value to the list.
  */
 void
-snap_track(TINFO *tinfo, thread_op op)
+snap_track(WT_CURSOR *cursor, TINFO *tinfo, thread_op op)
 {
     WT_ITEM *ip;
     SNAP_OPS *snap;
@@ -81,6 +85,11 @@ snap_track(TINFO *tinfo, thread_op op)
         memcpy(snap->vdata, ip->data, snap->vsize = ip->size);
     }
 
+    if (op == READ) {
+        __wt_yield();
+        snap_verify(cursor, tinfo, snap);
+    }
+
     /* Move to the next slot, wrap at the end of the circular buffer. */
     if (++tinfo->snap >= &tinfo->snap_list[WT_ELEMENTS(tinfo->snap_list)])
         tinfo->snap = tinfo->snap_list;
@@ -119,6 +128,52 @@ print_item_data(const char *tag, const uint8_t *data, size_t size)
     fprintf(stderr, "}\n");
 }
 
+/*
+ * snap_stop_all --
+ *     Stop all other threads. Set their quit flag.
+ */
+static void
+snap_stop_all()
+{
+    TINFO *tinfo;
+    uint32_t i;
+
+    for (i = 0; i < g.c_threads; ++i) {
+        tinfo = tinfo_list[i];
+        tinfo->quit = true;
+    }
+}
+
+/*
+ * snap_find_all --
+ *     Find any other threads that were committing at the same time we were.
+ */
+static int
+snap_find_all(TINFO *my_tinfo, SNAP_OPS *my_snap)
+{
+    SNAP_OPS *snap;
+    TINFO *tinfo;
+    uint32_t i, j;
+
+    if (my_snap->op != READ)
+        return (0);
+
+    for (i = 0; i < g.c_threads; ++i) {
+        tinfo = tinfo_list[i];
+        if (tinfo == my_tinfo)
+            continue;
+        for (j = 0; j < 512; ++j) {
+            snap = &tinfo->snap_list[j];
+            if (snap->keyno == my_snap->keyno)
+                fprintf(stderr, "KEY FOUND: tinfo[%" PRIu32 "] %p snap[%" PRIu32 "] %p\n", i, tinfo,
+                  j, snap);
+            if (WT_TIMECMP(tinfo->start_time, snap->commit_time) < 0)
+                fprintf(stderr, "CONCURRENT COMMIT: tinfo[%" PRIu32 "] %p snap[%" PRIu32 "] %p\n",
+                  i, tinfo, j, snap);
+        }
+    }
+}
+
 /*
  * snap_verify --
  *     Repeat a read and verify the contents.
@@ -238,6 +293,10 @@ snap_verify(WT_CURSOR *cursor, TINFO *tinfo, SNAP_OPS *snap)
      */
     fprintf(stderr, "\n%s: run FAILED\n", progname);
     set_core_off();
+    fprintf(stderr, "\n%s: run FAILED stopping threads\n", progname);
+    snap_stop_all();
+    fprintf(stderr, "\n%s: Searching for concurrent snapshot operations\n", progname);
+    snap_find_all(tinfo, snap);
 
     fprintf(stderr, "snapshot-isolation error: Dumping page to %s\n", g.home_pagedump);
     testutil_check(__wt_debug_cursor_page(cursor, g.home_pagedump));
