dgraph-io/badger · error

ErrTxnTooBig

ErrTxnTooBig

Error message

Txn is too big to fit into one request

What it means

ErrTxnTooBig is returned when too many writes are fit into a single transaction, exceeding Badger's per-transaction entry-count/size budget (derived from opt.maxBatchCount/maxBatchSize). The pending transaction refuses further mutations so the caller can commit and start a new one.

Source

Thrown at errors.go:27

	stderrors "errors"
	"math"
)

const (
	// ValueThresholdLimit is the maximum permissible value of opt.ValueThreshold.
	ValueThresholdLimit = math.MaxUint16 - 16 + 1
)

var (
	// ErrValueLogSize is returned when opt.ValueLogFileSize option is not within the valid
	// range.
	ErrValueLogSize = stderrors.New("Invalid ValueLogFileSize, must be in range [1MB, 2GB)")

	// ErrKeyNotFound is returned when key isn't found on a txn.Get.
	ErrKeyNotFound = stderrors.New("Key not found")

	// ErrTxnTooBig is returned if too many writes are fit into a single transaction.
	ErrTxnTooBig = stderrors.New("Txn is too big to fit into one request")

	// ErrConflict is returned when a transaction conflicts with another transaction. This can
	// happen if the read rows had been updated concurrently by another transaction.
	ErrConflict = stderrors.New("Transaction Conflict. Please retry")

	// ErrReadOnlyTxn is returned if an update function is called on a read-only transaction.
	ErrReadOnlyTxn = stderrors.New("No sets or deletes are allowed in a read-only transaction")

	// ErrDiscardedTxn is returned if a previously discarded transaction is reused.
	ErrDiscardedTxn = stderrors.New("This transaction has been discarded. Create a new one")

	// ErrEmptyKey is returned if an empty key is passed on an update function.
	ErrEmptyKey = stderrors.New("Key cannot be empty")

	// ErrInvalidKey is returned if the key has a special !badger! prefix,
	// reserved for internal usage.
	ErrInvalidKey = stderrors.New("Key is using a reserved !badger! prefix")

View on GitHub (pinned to 2a001d466f)

Solutions

  1. For WriteBatch, call wb.Flush() when you get ErrTxnTooBig, then continue adding entries
  2. For plain txns, commit and create a new transaction periodically in write loops
  3. Reduce entries-per-transaction or value sizes; chunk the workload
  4. Use db.WriteBatch or the Stream framework for bulk loads (handles batching)

Example fix

// before
err := db.Update(func(txn *Txn) error {
    for _, e := range millions {
        if err := txn.SetEntry(e); err != nil { return err } // ErrTxnTooBig
    }
    return nil
})
// after
wb := db.NewWriteBatch()
for _, e := range millions {
    if err := wb.SetEntry(e); err != nil {
        if err == badger.ErrTxnTooBig {
            if err := wb.Flush(); err != nil { return err }
            if err := wb.SetEntry(e); err != nil { return err }
        } else { return err }
    }
}
return wb.Flush()
Defensive patterns

Strategy: validation

Validate before calling

// before each write, or on error, rotate the batch
if err := txn.SetEntry(e); err == badger.ErrTxnTooBig {
    _ = txn.Commit()
    txn = db.NewTransaction(true)
    err = txn.SetEntry(e)
}

Try / catch

if err := txn.SetEntry(e); err != nil {
    if errors.Is(err, badger.ErrTxnTooBig) {
        return rotateAndRetry(err)
    }
    return err
}

Prevention

When it happens

Trigger: Txn.SetEntry or Txn.Delete after the pending batch exceeds its size budget; WriteBatch.handleEntry (batch.go:138) and WriteBatch.Delete (batch.go:178) when wb.txn.SetEntry/Delete returns ErrTxnTooBig; bulk imports inside one Update().

Common situations: Bulk-loading millions of rows in a single transaction, writing many large values, long-running loops that never commit, assuming transactions are unbounded.

Related errors


AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05). Data as JSON: /api/errors/e9af10bc229a24cc. Report an issue: GitHub.