diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index a6af14006c99fd21090141c4d2d9a48350e9adad..1f9ab90e251eea18497352d0051adb9f395f7043 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -43,6 +43,10 @@ import (
 	"github.com/ledgerwatch/turbo-geth/log"
 	"github.com/ledgerwatch/turbo-geth/metrics"
 	"github.com/ledgerwatch/turbo-geth/node"
+
+	"net/http"
+	//nolint:gosec
+	_ "net/http/pprof"
 )
 
 const (
@@ -260,6 +264,9 @@ func init() {
 }
 
 func main() {
+	go func() {
+		log.Info("HTTP", "error", http.ListenAndServe("localhost:6060", nil))
+	}()
 	if err := app.Run(os.Args); err != nil {
 		fmt.Fprintln(os.Stderr, err)
 		os.Exit(1)
diff --git a/core/blockchain.go b/core/blockchain.go
index 5aaf75081ebe70e5ebfcb50fbca3c600aaf3bf1f..d6ca2d2eaf855e1ddd69f9f98c470ed7abb8cfc5 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -1924,7 +1924,7 @@ func (st *insertStats) report(chain []*types.Block, index int, batch ethdb.DbWit
 		context := []interface{}{
 			"blocks", st.processed, "txs", txs, "mgas", float64(st.usedGas) / 1000000,
 			"elapsed", common.PrettyDuration(elapsed), "mgasps", float64(st.usedGas) * 1000 / float64(elapsed),
-			"number", end.Number(), "hash", end.Hash(), "batch", batch.BatchSize(),
+			"number", end.Number(), "hash", end.Hash(), "batch", common.StorageSize(batch.BatchSize()),
 		}
 		if timestamp := time.Unix(int64(end.Time()), 0); time.Since(timestamp) > time.Minute {
 			context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...)
diff --git a/core/state/db_state_reader.go b/core/state/db_state_reader.go
index c2a5b9b297c85aaa79b42f6334b8b0bfae845753..3e0c9e6189f6153e50ad32cbb30c7d39a6221c95 100644
--- a/core/state/db_state_reader.go
+++ b/core/state/db_state_reader.go
@@ -68,7 +68,7 @@ func (dbr *DbStateReader) ReadAccountData(address common.Address) (*accounts.Acc
 		return nil, nil
 	}
 	if dbr.accountCache != nil {
-		dbr.accountCache.Add(address, &a)
+		dbr.accountCache.Add(address, a.SelfCopy())
 	}
 	return &a, nil
 }
@@ -118,9 +118,12 @@ func (dbr *DbStateReader) ReadAccountCode(address common.Address, codeHash commo
 		}
 	}
 	code, err = dbr.db.Get(dbutils.CodeBucket, codeHash[:])
-	if dbr.codeCache != nil {
+	if dbr.codeCache != nil && len(code) <= 1024 {
 		dbr.codeCache.Add(address, code)
 	}
+	if dbr.codeSizeCache != nil {
+		dbr.codeSizeCache.Add(address, len(code))
+	}
 	return code, err
 }
 
diff --git a/core/state/db_state_writer.go b/core/state/db_state_writer.go
index 9b862b5cdb59cf62ae938e7e340b0adb51a96304..0050698e28ab9e3995a70b13bf27fd0651eda1a2 100644
--- a/core/state/db_state_writer.go
+++ b/core/state/db_state_writer.go
@@ -88,7 +88,7 @@ func (dsw *DbStateWriter) UpdateAccountData(ctx context.Context, address common.
 		return err
 	}
 	if dsw.accountCache != nil {
-		dsw.accountCache.Add(address, account)
+		dsw.accountCache.Add(address, account.SelfCopy())
 	}
 	return nil
 }
@@ -129,7 +129,7 @@ func (dsw *DbStateWriter) UpdateAccountCode(address common.Address, incarnation
 	if err := dsw.stateDb.Put(dbutils.ContractCodeBucket, dbutils.GenerateStoragePrefix(addrHash[:], incarnation), codeHash[:]); err != nil {
 		return err
 	}
-	if dsw.codeCache != nil {
+	if dsw.codeCache != nil && len(code) <= 1024 {
 		dsw.codeCache.Add(address, code)
 	}
 	if dsw.codeSizeCache != nil {
diff --git a/eth/downloader/stagedsync_stage_execute.go b/eth/downloader/stagedsync_stage_execute.go
index 765f11d425907b3eadc9e8ab874807906a6ef031..6961077fb8b0919fae7f93eca86e321232cd5cff 100644
--- a/eth/downloader/stagedsync_stage_execute.go
+++ b/eth/downloader/stagedsync_stage_execute.go
@@ -28,13 +28,15 @@ type progressLogger struct {
 	timer    *time.Ticker
 	quit     chan struct{}
 	interval int
+	batch    ethdb.DbWithPendingMutations
 }
 
-func NewProgressLogger(intervalInSeconds int) *progressLogger {
+func NewProgressLogger(intervalInSeconds int, batch ethdb.DbWithPendingMutations) *progressLogger {
 	return &progressLogger{
 		timer:    time.NewTicker(time.Duration(intervalInSeconds) * time.Second),
 		quit:     make(chan struct{}),
 		interval: intervalInSeconds,
+		batch:    batch,
 	}
 }
 
@@ -46,7 +48,7 @@ func (l *progressLogger) Start(numberRef *uint64) {
 			speed := float64(now-prev) / float64(l.interval)
 			var m runtime.MemStats
 			runtime.ReadMemStats(&m)
-			log.Info("Executed blocks:", "currentBlock", now, "speed (blk/second)", speed,
+			log.Info("Executed blocks:", "currentBlock", now, "speed (blk/second)", speed, "state batch", common.StorageSize(l.batch.BatchSize()),
 				"alloc", int(m.Alloc/1024), "sys", int(m.Sys/1024), "numGC", int(m.NumGC))
 			prev = now
 		}
@@ -67,8 +69,8 @@ func (l *progressLogger) Stop() {
 	close(l.quit)
 }
 
-const StateBatchSize = 1000000
-const ChangeBatchSize = 1000
+const StateBatchSize = 50 * 1024 * 1024 // 50 Mb
+const ChangeBatchSize = 1024 * 2014     // 1 Mb
 
 func spawnExecuteBlocksStage(stateDB ethdb.Database, blockchain BlockChain) (uint64, error) {
 	lastProcessedBlockNumber, err := GetStageProgress(stateDB, Execution)
@@ -94,7 +96,7 @@ func spawnExecuteBlocksStage(stateDB ethdb.Database, blockchain BlockChain) (uin
 	stateBatch := stateDB.NewBatch()
 	changeBatch := stateDB.NewBatch()
 
-	progressLogger := NewProgressLogger(logInterval)
+	progressLogger := NewProgressLogger(logInterval, stateBatch)
 	progressLogger.Start(&nextBlockNumber)
 	defer progressLogger.Stop()
 
diff --git a/ethdb/bolt_db.go b/ethdb/bolt_db.go
index 2a5f75d7566a5f3186b175e9245f616e1073f3ea..816a34433f19f4ff870c738466f518628b37bf06 100644
--- a/ethdb/bolt_db.go
+++ b/ethdb/bolt_db.go
@@ -725,7 +725,7 @@ func (db *BoltDatabase) NewBatch() DbWithPendingMutations {
 
 // IdealBatchSize defines the size of the data batches should ideally add in one write.
 func (db *BoltDatabase) IdealBatchSize() int {
-	return 100 * 1024
+	return 50 * 1024 * 1024 // 50 Mb
 }
 
 // [TURBO-GETH] Freezer support (not implemented yet)
diff --git a/ethdb/mutation.go b/ethdb/mutation.go
index c5887c8f2fee7af34eb7c47ad208955792d898c8..14f947ad72f32c47db92dbc228b0675f8ca61506 100644
--- a/ethdb/mutation.go
+++ b/ethdb/mutation.go
@@ -11,7 +11,7 @@ import (
 )
 
 type mutation struct {
-	puts puts // Map buckets to map[key]value
+	puts *puts // Map buckets to map[key]value
 	mu   sync.RWMutex
 	db   Database
 }
diff --git a/ethdb/mutation_puts.go b/ethdb/mutation_puts.go
index 83122af419981806ffe47b66e0c50a124ad17300..5413b10133f58eadbab8b8749a4e5ebf5ead56f3 100644
--- a/ethdb/mutation_puts.go
+++ b/ethdb/mutation_puts.go
@@ -1,29 +1,35 @@
 package ethdb
 
-import (
-)
-
 type puts struct {
-	mp       map[string]putsBucket //map[bucket]putsBucket
+	mp   map[string]putsBucket //map[bucket]putsBucket
+	size int
 }
 
-func newPuts() puts {
-	return puts{
-		mp:       make(map[string]putsBucket),
+func newPuts() *puts {
+	return &puts{
+		mp:   make(map[string]putsBucket),
+		size: 0,
 	}
 }
 
-func (p puts) set(bucket, key, value []byte) {
+func (p *puts) set(bucket, key, value []byte) {
 	var bucketPuts putsBucket
 	var ok bool
 	if bucketPuts, ok = p.mp[string(bucket)]; !ok {
 		bucketPuts = make(putsBucket)
 		p.mp[string(bucket)] = bucketPuts
 	}
+	skey := string(key)
+	if oldVal, ok := bucketPuts[skey]; ok {
+		p.size -= len(oldVal)
+	} else {
+		p.size += len(skey) + 32 // Add fixed overhead per key
+	}
 	bucketPuts[string(key)] = value
+	p.size += len(value)
 }
 
-func (p puts) get(bucket, key []byte) ([]byte, bool) {
+func (p *puts) get(bucket, key []byte) ([]byte, bool) {
 	var bucketPuts putsBucket
 	var ok bool
 	if bucketPuts, ok = p.mp[string(bucket)]; !ok {
@@ -32,16 +38,12 @@ func (p puts) get(bucket, key []byte) ([]byte, bool) {
 	return bucketPuts.Get(key)
 }
 
-func (p puts) Delete(bucket, key []byte) {
+func (p *puts) Delete(bucket, key []byte) {
 	p.set(bucket, key, nil)
 }
 
-func (p puts) Size() int {
-	var size int
-	for _, put := range p.mp {
-		size += len(put)
-	}
-	return size
+func (p *puts) Size() int {
+	return p.size
 }
 
 type putsBucket map[string][]byte //map[key]value
@@ -71,4 +73,3 @@ func (pb putsBucket) GetStr(key string) ([]byte, bool) {
 
 	return value, true
 }
-