Skip to content

Forkless Snapshot (Threadsave)#3648

Open
nitaicaro wants to merge 1 commit into
valkey-io:forkless-pre-threadsavefrom
nitaicaro:forkless-snapshot
Open

Forkless Snapshot (Threadsave)#3648
nitaicaro wants to merge 1 commit into
valkey-io:forkless-pre-threadsavefrom
nitaicaro:forkless-snapshot

Conversation

@nitaicaro

@nitaicaro nitaicaro commented May 8, 2026

Copy link
Copy Markdown
Contributor

Thread-based RDB snapshot (Threadsave)

Motivation

Fork-based BGSAVE relies on fork(), which on large datasets causes significant memory overhead from copy-on-write page duplication. On systems where memory is constrained, fork can fail entirely. Threadsave provides an alternative that avoids fork by performing the RDB snapshot on a background thread while the main thread continues serving clients.

How it works

Threadsave builds on the bgIteration framework (introduced in #3553). bgIteration walks the keyspace on the main thread, delivering keys to a FIFO queue. A background thread consumes entries from the queue and serializes them to an RDB file using the standard rdbSaveKeyValuePair encoding. The result is a normal RDB file - loadable by any Valkey instance.

Usage

A thread-based snapshot can be triggered in three ways:

  • BGSAVE THREAD - explicit command (requires forkless-options-supported yes)
  • config set threadsave-enabled-for-backup yes - makes plain BGSAVE use threadsave
  • Automatic periodic saves will use threadsave when threadsave-enabled-for-backup is enabled

BGSAVE FORK explicitly forces a fork-based snapshot regardless of configuration. BGSAVE SCHEDULE THREAD / BGSAVE SCHEDULE FORK schedule a snapshot with explicit type.

@codecov

codecov Bot commented May 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.35897% with 61 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.32%. Comparing base (f863b3c) to head (16bedb8).
⚠️ Report is 1 commits behind head on forkless-pre-threadsave.

Files with missing lines Patch % Lines
src/threadsave.c 82.38% 34 Missing ⚠️
src/rdb.c 88.59% 13 Missing ⚠️
src/server.c 77.77% 12 Missing ⚠️
src/module.c 0.00% 2 Missing ⚠️
Additional details and impacted files
@@                     Coverage Diff                     @@
##           forkless-pre-threadsave    #3648      +/-   ##
===========================================================
+ Coverage                    75.63%   77.32%   +1.69%     
===========================================================
  Files                          160      162       +2     
  Lines                        80744    82386    +1642     
===========================================================
+ Hits                         61069    63707    +2638     
+ Misses                       19675    18679     -996     
Files with missing lines Coverage Δ
src/bgiteration.c 93.64% <100.00%> (+89.90%) ⬆️
src/commands.def 100.00% <ø> (ø)
src/config.c 78.33% <ø> (ø)
src/db.c 94.60% <100.00%> (+0.34%) ⬆️
src/rdb.h 100.00% <ø> (ø)
src/replication.c 86.12% <100.00%> (ø)
src/server.h 100.00% <ø> (ø)
src/module.c 26.30% <0.00%> (-0.01%) ⬇️
src/server.c 89.85% <77.77%> (+0.62%) ⬆️
src/rdb.c 76.91% <88.59%> (-0.34%) ⬇️
... and 1 more

... and 24 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread src/threadsave.c
Comment thread src/threadsave.c
Comment thread src/threadsave.c
Comment thread src/threadsave.c Outdated
Comment thread src/threadsave.c
Comment thread src/threadsave.c Outdated
Comment thread src/threadsave.c Outdated
Comment thread src/threadsave.c Outdated
Comment thread src/threadsave.c
Comment thread src/threadsave.c
Comment thread src/module.c
Comment thread src/server.c Outdated
Comment thread src/rdb.c Outdated
Comment thread src/rdb.c
Comment thread src/rdb.c
@nitaicaro nitaicaro force-pushed the forkless-snapshot branch from a00a573 to 5482b96 Compare May 14, 2026 18:48
@coderabbitai

coderabbitai Bot commented May 14, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8a27b62c-7b40-458f-ba53-4ab3bbf2b6b8

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nitaicaro nitaicaro force-pushed the forkless-snapshot branch 2 times, most recently from 1588575 to 79b3cc3 Compare May 14, 2026 21:17
@nitaicaro nitaicaro requested a review from murphyjacob4 May 14, 2026 22:32
@nitaicaro nitaicaro force-pushed the forkless-snapshot branch 7 times, most recently from cca0dfe to fa3301a Compare May 19, 2026 18:49
@JimB123 JimB123 force-pushed the forkless-pre-threadsave branch from 281d627 to c0f533c Compare May 28, 2026 22:17
@nitaicaro nitaicaro force-pushed the forkless-snapshot branch 2 times, most recently from 05a2f38 to fa3301a Compare May 28, 2026 22:28
@JimB123 JimB123 force-pushed the forkless-pre-threadsave branch from 2634d89 to c0f533c Compare May 29, 2026 14:54
@nitaicaro nitaicaro force-pushed the forkless-snapshot branch 6 times, most recently from 00d57ed to fb0c570 Compare May 29, 2026 21:46
@nitaicaro nitaicaro changed the title Draft: Forkless Snapshot (Threadsave) Forkless Snapshot (Threadsave) May 29, 2026
@nitaicaro nitaicaro marked this pull request as ready for review May 29, 2026 22:22
Comment thread valkey.conf
# When disabled (default), automatic saves use fork. You can still trigger a
# thread-based snapshot explicitly with 'BGSAVE THREAD'.
#
# threadsave-enabled-for-backup no

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For naming consistency, these should ALL be forkless or ALL be threadsave. Right now we're mixing terminology.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

forkless-options-supported is from the preceding bgIteration PRs - it's the umbrella infrastructure flag that enables per-key metadata allocation needed for the entire forkless family:
threadsave-to-disk (this PR), future threadsave-for-replication, and future forkless slot migration. This PR only references it as a prerequisite check. Everything introduced here uses "threadsave" (config, INFO fields, API, flags).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it's ok to have a distinction between "forkless save" - a general strategy, and "Threadsave" - a specific implementation of that strategy. We might expect that someday, Threadsave could be replaced by a new-and-improved forkless implementation. In the code, I like calling it "Threadsave" - and there are contexts where talking about Threadsave as a "forkless save" makes sense.

However, I agree with Maddy that the external presentation should be consistent. I don't feel strongly regarding presentation as "forkless" or presentation as "threadsave". I can see reasons for each. The configs, and the bgsave option should match.

@nitaicaro nitaicaro force-pushed the forkless-snapshot branch 3 times, most recently from 06a2531 to 1321109 Compare June 12, 2026 17:44
Signed-off-by: Nitai Caro <caronita@amazon.com>
@nitaicaro nitaicaro force-pushed the forkless-snapshot branch from 1321109 to 16bedb8 Compare June 12, 2026 19:01
Sign up for free to 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.

4 participants