Repository: bitcoin/bitcoin (language: cpp)

Issue:
Raise maximum -dbcache setting
### Please describe the feature you'd like to see added.

`nMaxDbCache` was set to 16 GB back in 2015:  https://github.com/bitcoin/bitcoin/commit/b3ed4236beb7f68e1720ceb3da15e0c3682ef629#diff-d102b6032635ce90158c1e6e614f03b50e4449aa46ce23370da5387a658342fd

The UTXO set has been growing significantly over the past few months so we should probably raise it.

### Is your feature related to a problem, if so please describe it.

Doing IBD without flushing dbcache is faster. That said, I'm not sure how much one single flush matters.

### Describe the solution you'd like

Make `nMaxDbCache` bigger.

### Describe any alternatives you've considered

_No response_

### Please leave any additional context

Much growth recently:
https://statoshi.info/d/000000009/unspent-transaction-output-set?orgId=1&from=now%2Fy&to=now&refresh=5s&viewPanel=8


Discussion / hints:
cc @sipa 
There is some related discussion and testing in https://github.com/bitcoin/bitcoin/pull/6102 containing the commit you linked to and more recently in https://github.com/bitcoin/bitcoin/pull/25325.
Would the eBPF USDT tracepoints for the UTXO cache be of use here as a way to measure the overall impact of these flush operations during an IBD or reindex operation?

https://github.com/bitcoin/bitcoin/tree/master/contrib/tracing#log_utxocache_flushpy 
@Sjors When doing a full IBD from genesis with dbcache set to 16 GiB, is the limit ever reached (or gotten close to)? If not, it's probably unnecessary to raise it.


@sipa I ran an IBD as part of testing #27596. Since I did a restart after the cache initially hit 1 GB, the data is not accurate, but the cache reached 13,334 MiB at block at block 798,000. A month earlier at 794,000 the log shows it as 12,766 MiB. So the memory footprint is growing ~7 GB per year (and that's not even the worst month, see [chart I linked to above](https://statoshi.info/d/000000009/unspent-transaction-output-set?orgId=1&from=now%2Fy&to=now&refresh=5s&viewPanel=8)).
I am re running an -reindex=1 with tracepoints watching for flushes.

Here is my last log entry for cache size height 800673 size 14,045 MiB

```2023-08-11T12:56:23Z UpdateTip: new best=00000000000000000002b6e22bae3b1f28339b6275c02ec9cbb6f19ffd9c7e9c height=800673 version=0x3017a000 log2_work=94.326952 tx=871155372 date='2023-07-28T20:42:50Z' progress=0.995044 cache=14045.6MiB(115054304txo)```

Ran Again
```2023-08-16T15:41:07Z UpdateTip: new best=000000000000000000000ff0f3d17f4d92a0534cb63ba8e7293d21ea09932997 height=803380 version=0x20006000 log2_work=94.361871 tx=879733788 date='2023-08-16T01:52:09Z' progress=0.999792 cache=14590.0MiB(119818570txo)```
Seems reasonable to increase it to 32 GB in that case. I'm slightly worried about people setting it to the max "because they can, and higher is better" and then getting hit with an unexpectedly slow flush time at the end, but if we're close to hitting the maximum, then it's clearly not crazy to want to set it higher.
Opened a PR #28358 to ~double~ quadruple it.

Fix patch:
diff --git a/doc/release-notes-28358.md b/doc/release-notes-28358.md
new file mode 100644
index 0000000000000..336aaa59ed871
--- /dev/null
+++ b/doc/release-notes-28358.md
@@ -0,0 +1,6 @@
+Updated settings
+------
+
+- The maximum allowed value for the `-dbcache` configuration option has been
+  dropped due to recent UTXO set growth. Note that before this change, large `-dbcache`
+  values were automatically reduced to 16 GiB (1 GiB on 32 bit systems). (#28358)
diff --git a/src/init.cpp b/src/init.cpp
index 0aac2ac65f8c0..05f53aa1fa1b2 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -474,7 +474,7 @@ void SetupServerArgs(ArgsManager& argsman)
     argsman.AddArg("-conf=<file>", strprintf("Specify path to read-only configuration file. Relative paths will be prefixed by datadir location (only useable from command line, not configuration file) (default: %s)", BITCOIN_CONF_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
     argsman.AddArg("-datadir=<dir>", "Specify data directory", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
     argsman.AddArg("-dbbatchsize", strprintf("Maximum database write batch size in bytes (default: %u)", nDefaultDbBatchSize), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::OPTIONS);
-    argsman.AddArg("-dbcache=<n>", strprintf("Maximum database cache size <n> MiB (%d to %d, default: %d). In addition, unused mempool memory is shared for this cache (see -maxmempool).", nMinDbCache, nMaxDbCache, nDefaultDbCache), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
+    argsman.AddArg("-dbcache=<n>", strprintf("Maximum database cache size <n> MiB (minimum %d, default: %d). Make sure you have enough RAM. In addition, unused memory allocated to the mempool is shared with this cache (see -maxmempool).", nMinDbCache, nDefaultDbCache), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
     argsman.AddArg("-includeconf=<file>", "Specify additional configuration file, relative to the -datadir path (only useable from configuration file, not command line)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
     argsman.AddArg("-allowignoredconf", strprintf("For backwards compatibility, treat an unused %s file in the datadir as a warning, not an error.", BITCOIN_CONF_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
     argsman.AddArg("-loadblock=<file>", "Imports blocks from external file on startup", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
diff --git a/src/node/caches.cpp b/src/node/caches.cpp
index 7403f7ddeaad4..dc4d98f592a2a 100644
--- a/src/node/caches.cpp
+++ b/src/node/caches.cpp
@@ -13,7 +13,6 @@ CacheSizes CalculateCacheSizes(const ArgsManager& args, size_t n_indexes)
 {
     int64_t nTotalCache = (args.GetIntArg("-dbcache", nDefaultDbCache) << 20);
     nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache
-    nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greater than nMaxDbcache
     CacheSizes sizes;
     sizes.block_tree_db = std::min(nTotalCache / 8, nMaxBlockDBCache << 20);
     nTotalCache -= sizes.block_tree_db;
diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui
index 99fb238772342..1ce23c72bb640 100644
--- a/src/qt/forms/optionsdialog.ui
+++ b/src/qt/forms/optionsdialog.ui
@@ -105,7 +105,7 @@
          <item>
           <widget class="QLabel" name="databaseCacheLabel">
            <property name="toolTip">
-            <string extracomment="Tooltip text for Options window setting that sets the size of the database cache. Explains the corresponding effects of increasing/decreasing this value.">Maximum database cache size. A larger cache can contribute to faster sync, after which the benefit is less pronounced for most use cases. Lowering the cache size will reduce memory usage. Unused mempool memory is shared for this cache.</string>
+            <string extracomment="Tooltip text for Options window setting that sets the size of the database cache. Explains the corresponding effects of increasing/decreasing this value.">Maximum database cache size. Make sure you have enough RAM. A larger cache can contribute to faster sync, after which the benefit is less pronounced for most use cases. Lowering the cache size will reduce memory usage. Unused mempool memory is shared for this cache.</string>
            </property>
            <property name="text">
             <string>Size of &amp;database cache</string>
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index ee53a59bb5c82..4df6dce953bbf 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -93,8 +93,7 @@ OptionsDialog::OptionsDialog(QWidget* parent, bool enableWallet)
     ui->setupUi(this);
 
     /* Main elements init */
-    ui->databaseCache->setMinimum(nMinDbCache);
-    ui->databaseCache->setMaximum(nMaxDbCache);
+    ui->databaseCache->setRange(nMinDbCache, std::numeric_limits<int>::max());
     ui->threadsScriptVerif->setMinimum(-GetNumCores());
     ui->threadsScriptVerif->setMaximum(MAX_SCRIPTCHECK_THREADS);
     ui->pruneWarning->setVisible(false);
diff --git a/src/txdb.h b/src/txdb.h
index c9af0a091ec68..1966991ceb2d6 100644
--- a/src/txdb.h
+++ b/src/txdb.h
@@ -25,8 +25,6 @@ class uint256;
 static const int64_t nDefaultDbCache = 450;
 //! -dbbatchsize default (bytes)
 static const int64_t nDefaultDbBatchSize = 16 << 20;
-//! max. -dbcache (MiB)
-static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 16384 : 1024;
 //! min. -dbcache (MiB)
 static const int64_t nMinDbCache = 4;
 //! Max memory allocated to block tree DB specific cache, if no -txindex (MiB)


Test patch: