diff --git a/gulpfile.helper.js b/gulpfile.helper.js
index ff9c2152b16a1c33cdeece0d6fa7a7a65ca16850..fd1ba8ede46f91561566c9e055d8d5145a80f451 100644
--- a/gulpfile.helper.js
+++ b/gulpfile.helper.js
@@ -145,7 +145,7 @@ module.exports = function (gulp, helperOptions) {
           'git pull',
           'cd ./dist/ && git add -A',
           'cd ./dist/ && git commit -am "Deploy <%= getVersion(file.path) %>" -n',
-          'cd ./dist/ && git push',
+          'cd ./dist/ && git push origin HEAD:dist',
           'cd ./dist/ && git tag -a v<%= getVersion(file.path) %> -m "Release <%= getVersion(file.path) %>"',
           'cd ./dist/ && git push origin --tags',
           'git commit -am "Release <%= getVersion(file.path) %>" -n',
diff --git a/src/Connectors/Test.js b/src/Connectors/Test.js
index f2ee9814321f04445ccf77f9b0442a7e1c0ccd94..9e798a5417acca66f101b3dc94a600f47ec8ba00 100644
--- a/src/Connectors/Test.js
+++ b/src/Connectors/Test.js
@@ -1,4 +1,4 @@
-/* global getRandom, wait, async */
+/* global getRandom, async */
 'use strict'
 
 module.exports = function (Y) {
@@ -22,29 +22,33 @@ module.exports = function (Y) {
           connector.userJoined(u.userId, 'master')
         }
       }
-    }
-  }
-  Y.utils.globalRoom = globalRoom
-
-  function flushOne () {
-    var bufs = []
-    for (var i in globalRoom.buffers) {
-      if (globalRoom.buffers[i].length > 0) {
-        bufs.push(i)
+    },
+    whenTransactionsFinished: function () {
+      var ps = []
+      for (var name in this.users) {
+        ps.push(this.users[name].y.db.whenTransactionsFinished())
+      }
+      return Promise.all(ps)
+    },
+    flushOne: function flushOne () {
+      var bufs = []
+      for (var i in globalRoom.buffers) {
+        if (globalRoom.buffers[i].length > 0) {
+          bufs.push(i)
+        }
+      }
+      if (bufs.length > 0) {
+        var userId = getRandom(bufs)
+        var m = globalRoom.buffers[userId].shift()
+        var user = globalRoom.users[userId]
+        user.receiveMessage(m[0], m[1])
+        return user.y.db.whenTransactionsFinished()
+      } else {
+        return false
       }
-    }
-    if (bufs.length > 0) {
-      var userId = getRandom(bufs)
-      var m = globalRoom.buffers[userId].shift()
-      var user = globalRoom.users[userId]
-      user.receiveMessage(m[0], m[1])
-      return true
-    } else {
-      return false
     }
   }
-
-  // setInterval(flushOne, 10)
+  Y.utils.globalRoom = globalRoom
 
   var userIdCounter = 0
 
@@ -91,17 +95,16 @@ module.exports = function (Y) {
         globalRoom.removeUser(this.userId)
         super.disconnect()
       }
-      return wait()
+      return this.y.db.whenTransactionsFinished()
     }
     flush () {
       var self = this
       return async(function * () {
-        yield wait()
         while (globalRoom.buffers[self.userId].length > 0) {
           var m = globalRoom.buffers[self.userId].shift()
           this.receiveMessage(m[0], m[1])
-          yield wait()
         }
+        yield self.whenTransactionsFinished()
       })
     }
     flushAll () {
@@ -109,29 +112,19 @@ module.exports = function (Y) {
         // flushes may result in more created operations,
         // flush until there is nothing more to flush
         function nextFlush () {
-          var c = flushOne()
+          var c = globalRoom.flushOne()
           if (c) {
-            while (flushOne()) {
+            while (globalRoom.flushOne()) {
               // nop
             }
-            wait().then(nextFlush)
+            globalRoom.whenTransactionsFinished().then(nextFlush)
           } else {
-            wait().then(function () {
-              resolve()
-            })
+            resolve()
           }
         }
-        // in the case that there are
-        // still actions that want to be performed
-        wait().then(nextFlush)
+        globalRoom.whenTransactionsFinished().then(nextFlush)
       })
     }
-    /*
-      Flushes an operation for some user..
-    */
-    flushOne () {
-      flushOne()
-    }
   }
 
   Y.Test = Test
diff --git a/src/Database.js b/src/Database.js
index 46f8f253a5903faa4aadc15dbc8ae577f093ebb8..e69778883f06f1449ff8dc1b80ed297423cdaccd 100644
--- a/src/Database.js
+++ b/src/Database.js
@@ -318,9 +318,23 @@ module.exports = function (Y) {
         }
       }
     }
+    whenTransactionsFinished () {
+      if (this.transactionInProgress) {
+        if (this.transactionsFinished == null) {
+          this.transactionsFinished = Promise.defer()
+        }
+        return this.transactionsFinished.promise
+      } else {
+        return Promise.resolve()
+      }
+    }
     getNextRequest () {
       if (this.waitingTransactions.length === 0) {
         this.transactionInProgress = false
+        if (this.transactionsFinished != null) {
+          this.transactionsFinished.resolve()
+          this.transactionsFinished = null
+        }
         return null
       } else {
         return this.waitingTransactions.shift()
diff --git a/src/SpecHelper.js b/src/SpecHelper.js
index 6cf30d8d92708a34b3b01a73c3aaaa92cd7b7a47..41f2363dbcce19a7a8611296878d76895aeb7521 100644
--- a/src/SpecHelper.js
+++ b/src/SpecHelper.js
@@ -7,6 +7,9 @@
 // When testing, you store everything on the global object. We call it g
 
 var Y = require('./y.js')
+require('../../y-memory/src/Memory.js')(Y)
+require('../../y-array/src/Array.js')(Y)
+require('../../y-indexeddb/src/IndexedDB.js')(Y)
 module.exports = Y
 
 var g
@@ -33,6 +36,8 @@ g.describeManyTimes = function describeManyTimes (times, name, f) {
   Wait for a specified amount of time (in ms). defaults to 5ms
 */
 function wait (t) {
+  throw new Error("waiting..")
+  console.log("waiting..", t)
   if (t == null) {
     t = 5
   }
@@ -45,13 +50,9 @@ function wait (t) {
 g.wait = wait
 
 g.databases = ['memory']
-require('../../y-memory/src/Memory.js')(Y)
 if (typeof window !== 'undefined') {
   g.databases.push('indexeddb')
-  require('../../y-indexeddb/src/IndexedDB.js')(Y)
 }
-require('../../y-array/src/Array.js')
-
 /*
   returns a random element of o.
   works on Object, and Array
@@ -86,10 +87,11 @@ function * applyTransactions (relAmount, numberOfTransactions, objects, users, t
     var r = Math.random()
     if (r >= 0.5) {
       // 50% chance to flush
-      users[0].connector.flushOne() // flushes for some user.. (not necessarily 0)
+      Y.utils.globalRoom.flushOne() // flushes for some user.. (not necessarily 0)
     } else if (r >= 0.05) {
       // 45% chance to create operation
       randomTransaction(getRandom(objects))
+      yield Y.utils.globalRoom.whenTransactionsFinished()
     } else {
       // 5% chance to disconnect/reconnect
       var u = getRandom(users)
@@ -99,18 +101,15 @@ function * applyTransactions (relAmount, numberOfTransactions, objects, users, t
         yield u.disconnect()
       }
     }
-    yield wait()
   }
 }
 
 g.applyRandomTransactionsAllRejoinNoGC = async(function * applyRandomTransactions (users, objects, transactions, numberOfTransactions) {
   yield* applyTransactions(1, numberOfTransactions, objects, users, transactions)
   yield users[0].connector.flushAll()
-  yield wait()
   for (var u in users) {
     yield users[u].reconnect()
   }
-  yield wait(100)
   yield users[0].connector.flushAll()
   yield g.garbageCollectAllUsers(users)
 })
@@ -119,26 +118,21 @@ g.applyRandomTransactionsWithGC = async(function * applyRandomTransactions (user
   yield* applyTransactions(1, numberOfTransactions, objects, users.slice(1), transactions)
   yield users[0].connector.flushAll()
   yield g.garbageCollectAllUsers(users)
-  yield wait(100)
   for (var u in users) {
     // TODO: here, we enforce that two users never sync at the same time with u[0]
     //       enforce that in the connector itself!
     yield users[u].reconnect()
   }
-  yield wait(100)
   yield users[0].connector.flushAll()
-  yield wait(100)
   yield g.garbageCollectAllUsers(users)
 })
 
 g.garbageCollectAllUsers = async(function * garbageCollectAllUsers (users) {
   // gc two times because of the two gc phases (really collect everything)
-  yield wait(100)
   for (var i in users) {
     yield users[i].db.garbageCollect()
     yield users[i].db.garbageCollect()
   }
-  yield wait(100)
 })
 
 g.compareAllUsers = async(function * compareAllUsers (users) {
@@ -165,7 +159,6 @@ g.compareAllUsers = async(function * compareAllUsers (users) {
     })
   }
   yield users[0].connector.flushAll()
-  yield wait()
   yield g.garbageCollectAllUsers(users)
 
   for (var uid = 0; uid < users.length; uid++) {
@@ -196,7 +189,6 @@ g.compareAllUsers = async(function * compareAllUsers (users) {
       }
     })
     // compare allDels tree
-    yield wait()
     if (s1 == null) {
       u.db.requestTransaction(function * () {
         yield* t1.call(this)
@@ -206,7 +198,6 @@ g.compareAllUsers = async(function * compareAllUsers (users) {
           db1.push(o)
         })
       })
-      yield wait()
     } else {
       // TODO: make requestTransaction return a promise..
       u.db.requestTransaction(function * () {
@@ -221,8 +212,8 @@ g.compareAllUsers = async(function * compareAllUsers (users) {
           expect(db1[count++]).toEqual(o)
         })
       })
-      yield wait()
     }
+    yield u.db.whenTransactionsFinished()
   }
 })