diff --git a/internal/sqladapter/testing/adapter.go.tpl b/internal/sqladapter/testing/adapter.go.tpl
index 96ed05a6a5857d5249f55b8a945b9f25455e32e4..748b03338d05fff788947b298f8d662757436aea 100644
--- a/internal/sqladapter/testing/adapter.go.tpl
+++ b/internal/sqladapter/testing/adapter.go.tpl
@@ -1078,6 +1078,28 @@ func TestDataTypes(t *testing.T) {
 	assert.Equal(t, testValues, item)
 }
 
+func TestBatchInsert(t *testing.T) {
+	sess := mustOpen()
+	defer sess.Close()
+
+	err := sess.Collection("artist").Truncate()
+	assert.NoError(t, err)
+
+	batch := sess.InsertInto("artist").Columns("name").NewBatch(5)
+
+	go func() {
+		for i := 0; i < 9; i++ {
+			batch.Values(fmt.Sprintf("artist-%d", i))
+		}
+		batch.Done()
+	}()
+
+	for q := range batch.Next() {
+		_, err = q.Exec()
+		assert.NoError(t, err)
+	}
+}
+
 func TestBuilder(t *testing.T) {
 	sess := mustOpen()
 	defer sess.Close()
diff --git a/lib/sqlbuilder/insert.go b/lib/sqlbuilder/insert.go
index 0124ff7f12e4cb0032f904d5747f92a3de9b6c20..f7259de4c4cd7289e218e3048a4bddbce65756e7 100644
--- a/lib/sqlbuilder/insert.go
+++ b/lib/sqlbuilder/insert.go
@@ -17,6 +17,16 @@ type inserter struct {
 	extra     string
 }
 
+func (qi *inserter) clone() *inserter {
+	clone := &inserter{}
+	*clone = *qi
+	return clone
+}
+
+func (qi *inserter) NewBatch(n int) *BatchInserter {
+	return &BatchInserter{inserter: qi.clone(), size: n}
+}
+
 func (qi *inserter) columnsToFragments(dst *[]exql.Fragment, columns []string) error {
 	l := len(columns)
 	f := make([]exql.Fragment, l)
diff --git a/lib/sqlbuilder/interfaces.go b/lib/sqlbuilder/interfaces.go
index b0c4382a109a809e4b56167871ba78401eda155c..dbef6a8db9bfa4203d13da0b36fe5bdc64153253 100644
--- a/lib/sqlbuilder/interfaces.go
+++ b/lib/sqlbuilder/interfaces.go
@@ -323,6 +323,11 @@ type Inserter interface {
 	// Inserter. This is only possible when using Returning().
 	Iterator() Iterator
 
+	// Batch provies a BatchInserter that can be used to insert many elements at
+	// once by issuing several calls to Values(). It accepts a size parameter
+	// which defines the batch size. If size is < 1, the batch size is set to 1.
+	NewBatch(size int) *BatchInserter
+
 	// Execer provides the Exec method.
 	Execer