diff --git a/core/src/main/java/com/yahoo/ycsb/generator/AcknowledgedCounterGenerator.java b/core/src/main/java/com/yahoo/ycsb/generator/AcknowledgedCounterGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..443b47f5afa7063517fcbb9c4706ca79f50c0bf8
--- /dev/null
+++ b/core/src/main/java/com/yahoo/ycsb/generator/AcknowledgedCounterGenerator.java
@@ -0,0 +1,72 @@
+package com.yahoo.ycsb.generator;
+
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * A CounterGenerator that reports generated integers via lastInt()
+ * only after they have been acknowledged.
+ */
+public class AcknowledgedCounterGenerator extends CounterGenerator
+{
+	private static final int WINDOW_SIZE = 1000000;
+
+	private final ReentrantLock lock;
+	private final boolean[] window;
+	private volatile int limit;
+
+	/**
+	 * Create a counter that starts at countstart.
+	 */
+	public AcknowledgedCounterGenerator(int countstart)
+	{
+		super(countstart);
+		lock = new ReentrantLock();
+		window = new boolean[WINDOW_SIZE];
+		limit = countstart - 1;
+	}
+
+	/**
+	 * In this generator, the highest acknowledged counter value
+	 * (as opposed to the highest generated counter value).
+	 */
+	@Override
+	public int lastInt()
+	{
+		return limit;
+	}
+
+	/**
+	 * Make a generated counter value available via lastInt().
+	 */
+	public void acknowledge(int value)
+	{
+		if (value > limit + WINDOW_SIZE) {
+			throw new RuntimeException("Too many unacknowledged insertion keys.");
+		}
+
+		window[value % WINDOW_SIZE] = true;
+
+		if (lock.tryLock()) {
+			// move a contiguous sequence from the window
+			// over to the "limit" variable
+
+			try {
+				int index;
+
+				for (index = limit + 1; index <= value; ++index) {
+					int slot = index % WINDOW_SIZE;
+
+					if (!window[slot]) {
+						break;
+					}
+
+					window[slot] = false;
+				}
+
+				limit = index - 1;
+			} finally {
+				lock.unlock();
+			}
+		}
+	}
+}
diff --git a/core/src/main/java/com/yahoo/ycsb/workloads/CoreWorkload.java b/core/src/main/java/com/yahoo/ycsb/workloads/CoreWorkload.java
index b4a477b40e8371eca90a8da07b2a4b7aaae9ac59..ac625b74dda1395bad58e92dc2431135ce3a3e65 100644
--- a/core/src/main/java/com/yahoo/ycsb/workloads/CoreWorkload.java
+++ b/core/src/main/java/com/yahoo/ycsb/workloads/CoreWorkload.java
@@ -20,6 +20,7 @@ package com.yahoo.ycsb.workloads;
 import java.util.Properties;
 
 import com.yahoo.ycsb.*;
+import com.yahoo.ycsb.generator.AcknowledgedCounterGenerator;
 import com.yahoo.ycsb.generator.CounterGenerator;
 import com.yahoo.ycsb.generator.DiscreteGenerator;
 import com.yahoo.ycsb.generator.ExponentialGenerator;
@@ -299,7 +300,7 @@ public class CoreWorkload extends Workload
 
 	Generator fieldchooser;
 
-	CounterGenerator transactioninsertkeysequence;
+	AcknowledgedCounterGenerator transactioninsertkeysequence;
 	
 	IntegerGenerator scanlength;
 	
@@ -417,7 +418,7 @@ public class CoreWorkload extends Workload
 			operationchooser.addValue(readmodifywriteproportion,"READMODIFYWRITE");
 		}
 
-		transactioninsertkeysequence=new CounterGenerator(recordcount);
+		transactioninsertkeysequence=new AcknowledgedCounterGenerator(recordcount);
 		if (requestdistrib.compareTo("uniform")==0)
 		{
 			keychooser=new UniformIntegerGenerator(0,recordcount-1);
@@ -759,9 +760,13 @@ public class CoreWorkload extends Workload
 		//choose the next key
 		int keynum=transactioninsertkeysequence.nextInt();
 
-		String dbkey = buildKeyName(keynum);
+		try {
+			String dbkey = buildKeyName(keynum);
 
-		HashMap<String, ByteIterator> values = buildValues(dbkey);
-		db.insert(table,dbkey,values);
+			HashMap<String, ByteIterator> values = buildValues(dbkey);
+			db.insert(table,dbkey,values);
+		} finally {
+			transactioninsertkeysequence.acknowledge(keynum);
+		}
 	}
 }