diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index 8099d4dc6020e17920718e9fa756a51eb3bd7b5b..f20ea390fd82d1ef997f4682ea58d65de67082f1 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -281,6 +281,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
 		utils.BootnodesFlag,
 		utils.DataDirFlag,
 		utils.BlockchainVersionFlag,
+		utils.CacheFlag,
 		utils.JSpathFlag,
 		utils.ListenPortFlag,
 		utils.MaxPeersFlag,
@@ -492,7 +493,7 @@ func blockRecovery(ctx *cli.Context) {
 	cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
 	utils.CheckLegalese(cfg.DataDir)
 
-	blockDb, err := ethdb.NewLDBDatabase(filepath.Join(cfg.DataDir, "blockchain"))
+	blockDb, err := ethdb.NewLDBDatabase(filepath.Join(cfg.DataDir, "blockchain"), cfg.DatabaseCache)
 	if err != nil {
 		glog.Fatalln("could not open db:", err)
 	}
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 73bdb935a33e00ff2643b680e01fa51c5f54940f..68de67cde71f8c531e8f14e8bd19f1bcaa655e75 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -126,6 +126,11 @@ var (
 		Name:  "natspec",
 		Usage: "Enable NatSpec confirmation notice",
 	}
+	CacheFlag = cli.IntFlag{
+		Name:  "cache",
+		Usage: "Megabytes of memory allocated to internal caching",
+		Value: 0,
+	}
 
 	// miner settings
 	MinerThreadsFlag = cli.IntFlag{
@@ -384,6 +389,7 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
 		GenesisNonce:            ctx.GlobalInt(GenesisNonceFlag.Name),
 		GenesisFile:             ctx.GlobalString(GenesisFileFlag.Name),
 		BlockChainVersion:       ctx.GlobalInt(BlockchainVersionFlag.Name),
+		DatabaseCache:           ctx.GlobalInt(CacheFlag.Name),
 		SkipBcVersionCheck:      false,
 		NetworkId:               ctx.GlobalInt(NetworkIdFlag.Name),
 		LogFile:                 ctx.GlobalString(LogFileFlag.Name),
@@ -425,15 +431,17 @@ func SetupLogger(ctx *cli.Context) {
 
 // MakeChain creates a chain manager from set command line flags.
 func MakeChain(ctx *cli.Context) (chain *core.ChainManager, blockDB, stateDB, extraDB common.Database) {
-	dd := ctx.GlobalString(DataDirFlag.Name)
+	datadir := ctx.GlobalString(DataDirFlag.Name)
+	cache := ctx.GlobalInt(CacheFlag.Name)
+
 	var err error
-	if blockDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "blockchain")); err != nil {
+	if blockDB, err = ethdb.NewLDBDatabase(filepath.Join(datadir, "blockchain"), cache); err != nil {
 		Fatalf("Could not open database: %v", err)
 	}
-	if stateDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "state")); err != nil {
+	if stateDB, err = ethdb.NewLDBDatabase(filepath.Join(datadir, "state"), cache); err != nil {
 		Fatalf("Could not open database: %v", err)
 	}
-	if extraDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "extra")); err != nil {
+	if extraDB, err = ethdb.NewLDBDatabase(filepath.Join(datadir, "extra"), cache); err != nil {
 		Fatalf("Could not open database: %v", err)
 	}
 
diff --git a/core/bench_test.go b/core/bench_test.go
index 018d27d8dc5f7093a9011d920469b1777388d1a9..ec0474ad9f01eace3b2164d7651e8861e5abcf74 100644
--- a/core/bench_test.go
+++ b/core/bench_test.go
@@ -153,7 +153,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
 			b.Fatalf("cannot create temporary directory: %v", err)
 		}
 		defer os.RemoveAll(dir)
-		db, err = ethdb.NewLDBDatabase(dir)
+		db, err = ethdb.NewLDBDatabase(dir, 0)
 		if err != nil {
 			b.Fatalf("cannot create temporary database: %v", err)
 		}
diff --git a/eth/backend.go b/eth/backend.go
index e7250c019f1153a107e9d941edcc2cb5a54e2fe8..4906f78efc7cde6c01c1f06ec8a59249243bd38e 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -80,6 +80,7 @@ type Config struct {
 
 	BlockChainVersion  int
 	SkipBcVersionCheck bool // e.g. blockchain export
+	DatabaseCache      int
 
 	DataDir   string
 	LogFile   string
@@ -261,7 +262,7 @@ func New(config *Config) (*Ethereum, error) {
 
 	newdb := config.NewDB
 	if newdb == nil {
-		newdb = func(path string) (common.Database, error) { return ethdb.NewLDBDatabase(path) }
+		newdb = func(path string) (common.Database, error) { return ethdb.NewLDBDatabase(path, config.DatabaseCache) }
 	}
 	blockDb, err := newdb(filepath.Join(config.DataDir, "blockchain"))
 	if err != nil {
diff --git a/ethdb/database.go b/ethdb/database.go
index c75136a1b9ac9df08a9651c6fd0e8b509cf89e2c..38e454c00cfea7e2f48eda7c6a5144d227012be8 100644
--- a/ethdb/database.go
+++ b/ethdb/database.go
@@ -17,6 +17,7 @@
 package ethdb
 
 import (
+	"path/filepath"
 	"strconv"
 	"strings"
 	"sync"
@@ -36,6 +37,14 @@ import (
 
 var OpenFileLimit = 64
 
+// cacheRatio specifies how the total alloted cache is distributed between the
+// various system databases.
+var cacheRatio = map[string]float64{
+	"blockchain": 1.0 / 13.0,
+	"extra":      2.0 / 13.0,
+	"state":      10.0 / 13.0,
+}
+
 type LDBDatabase struct {
 	fn string      // filename for reporting
 	db *leveldb.DB // LevelDB instance
@@ -57,14 +66,24 @@ type LDBDatabase struct {
 // NewLDBDatabase returns a LevelDB wrapped object. LDBDatabase does not persist data by
 // it self but requires a background poller which syncs every X. `Flush` should be called
 // when data needs to be stored and written to disk.
-func NewLDBDatabase(file string) (*LDBDatabase, error) {
-	// Open the db
-	db, err := leveldb.OpenFile(file, &opt.Options{OpenFilesCacheCapacity: OpenFileLimit})
-	// check for corruption and attempt to recover
-	if _, iscorrupted := err.(*errors.ErrCorrupted); iscorrupted {
+func NewLDBDatabase(file string, cache int) (*LDBDatabase, error) {
+	// Calculate the cache allowance for this particular database
+	cache = int(float64(cache) * cacheRatio[filepath.Base(file)])
+	if cache < 16 {
+		cache = 16
+	}
+	glog.V(logger.Info).Infof("Alloted %dMB cache to %s", cache, file)
+
+	// Open the db and recover any potential corruptions
+	db, err := leveldb.OpenFile(file, &opt.Options{
+		OpenFilesCacheCapacity: OpenFileLimit,
+		BlockCacheCapacity:     cache / 2 * opt.MiB,
+		WriteBuffer:            cache / 4 * opt.MiB, // Two of these are used internally
+	})
+	if _, corrupted := err.(*errors.ErrCorrupted); corrupted {
 		db, err = leveldb.RecoverFile(file, nil)
 	}
-	// (re) check for errors and abort if opening of the db failed
+	// (Re)check for errors and abort if opening of the db failed
 	if err != nil {
 		return nil, err
 	}
diff --git a/ethdb/database_test.go b/ethdb/database_test.go
index 29292d01675c86455c34c137ad029ac86b2f0cac..41947a6981315a7d28bdcbce9db5ebf02fe9b789 100644
--- a/ethdb/database_test.go
+++ b/ethdb/database_test.go
@@ -28,8 +28,7 @@ func newDb() *LDBDatabase {
 	if common.FileExist(file) {
 		os.RemoveAll(file)
 	}
-
-	db, _ := NewLDBDatabase(file)
+	db, _ := NewLDBDatabase(file, 0)
 
 	return db
 }