feat: Make MonitorUpdatingPersister change persist type based on size - #3834

Closed
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type
Closed

feat: Make MonitorUpdatingPersister change persist type based on size#3834
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type

Conversation

@Prabhat1308

Copy link
Copy Markdown
Contributor

fixes#3770

  • Skips full persistence when ChannelMonitor is smaller than a pre-determined size.
  • Adds a field minimum_monitor_size_for_updates to specify the minimum size for full persistence to be activated
  • Adds new_with_default_threshold function to setup MonitorUpdatingPersister with a default minimum_monitor_size_for_updates value

@ldk-reviews-bot

ldk-reviews-bot commented Jun 7, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnull
tnull requested review from tnull and removed request for joostjagerJune 9, 2025 07:24
/// For small channel monitors (below `minimum_monitor_size_for_updates` bytes when serialized),
/// this persister will always write the full monitor instead of individual updates. This avoids
/// the overhead of managing update files and later compaction for tiny monitors that don't benefit
/// from differential updates.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is still not clear to me how much the gain is of this in practice. Also worried that disabling the incremental path initially allow certain bugs to linger for longer, just because the path isn't hit as much, or rarely.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good, but can we add some test coverage for the new behavior?

Additionally, benchmarks would indeed very helpful to evaluate what a reasonable threshold value would be.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from ac6966e to c6ad41bCompareJune 11, 2025 17:52

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rewrite your commit history so that it's clear what are feature and fixup commits. Each commit message should have a clear headline followed by some paragraph(s) describing the change, where it happened, and why it was necessary. For guidance, please take a look at https://cbea.ms/git-commit/

Comment threadlightning/src/util/persist.rs Outdated
Introduces an optimization to the MonitorUpdatingPersister to
avoid writing differential updates for small channel monitors.
When a channel monitor is smaller than a configurable threshold
, the persister will now write the full monitor instead of an update.
This avoids the I/O overhead of creating and managing many small update
files for monitors that don't benefit significantly from differential updates.
Adds unit test for introduced size based optimisation. Also updates
the old unit test to use a threshold value and use constructors to
increase test coverage
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 357ce4b to b313e39CompareJune 12, 2025 09:54
@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

I have created a minimal benchmarking setup here for this.
https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm not sure we can conclude all that much from a local-filesystem benchmark, sadly. We have several users (and hopefully more soon with ldk-node) who use the MonitorUpdatingPersister with remote storage, where costs can be very different from local (eg IP packet size bound). I'd say we use a threshold of 8192 for now and call it a day.

@tnull

Copy link
Copy Markdown
Contributor

I have created a minimal benchmarking setup here for this. https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger. Maybe @TheBlueMatt can provide some realistic monitor sizes here?

I'm asking because I suspect the results may stem from a latency vs. throughput trade-off, and under certain circumstances one might dominate over the other. The filesystem store for example likely (especially assuming that most file systems by now have 4kb block size) does not incur that much more latency when reading/writing 'larger' monitors (as 8kb is still tiny and the syscall / IO latency likely the dominant factor), while persistence to a remote server would see much slower write speeds and hence higher latency when (re-)persisting full monitors.

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Maybe @TheBlueMatt can provide some realistic monitor sizes here?

Yea, so 8KiB is a reasonable "channel that got opened and has only done a handful of HTLC operations in its history" threshold (tho is maybe even a bit too small for a more active mobile wallet). On my routing node the largest monitor is ~73MiB, I imagine c= has some that get into the hundreds of MiB.

@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger.

My assumptions here were to test the crossover point to select what was the optimal value of the threshold . Since the talks in the issue for threshold were in kBs , I assumed them to be in the same range and didn't go as far as to check the monitors in MB range and the results I was getting was becoming worse as I was moving towards bigger sizes which also made me not go higher. So the comments to monitor sizes in benchmark are not of much significance as they were relative to 4kB monitor size.

changes the threshold value to 8192 bytes as suggested in the PR comments
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 41c5253 to 9b4508bCompareJune 16, 2025 17:09
Comment threadlightning/src/util/persist.rs
@domZippilli

Copy link
Copy Markdown
Contributor

Left some thoughts on the issue, since my thoughts aren't about this implementation but more the feature itself. But posting here since this is where the recent action is. 🙇

@yuvicc

Copy link
Copy Markdown

Concept ACK

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current changes look good to me, but I'll defer ACKing to after the discussion on whether we want this change afterall has concluded.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
/// monitors. Set to 0 to always use update-based persistence regardless of size.
///
/// For other parameters, see [`MonitorUpdatingPersister::new`].
pub fn new_with_monitor_size_threshold(

@domZippillidomZippilliJun 30, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if, instead of a "with" constructor, it would be nicer/better to either add this to the default constructor, or use a config struct, or write a builder.

It's not a problem here, but I wonder if we'll think of another tunable for MUP and then there will be a third constructor, and so on.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have for now added this in the default constructor , since there is only 1 parameter that was affected . If more such tunables are added in the future , I would lean towards the config approach

changes the code to have a proper constant value than a unnamed hardcoded constant . Removes the extra constructor added and adjust the min_monitor_size_for_updates_bytes variable in the constructor
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make MonitorUpdatingPersister change persist type based on size

7 participants

@Prabhat1308@ldk-reviews-bot@TheBlueMatt@tnull@domZippilli@yuvicc@joostjager
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: Make MonitorUpdatingPersister change persist type based on size - #3834

Closed
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type
Closed

feat: Make MonitorUpdatingPersister change persist type based on size#3834
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type

Conversation

@Prabhat1308

Copy link
Copy Markdown
Contributor

fixes#3770

  • Skips full persistence when ChannelMonitor is smaller than a pre-determined size.
  • Adds a field minimum_monitor_size_for_updates to specify the minimum size for full persistence to be activated
  • Adds new_with_default_threshold function to setup MonitorUpdatingPersister with a default minimum_monitor_size_for_updates value

@ldk-reviews-bot

ldk-reviews-bot commented Jun 7, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnull
tnull requested review from tnull and removed request for joostjagerJune 9, 2025 07:24
/// For small channel monitors (below `minimum_monitor_size_for_updates` bytes when serialized),
/// this persister will always write the full monitor instead of individual updates. This avoids
/// the overhead of managing update files and later compaction for tiny monitors that don't benefit
/// from differential updates.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is still not clear to me how much the gain is of this in practice. Also worried that disabling the incremental path initially allow certain bugs to linger for longer, just because the path isn't hit as much, or rarely.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good, but can we add some test coverage for the new behavior?

Additionally, benchmarks would indeed very helpful to evaluate what a reasonable threshold value would be.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from ac6966e to c6ad41bCompareJune 11, 2025 17:52

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rewrite your commit history so that it's clear what are feature and fixup commits. Each commit message should have a clear headline followed by some paragraph(s) describing the change, where it happened, and why it was necessary. For guidance, please take a look at https://cbea.ms/git-commit/

Comment threadlightning/src/util/persist.rs Outdated
Introduces an optimization to the MonitorUpdatingPersister to
avoid writing differential updates for small channel monitors.
When a channel monitor is smaller than a configurable threshold
, the persister will now write the full monitor instead of an update.
This avoids the I/O overhead of creating and managing many small update
files for monitors that don't benefit significantly from differential updates.
Adds unit test for introduced size based optimisation. Also updates
the old unit test to use a threshold value and use constructors to
increase test coverage
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 357ce4b to b313e39CompareJune 12, 2025 09:54
@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

I have created a minimal benchmarking setup here for this.
https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm not sure we can conclude all that much from a local-filesystem benchmark, sadly. We have several users (and hopefully more soon with ldk-node) who use the MonitorUpdatingPersister with remote storage, where costs can be very different from local (eg IP packet size bound). I'd say we use a threshold of 8192 for now and call it a day.

@tnull

Copy link
Copy Markdown
Contributor

I have created a minimal benchmarking setup here for this. https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger. Maybe @TheBlueMatt can provide some realistic monitor sizes here?

I'm asking because I suspect the results may stem from a latency vs. throughput trade-off, and under certain circumstances one might dominate over the other. The filesystem store for example likely (especially assuming that most file systems by now have 4kb block size) does not incur that much more latency when reading/writing 'larger' monitors (as 8kb is still tiny and the syscall / IO latency likely the dominant factor), while persistence to a remote server would see much slower write speeds and hence higher latency when (re-)persisting full monitors.

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Maybe @TheBlueMatt can provide some realistic monitor sizes here?

Yea, so 8KiB is a reasonable "channel that got opened and has only done a handful of HTLC operations in its history" threshold (tho is maybe even a bit too small for a more active mobile wallet). On my routing node the largest monitor is ~73MiB, I imagine c= has some that get into the hundreds of MiB.

@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger.

My assumptions here were to test the crossover point to select what was the optimal value of the threshold . Since the talks in the issue for threshold were in kBs , I assumed them to be in the same range and didn't go as far as to check the monitors in MB range and the results I was getting was becoming worse as I was moving towards bigger sizes which also made me not go higher. So the comments to monitor sizes in benchmark are not of much significance as they were relative to 4kB monitor size.

changes the threshold value to 8192 bytes as suggested in the PR comments
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 41c5253 to 9b4508bCompareJune 16, 2025 17:09
Comment threadlightning/src/util/persist.rs
@domZippilli

Copy link
Copy Markdown
Contributor

Left some thoughts on the issue, since my thoughts aren't about this implementation but more the feature itself. But posting here since this is where the recent action is. 🙇

@yuvicc

Copy link
Copy Markdown

Concept ACK

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current changes look good to me, but I'll defer ACKing to after the discussion on whether we want this change afterall has concluded.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
/// monitors. Set to 0 to always use update-based persistence regardless of size.
///
/// For other parameters, see [`MonitorUpdatingPersister::new`].
pub fn new_with_monitor_size_threshold(

@domZippillidomZippilliJun 30, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if, instead of a "with" constructor, it would be nicer/better to either add this to the default constructor, or use a config struct, or write a builder.

It's not a problem here, but I wonder if we'll think of another tunable for MUP and then there will be a third constructor, and so on.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have for now added this in the default constructor , since there is only 1 parameter that was affected . If more such tunables are added in the future , I would lean towards the config approach

changes the code to have a proper constant value than a unnamed hardcoded constant . Removes the extra constructor added and adjust the min_monitor_size_for_updates_bytes variable in the constructor
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make MonitorUpdatingPersister change persist type based on size

7 participants

@Prabhat1308@ldk-reviews-bot@TheBlueMatt@tnull@domZippilli@yuvicc@joostjager
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Make MonitorUpdatingPersister change persist type based on size - #3834

Closed
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type
Closed

feat: Make MonitorUpdatingPersister change persist type based on size#3834
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type

Conversation

@Prabhat1308

Copy link
Copy Markdown
Contributor

fixes#3770

  • Skips full persistence when ChannelMonitor is smaller than a pre-determined size.
  • Adds a field minimum_monitor_size_for_updates to specify the minimum size for full persistence to be activated
  • Adds new_with_default_threshold function to setup MonitorUpdatingPersister with a default minimum_monitor_size_for_updates value

@ldk-reviews-bot

ldk-reviews-bot commented Jun 7, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnull
tnull requested review from tnull and removed request for joostjagerJune 9, 2025 07:24
/// For small channel monitors (below `minimum_monitor_size_for_updates` bytes when serialized),
/// this persister will always write the full monitor instead of individual updates. This avoids
/// the overhead of managing update files and later compaction for tiny monitors that don't benefit
/// from differential updates.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is still not clear to me how much the gain is of this in practice. Also worried that disabling the incremental path initially allow certain bugs to linger for longer, just because the path isn't hit as much, or rarely.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good, but can we add some test coverage for the new behavior?

Additionally, benchmarks would indeed very helpful to evaluate what a reasonable threshold value would be.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from ac6966e to c6ad41bCompareJune 11, 2025 17:52

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rewrite your commit history so that it's clear what are feature and fixup commits. Each commit message should have a clear headline followed by some paragraph(s) describing the change, where it happened, and why it was necessary. For guidance, please take a look at https://cbea.ms/git-commit/

Comment threadlightning/src/util/persist.rs Outdated
Introduces an optimization to the MonitorUpdatingPersister to
avoid writing differential updates for small channel monitors.
When a channel monitor is smaller than a configurable threshold
, the persister will now write the full monitor instead of an update.
This avoids the I/O overhead of creating and managing many small update
files for monitors that don't benefit significantly from differential updates.
Adds unit test for introduced size based optimisation. Also updates
the old unit test to use a threshold value and use constructors to
increase test coverage
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 357ce4b to b313e39CompareJune 12, 2025 09:54
@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

I have created a minimal benchmarking setup here for this.
https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm not sure we can conclude all that much from a local-filesystem benchmark, sadly. We have several users (and hopefully more soon with ldk-node) who use the MonitorUpdatingPersister with remote storage, where costs can be very different from local (eg IP packet size bound). I'd say we use a threshold of 8192 for now and call it a day.

@tnull

Copy link
Copy Markdown
Contributor

I have created a minimal benchmarking setup here for this. https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger. Maybe @TheBlueMatt can provide some realistic monitor sizes here?

I'm asking because I suspect the results may stem from a latency vs. throughput trade-off, and under certain circumstances one might dominate over the other. The filesystem store for example likely (especially assuming that most file systems by now have 4kb block size) does not incur that much more latency when reading/writing 'larger' monitors (as 8kb is still tiny and the syscall / IO latency likely the dominant factor), while persistence to a remote server would see much slower write speeds and hence higher latency when (re-)persisting full monitors.

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Maybe @TheBlueMatt can provide some realistic monitor sizes here?

Yea, so 8KiB is a reasonable "channel that got opened and has only done a handful of HTLC operations in its history" threshold (tho is maybe even a bit too small for a more active mobile wallet). On my routing node the largest monitor is ~73MiB, I imagine c= has some that get into the hundreds of MiB.

@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger.

My assumptions here were to test the crossover point to select what was the optimal value of the threshold . Since the talks in the issue for threshold were in kBs , I assumed them to be in the same range and didn't go as far as to check the monitors in MB range and the results I was getting was becoming worse as I was moving towards bigger sizes which also made me not go higher. So the comments to monitor sizes in benchmark are not of much significance as they were relative to 4kB monitor size.

changes the threshold value to 8192 bytes as suggested in the PR comments
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 41c5253 to 9b4508bCompareJune 16, 2025 17:09
Comment threadlightning/src/util/persist.rs
@domZippilli

Copy link
Copy Markdown
Contributor

Left some thoughts on the issue, since my thoughts aren't about this implementation but more the feature itself. But posting here since this is where the recent action is. 🙇

@yuvicc

Copy link
Copy Markdown

Concept ACK

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current changes look good to me, but I'll defer ACKing to after the discussion on whether we want this change afterall has concluded.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
/// monitors. Set to 0 to always use update-based persistence regardless of size.
///
/// For other parameters, see [`MonitorUpdatingPersister::new`].
pub fn new_with_monitor_size_threshold(

@domZippillidomZippilliJun 30, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if, instead of a "with" constructor, it would be nicer/better to either add this to the default constructor, or use a config struct, or write a builder.

It's not a problem here, but I wonder if we'll think of another tunable for MUP and then there will be a third constructor, and so on.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have for now added this in the default constructor , since there is only 1 parameter that was affected . If more such tunables are added in the future , I would lean towards the config approach

changes the code to have a proper constant value than a unnamed hardcoded constant . Removes the extra constructor added and adjust the min_monitor_size_for_updates_bytes variable in the constructor
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make MonitorUpdatingPersister change persist type based on size

7 participants

@Prabhat1308@ldk-reviews-bot@TheBlueMatt@tnull@domZippilli@yuvicc@joostjager
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Make MonitorUpdatingPersister change persist type based on size - #3834

Closed
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type
Closed

feat: Make MonitorUpdatingPersister change persist type based on size#3834
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type

Conversation

@Prabhat1308

Copy link
Copy Markdown
Contributor

fixes#3770

  • Skips full persistence when ChannelMonitor is smaller than a pre-determined size.
  • Adds a field minimum_monitor_size_for_updates to specify the minimum size for full persistence to be activated
  • Adds new_with_default_threshold function to setup MonitorUpdatingPersister with a default minimum_monitor_size_for_updates value

@ldk-reviews-bot

ldk-reviews-bot commented Jun 7, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnull
tnull requested review from tnull and removed request for joostjagerJune 9, 2025 07:24
/// For small channel monitors (below `minimum_monitor_size_for_updates` bytes when serialized),
/// this persister will always write the full monitor instead of individual updates. This avoids
/// the overhead of managing update files and later compaction for tiny monitors that don't benefit
/// from differential updates.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is still not clear to me how much the gain is of this in practice. Also worried that disabling the incremental path initially allow certain bugs to linger for longer, just because the path isn't hit as much, or rarely.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good, but can we add some test coverage for the new behavior?

Additionally, benchmarks would indeed very helpful to evaluate what a reasonable threshold value would be.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from ac6966e to c6ad41bCompareJune 11, 2025 17:52

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rewrite your commit history so that it's clear what are feature and fixup commits. Each commit message should have a clear headline followed by some paragraph(s) describing the change, where it happened, and why it was necessary. For guidance, please take a look at https://cbea.ms/git-commit/

Comment threadlightning/src/util/persist.rs Outdated
Introduces an optimization to the MonitorUpdatingPersister to
avoid writing differential updates for small channel monitors.
When a channel monitor is smaller than a configurable threshold
, the persister will now write the full monitor instead of an update.
This avoids the I/O overhead of creating and managing many small update
files for monitors that don't benefit significantly from differential updates.
Adds unit test for introduced size based optimisation. Also updates
the old unit test to use a threshold value and use constructors to
increase test coverage
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 357ce4b to b313e39CompareJune 12, 2025 09:54
@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

I have created a minimal benchmarking setup here for this.
https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm not sure we can conclude all that much from a local-filesystem benchmark, sadly. We have several users (and hopefully more soon with ldk-node) who use the MonitorUpdatingPersister with remote storage, where costs can be very different from local (eg IP packet size bound). I'd say we use a threshold of 8192 for now and call it a day.

@tnull

Copy link
Copy Markdown
Contributor

I have created a minimal benchmarking setup here for this. https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger. Maybe @TheBlueMatt can provide some realistic monitor sizes here?

I'm asking because I suspect the results may stem from a latency vs. throughput trade-off, and under certain circumstances one might dominate over the other. The filesystem store for example likely (especially assuming that most file systems by now have 4kb block size) does not incur that much more latency when reading/writing 'larger' monitors (as 8kb is still tiny and the syscall / IO latency likely the dominant factor), while persistence to a remote server would see much slower write speeds and hence higher latency when (re-)persisting full monitors.

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Maybe @TheBlueMatt can provide some realistic monitor sizes here?

Yea, so 8KiB is a reasonable "channel that got opened and has only done a handful of HTLC operations in its history" threshold (tho is maybe even a bit too small for a more active mobile wallet). On my routing node the largest monitor is ~73MiB, I imagine c= has some that get into the hundreds of MiB.

@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger.

My assumptions here were to test the crossover point to select what was the optimal value of the threshold . Since the talks in the issue for threshold were in kBs , I assumed them to be in the same range and didn't go as far as to check the monitors in MB range and the results I was getting was becoming worse as I was moving towards bigger sizes which also made me not go higher. So the comments to monitor sizes in benchmark are not of much significance as they were relative to 4kB monitor size.

changes the threshold value to 8192 bytes as suggested in the PR comments
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 41c5253 to 9b4508bCompareJune 16, 2025 17:09
Comment threadlightning/src/util/persist.rs
@domZippilli

Copy link
Copy Markdown
Contributor

Left some thoughts on the issue, since my thoughts aren't about this implementation but more the feature itself. But posting here since this is where the recent action is. 🙇

@yuvicc

Copy link
Copy Markdown

Concept ACK

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current changes look good to me, but I'll defer ACKing to after the discussion on whether we want this change afterall has concluded.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
/// monitors. Set to 0 to always use update-based persistence regardless of size.
///
/// For other parameters, see [`MonitorUpdatingPersister::new`].
pub fn new_with_monitor_size_threshold(

@domZippillidomZippilliJun 30, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if, instead of a "with" constructor, it would be nicer/better to either add this to the default constructor, or use a config struct, or write a builder.

It's not a problem here, but I wonder if we'll think of another tunable for MUP and then there will be a third constructor, and so on.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have for now added this in the default constructor , since there is only 1 parameter that was affected . If more such tunables are added in the future , I would lean towards the config approach

changes the code to have a proper constant value than a unnamed hardcoded constant . Removes the extra constructor added and adjust the min_monitor_size_for_updates_bytes variable in the constructor
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make MonitorUpdatingPersister change persist type based on size

7 participants

@Prabhat1308@ldk-reviews-bot@TheBlueMatt@tnull@domZippilli@yuvicc@joostjager
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: Make MonitorUpdatingPersister change persist type based on size - #3834

Closed
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type
Closed

feat: Make MonitorUpdatingPersister change persist type based on size#3834
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type

Conversation

@Prabhat1308

Copy link
Copy Markdown
Contributor

fixes#3770

  • Skips full persistence when ChannelMonitor is smaller than a pre-determined size.
  • Adds a field minimum_monitor_size_for_updates to specify the minimum size for full persistence to be activated
  • Adds new_with_default_threshold function to setup MonitorUpdatingPersister with a default minimum_monitor_size_for_updates value

@ldk-reviews-bot

ldk-reviews-bot commented Jun 7, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnull
tnull requested review from tnull and removed request for joostjagerJune 9, 2025 07:24
/// For small channel monitors (below `minimum_monitor_size_for_updates` bytes when serialized),
/// this persister will always write the full monitor instead of individual updates. This avoids
/// the overhead of managing update files and later compaction for tiny monitors that don't benefit
/// from differential updates.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is still not clear to me how much the gain is of this in practice. Also worried that disabling the incremental path initially allow certain bugs to linger for longer, just because the path isn't hit as much, or rarely.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good, but can we add some test coverage for the new behavior?

Additionally, benchmarks would indeed very helpful to evaluate what a reasonable threshold value would be.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from ac6966e to c6ad41bCompareJune 11, 2025 17:52

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rewrite your commit history so that it's clear what are feature and fixup commits. Each commit message should have a clear headline followed by some paragraph(s) describing the change, where it happened, and why it was necessary. For guidance, please take a look at https://cbea.ms/git-commit/

Comment threadlightning/src/util/persist.rs Outdated
Introduces an optimization to the MonitorUpdatingPersister to
avoid writing differential updates for small channel monitors.
When a channel monitor is smaller than a configurable threshold
, the persister will now write the full monitor instead of an update.
This avoids the I/O overhead of creating and managing many small update
files for monitors that don't benefit significantly from differential updates.
Adds unit test for introduced size based optimisation. Also updates
the old unit test to use a threshold value and use constructors to
increase test coverage
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 357ce4b to b313e39CompareJune 12, 2025 09:54
@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

I have created a minimal benchmarking setup here for this.
https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm not sure we can conclude all that much from a local-filesystem benchmark, sadly. We have several users (and hopefully more soon with ldk-node) who use the MonitorUpdatingPersister with remote storage, where costs can be very different from local (eg IP packet size bound). I'd say we use a threshold of 8192 for now and call it a day.

@tnull

Copy link
Copy Markdown
Contributor

I have created a minimal benchmarking setup here for this. https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger. Maybe @TheBlueMatt can provide some realistic monitor sizes here?

I'm asking because I suspect the results may stem from a latency vs. throughput trade-off, and under certain circumstances one might dominate over the other. The filesystem store for example likely (especially assuming that most file systems by now have 4kb block size) does not incur that much more latency when reading/writing 'larger' monitors (as 8kb is still tiny and the syscall / IO latency likely the dominant factor), while persistence to a remote server would see much slower write speeds and hence higher latency when (re-)persisting full monitors.

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Maybe @TheBlueMatt can provide some realistic monitor sizes here?

Yea, so 8KiB is a reasonable "channel that got opened and has only done a handful of HTLC operations in its history" threshold (tho is maybe even a bit too small for a more active mobile wallet). On my routing node the largest monitor is ~73MiB, I imagine c= has some that get into the hundreds of MiB.

@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger.

My assumptions here were to test the crossover point to select what was the optimal value of the threshold . Since the talks in the issue for threshold were in kBs , I assumed them to be in the same range and didn't go as far as to check the monitors in MB range and the results I was getting was becoming worse as I was moving towards bigger sizes which also made me not go higher. So the comments to monitor sizes in benchmark are not of much significance as they were relative to 4kB monitor size.

changes the threshold value to 8192 bytes as suggested in the PR comments
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 41c5253 to 9b4508bCompareJune 16, 2025 17:09
Comment threadlightning/src/util/persist.rs
@domZippilli

Copy link
Copy Markdown
Contributor

Left some thoughts on the issue, since my thoughts aren't about this implementation but more the feature itself. But posting here since this is where the recent action is. 🙇

@yuvicc

Copy link
Copy Markdown

Concept ACK

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current changes look good to me, but I'll defer ACKing to after the discussion on whether we want this change afterall has concluded.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
/// monitors. Set to 0 to always use update-based persistence regardless of size.
///
/// For other parameters, see [`MonitorUpdatingPersister::new`].
pub fn new_with_monitor_size_threshold(

@domZippillidomZippilliJun 30, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if, instead of a "with" constructor, it would be nicer/better to either add this to the default constructor, or use a config struct, or write a builder.

It's not a problem here, but I wonder if we'll think of another tunable for MUP and then there will be a third constructor, and so on.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have for now added this in the default constructor , since there is only 1 parameter that was affected . If more such tunables are added in the future , I would lean towards the config approach

changes the code to have a proper constant value than a unnamed hardcoded constant . Removes the extra constructor added and adjust the min_monitor_size_for_updates_bytes variable in the constructor
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make MonitorUpdatingPersister change persist type based on size

7 participants

@Prabhat1308@ldk-reviews-bot@TheBlueMatt@tnull@domZippilli@yuvicc@joostjager
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Make MonitorUpdatingPersister change persist type based on size - #3834

Closed
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type
Closed

feat: Make MonitorUpdatingPersister change persist type based on size#3834
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type

Conversation

@Prabhat1308

Copy link
Copy Markdown
Contributor

fixes#3770

  • Skips full persistence when ChannelMonitor is smaller than a pre-determined size.
  • Adds a field minimum_monitor_size_for_updates to specify the minimum size for full persistence to be activated
  • Adds new_with_default_threshold function to setup MonitorUpdatingPersister with a default minimum_monitor_size_for_updates value

@ldk-reviews-bot

ldk-reviews-bot commented Jun 7, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnull
tnull requested review from tnull and removed request for joostjagerJune 9, 2025 07:24
/// For small channel monitors (below `minimum_monitor_size_for_updates` bytes when serialized),
/// this persister will always write the full monitor instead of individual updates. This avoids
/// the overhead of managing update files and later compaction for tiny monitors that don't benefit
/// from differential updates.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is still not clear to me how much the gain is of this in practice. Also worried that disabling the incremental path initially allow certain bugs to linger for longer, just because the path isn't hit as much, or rarely.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good, but can we add some test coverage for the new behavior?

Additionally, benchmarks would indeed very helpful to evaluate what a reasonable threshold value would be.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from ac6966e to c6ad41bCompareJune 11, 2025 17:52

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rewrite your commit history so that it's clear what are feature and fixup commits. Each commit message should have a clear headline followed by some paragraph(s) describing the change, where it happened, and why it was necessary. For guidance, please take a look at https://cbea.ms/git-commit/

Comment threadlightning/src/util/persist.rs Outdated
Introduces an optimization to the MonitorUpdatingPersister to
avoid writing differential updates for small channel monitors.
When a channel monitor is smaller than a configurable threshold
, the persister will now write the full monitor instead of an update.
This avoids the I/O overhead of creating and managing many small update
files for monitors that don't benefit significantly from differential updates.
Adds unit test for introduced size based optimisation. Also updates
the old unit test to use a threshold value and use constructors to
increase test coverage
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 357ce4b to b313e39CompareJune 12, 2025 09:54
@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

I have created a minimal benchmarking setup here for this.
https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm not sure we can conclude all that much from a local-filesystem benchmark, sadly. We have several users (and hopefully more soon with ldk-node) who use the MonitorUpdatingPersister with remote storage, where costs can be very different from local (eg IP packet size bound). I'd say we use a threshold of 8192 for now and call it a day.

@tnull

Copy link
Copy Markdown
Contributor

I have created a minimal benchmarking setup here for this. https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger. Maybe @TheBlueMatt can provide some realistic monitor sizes here?

I'm asking because I suspect the results may stem from a latency vs. throughput trade-off, and under certain circumstances one might dominate over the other. The filesystem store for example likely (especially assuming that most file systems by now have 4kb block size) does not incur that much more latency when reading/writing 'larger' monitors (as 8kb is still tiny and the syscall / IO latency likely the dominant factor), while persistence to a remote server would see much slower write speeds and hence higher latency when (re-)persisting full monitors.

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Maybe @TheBlueMatt can provide some realistic monitor sizes here?

Yea, so 8KiB is a reasonable "channel that got opened and has only done a handful of HTLC operations in its history" threshold (tho is maybe even a bit too small for a more active mobile wallet). On my routing node the largest monitor is ~73MiB, I imagine c= has some that get into the hundreds of MiB.

@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger.

My assumptions here were to test the crossover point to select what was the optimal value of the threshold . Since the talks in the issue for threshold were in kBs , I assumed them to be in the same range and didn't go as far as to check the monitors in MB range and the results I was getting was becoming worse as I was moving towards bigger sizes which also made me not go higher. So the comments to monitor sizes in benchmark are not of much significance as they were relative to 4kB monitor size.

changes the threshold value to 8192 bytes as suggested in the PR comments
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 41c5253 to 9b4508bCompareJune 16, 2025 17:09
Comment threadlightning/src/util/persist.rs
@domZippilli

Copy link
Copy Markdown
Contributor

Left some thoughts on the issue, since my thoughts aren't about this implementation but more the feature itself. But posting here since this is where the recent action is. 🙇

@yuvicc

Copy link
Copy Markdown

Concept ACK

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current changes look good to me, but I'll defer ACKing to after the discussion on whether we want this change afterall has concluded.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
/// monitors. Set to 0 to always use update-based persistence regardless of size.
///
/// For other parameters, see [`MonitorUpdatingPersister::new`].
pub fn new_with_monitor_size_threshold(

@domZippillidomZippilliJun 30, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if, instead of a "with" constructor, it would be nicer/better to either add this to the default constructor, or use a config struct, or write a builder.

It's not a problem here, but I wonder if we'll think of another tunable for MUP and then there will be a third constructor, and so on.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have for now added this in the default constructor , since there is only 1 parameter that was affected . If more such tunables are added in the future , I would lean towards the config approach

changes the code to have a proper constant value than a unnamed hardcoded constant . Removes the extra constructor added and adjust the min_monitor_size_for_updates_bytes variable in the constructor
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make MonitorUpdatingPersister change persist type based on size

7 participants

@Prabhat1308@ldk-reviews-bot@TheBlueMatt@tnull@domZippilli@yuvicc@joostjager
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Make MonitorUpdatingPersister change persist type based on size - #3834

Closed
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type
Closed

feat: Make MonitorUpdatingPersister change persist type based on size#3834
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type

Conversation

@Prabhat1308

Copy link
Copy Markdown
Contributor

fixes#3770

  • Skips full persistence when ChannelMonitor is smaller than a pre-determined size.
  • Adds a field minimum_monitor_size_for_updates to specify the minimum size for full persistence to be activated
  • Adds new_with_default_threshold function to setup MonitorUpdatingPersister with a default minimum_monitor_size_for_updates value

@ldk-reviews-bot

ldk-reviews-bot commented Jun 7, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnull
tnull requested review from tnull and removed request for joostjagerJune 9, 2025 07:24
/// For small channel monitors (below `minimum_monitor_size_for_updates` bytes when serialized),
/// this persister will always write the full monitor instead of individual updates. This avoids
/// the overhead of managing update files and later compaction for tiny monitors that don't benefit
/// from differential updates.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is still not clear to me how much the gain is of this in practice. Also worried that disabling the incremental path initially allow certain bugs to linger for longer, just because the path isn't hit as much, or rarely.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good, but can we add some test coverage for the new behavior?

Additionally, benchmarks would indeed very helpful to evaluate what a reasonable threshold value would be.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from ac6966e to c6ad41bCompareJune 11, 2025 17:52

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rewrite your commit history so that it's clear what are feature and fixup commits. Each commit message should have a clear headline followed by some paragraph(s) describing the change, where it happened, and why it was necessary. For guidance, please take a look at https://cbea.ms/git-commit/

Comment threadlightning/src/util/persist.rs Outdated
Introduces an optimization to the MonitorUpdatingPersister to
avoid writing differential updates for small channel monitors.
When a channel monitor is smaller than a configurable threshold
, the persister will now write the full monitor instead of an update.
This avoids the I/O overhead of creating and managing many small update
files for monitors that don't benefit significantly from differential updates.
Adds unit test for introduced size based optimisation. Also updates
the old unit test to use a threshold value and use constructors to
increase test coverage
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 357ce4b to b313e39CompareJune 12, 2025 09:54
@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

I have created a minimal benchmarking setup here for this.
https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm not sure we can conclude all that much from a local-filesystem benchmark, sadly. We have several users (and hopefully more soon with ldk-node) who use the MonitorUpdatingPersister with remote storage, where costs can be very different from local (eg IP packet size bound). I'd say we use a threshold of 8192 for now and call it a day.

@tnull

Copy link
Copy Markdown
Contributor

I have created a minimal benchmarking setup here for this. https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger. Maybe @TheBlueMatt can provide some realistic monitor sizes here?

I'm asking because I suspect the results may stem from a latency vs. throughput trade-off, and under certain circumstances one might dominate over the other. The filesystem store for example likely (especially assuming that most file systems by now have 4kb block size) does not incur that much more latency when reading/writing 'larger' monitors (as 8kb is still tiny and the syscall / IO latency likely the dominant factor), while persistence to a remote server would see much slower write speeds and hence higher latency when (re-)persisting full monitors.

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Maybe @TheBlueMatt can provide some realistic monitor sizes here?

Yea, so 8KiB is a reasonable "channel that got opened and has only done a handful of HTLC operations in its history" threshold (tho is maybe even a bit too small for a more active mobile wallet). On my routing node the largest monitor is ~73MiB, I imagine c= has some that get into the hundreds of MiB.

@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger.

My assumptions here were to test the crossover point to select what was the optimal value of the threshold . Since the talks in the issue for threshold were in kBs , I assumed them to be in the same range and didn't go as far as to check the monitors in MB range and the results I was getting was becoming worse as I was moving towards bigger sizes which also made me not go higher. So the comments to monitor sizes in benchmark are not of much significance as they were relative to 4kB monitor size.

changes the threshold value to 8192 bytes as suggested in the PR comments
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 41c5253 to 9b4508bCompareJune 16, 2025 17:09
Comment threadlightning/src/util/persist.rs
@domZippilli

Copy link
Copy Markdown
Contributor

Left some thoughts on the issue, since my thoughts aren't about this implementation but more the feature itself. But posting here since this is where the recent action is. 🙇

@yuvicc

Copy link
Copy Markdown

Concept ACK

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current changes look good to me, but I'll defer ACKing to after the discussion on whether we want this change afterall has concluded.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
/// monitors. Set to 0 to always use update-based persistence regardless of size.
///
/// For other parameters, see [`MonitorUpdatingPersister::new`].
pub fn new_with_monitor_size_threshold(

@domZippillidomZippilliJun 30, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if, instead of a "with" constructor, it would be nicer/better to either add this to the default constructor, or use a config struct, or write a builder.

It's not a problem here, but I wonder if we'll think of another tunable for MUP and then there will be a third constructor, and so on.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have for now added this in the default constructor , since there is only 1 parameter that was affected . If more such tunables are added in the future , I would lean towards the config approach

changes the code to have a proper constant value than a unnamed hardcoded constant . Removes the extra constructor added and adjust the min_monitor_size_for_updates_bytes variable in the constructor
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make MonitorUpdatingPersister change persist type based on size

7 participants

@Prabhat1308@ldk-reviews-bot@TheBlueMatt@tnull@domZippilli@yuvicc@joostjager
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: Make MonitorUpdatingPersister change persist type based on size - #3834

Closed
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type
Closed

feat: Make MonitorUpdatingPersister change persist type based on size#3834
Prabhat1308 wants to merge 4 commits into
lightningdevkit:mainfrom
Prabhat1308:probot/change_persist_type

Conversation

@Prabhat1308

Copy link
Copy Markdown
Contributor

fixes#3770

  • Skips full persistence when ChannelMonitor is smaller than a pre-determined size.
  • Adds a field minimum_monitor_size_for_updates to specify the minimum size for full persistence to be activated
  • Adds new_with_default_threshold function to setup MonitorUpdatingPersister with a default minimum_monitor_size_for_updates value

@ldk-reviews-bot

ldk-reviews-bot commented Jun 7, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnull
tnull requested review from tnull and removed request for joostjagerJune 9, 2025 07:24
/// For small channel monitors (below `minimum_monitor_size_for_updates` bytes when serialized),
/// this persister will always write the full monitor instead of individual updates. This avoids
/// the overhead of managing update files and later compaction for tiny monitors that don't benefit
/// from differential updates.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is still not clear to me how much the gain is of this in practice. Also worried that disabling the incremental path initially allow certain bugs to linger for longer, just because the path isn't hit as much, or rarely.

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good, but can we add some test coverage for the new behavior?

Additionally, benchmarks would indeed very helpful to evaluate what a reasonable threshold value would be.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from ac6966e to c6ad41bCompareJune 11, 2025 17:52

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rewrite your commit history so that it's clear what are feature and fixup commits. Each commit message should have a clear headline followed by some paragraph(s) describing the change, where it happened, and why it was necessary. For guidance, please take a look at https://cbea.ms/git-commit/

Comment threadlightning/src/util/persist.rs Outdated
Introduces an optimization to the MonitorUpdatingPersister to
avoid writing differential updates for small channel monitors.
When a channel monitor is smaller than a configurable threshold
, the persister will now write the full monitor instead of an update.
This avoids the I/O overhead of creating and managing many small update
files for monitors that don't benefit significantly from differential updates.
Adds unit test for introduced size based optimisation. Also updates
the old unit test to use a threshold value and use constructors to
increase test coverage
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 357ce4b to b313e39CompareJune 12, 2025 09:54
@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

I have created a minimal benchmarking setup here for this.
https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm not sure we can conclude all that much from a local-filesystem benchmark, sadly. We have several users (and hopefully more soon with ldk-node) who use the MonitorUpdatingPersister with remote storage, where costs can be very different from local (eg IP packet size bound). I'd say we use a threshold of 8192 for now and call it a day.

@tnull

Copy link
Copy Markdown
Contributor

I have created a minimal benchmarking setup here for this. https://github.com/Prabhat1308/rust-lightning/tree/probot/benchmark

from this I get that adding update based persistence is reducing the performance completely opposite to what is claimed in the issue . [There are a lot of assumptions in the benchmarking regarding the update size and monitor sizes ]

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger. Maybe @TheBlueMatt can provide some realistic monitor sizes here?

I'm asking because I suspect the results may stem from a latency vs. throughput trade-off, and under certain circumstances one might dominate over the other. The filesystem store for example likely (especially assuming that most file systems by now have 4kb block size) does not incur that much more latency when reading/writing 'larger' monitors (as 8kb is still tiny and the syscall / IO latency likely the dominant factor), while persistence to a remote server would see much slower write speeds and hence higher latency when (re-)persisting full monitors.

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Maybe @TheBlueMatt can provide some realistic monitor sizes here?

Yea, so 8KiB is a reasonable "channel that got opened and has only done a handful of HTLC operations in its history" threshold (tho is maybe even a bit too small for a more active mobile wallet). On my routing node the largest monitor is ~73MiB, I imagine c= has some that get into the hundreds of MiB.

@Prabhat1308

Copy link
Copy Markdown
ContributorAuthor

Thanks for taking a first look at these benchmarks. How did you arrive at some of these assumptions? E.g., how did you decide on the 8KB threshold being 'large' monitors. I believe in reality monitors could end up being much larger.

My assumptions here were to test the crossover point to select what was the optimal value of the threshold . Since the talks in the issue for threshold were in kBs , I assumed them to be in the same range and didn't go as far as to check the monitors in MB range and the results I was getting was becoming worse as I was moving towards bigger sizes which also made me not go higher. So the comments to monitor sizes in benchmark are not of much significance as they were relative to 4kB monitor size.

changes the threshold value to 8192 bytes as suggested in the PR comments
@Prabhat1308
Prabhat1308force-pushed the probot/change_persist_type branch from 41c5253 to 9b4508bCompareJune 16, 2025 17:09
Comment threadlightning/src/util/persist.rs
@domZippilli

Copy link
Copy Markdown
Contributor

Left some thoughts on the issue, since my thoughts aren't about this implementation but more the feature itself. But posting here since this is where the recent action is. 🙇

@yuvicc

Copy link
Copy Markdown

Concept ACK

@tnulltnull left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current changes look good to me, but I'll defer ACKing to after the discussion on whether we want this change afterall has concluded.

Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
Comment threadlightning/src/util/persist.rs Outdated
/// monitors. Set to 0 to always use update-based persistence regardless of size.
///
/// For other parameters, see [`MonitorUpdatingPersister::new`].
pub fn new_with_monitor_size_threshold(

@domZippillidomZippilliJun 30, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if, instead of a "with" constructor, it would be nicer/better to either add this to the default constructor, or use a config struct, or write a builder.

It's not a problem here, but I wonder if we'll think of another tunable for MUP and then there will be a third constructor, and so on.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have for now added this in the default constructor , since there is only 1 parameter that was affected . If more such tunables are added in the future , I would lean towards the config approach

changes the code to have a proper constant value than a unnamed hardcoded constant . Removes the extra constructor added and adjust the min_monitor_size_for_updates_bytes variable in the constructor
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make MonitorUpdatingPersister change persist type based on size

7 participants

@Prabhat1308@ldk-reviews-bot@TheBlueMatt@tnull@domZippilli@yuvicc@joostjager