From 3b1d6fbbd72e20b31c13d0144d110cf5e9c3f39e Mon Sep 17 00:00:00 2001 From: mich-elle-luna Date: Tue, 21 Jul 2026 09:24:01 -0700 Subject: [PATCH 1/2] DOC-6874: Document smooth scaling prerequisites on Cloud clustering page Adds a Smooth scaling section covering prerequisites (new DB, Redis hashing policy, DB version 8.4+, cluster version 8.0.18+, HA required), unsupported cases (Active-Active, Flex, existing DBs), and backward compatibility guidance for when it is safe to enable. Updates the Redis hashing policy description to link to the new section. Co-Authored-By: Claude Sonnet 4.6 --- .../rc/databases/configuration/clustering.md | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/content/operate/rc/databases/configuration/clustering.md b/content/operate/rc/databases/configuration/clustering.md index c42574e6b6..c7476cff63 100644 --- a/content/operate/rc/databases/configuration/clustering.md +++ b/content/operate/rc/databases/configuration/clustering.md @@ -100,7 +100,7 @@ The Redis hashing policy is identical to the [hashing policy used by Redis Open - Your application does not use hashtags in database key names. - Your application uses binary data as key names. -The Redis hashing policy allows for faster scaling where available. +The Redis hashing policy allows for [faster scaling](#smooth-scaling) where available. ### Standard hashing policy @@ -194,4 +194,43 @@ After you select OSS Cluster API, you can select **Use external endpoint** if yo The OSS Cluster API is supported only when a database uses the [standard hashing policy](#standard-hashing-policy). -Review [OSS Cluster API architecture]({{< relref "/operate/rs/clusters/optimize/oss-cluster-api" >}}) to determine if you should enable this feature for your database. \ No newline at end of file +Review [OSS Cluster API architecture]({{< relref "/operate/rs/clusters/optimize/oss-cluster-api" >}}) to determine if you should enable this feature for your database. + +## Smooth scaling {#smooth-scaling} + +Smooth scaling is an improved resharding method for Redis Cloud Pro databases. Compared to legacy resharding, it is significantly faster, reduces latency spikes and disconnects during scaling, and supports scaling down (decreasing shard count). Legacy resharding always doubles the shard count and does not support scale-down. + +{{< note >}} +Smooth scaling is only available for new databases. Existing databases continue to use legacy resharding. +{{< /note >}} + +### Prerequisites + +All of the following conditions must be met to use smooth scaling: + +| Requirement | Detail | +|---|---| +| New database | Smooth scaling cannot be enabled on an existing database. | +| Hashing policy | Must use the [Redis hashing policy](#redis-hashing-policy). Standard and Custom hashing policies are not supported. | +| Database version | Redis 8.4 or later. | +| Cluster version | Redis Cloud cluster version 8.0.18 or later. | +| High availability | HA must be enabled. Without HA, a database restart during scaling risks data loss. | + +### Not supported + +Smooth scaling is not available for: + +- Active-Active databases +- Flex (Auto Tiering) databases +- Existing databases that use the Standard or Custom hashing policy + +### Backward compatibility + +Enabling smooth scaling puts shards into cluster mode, which enforces the same-slot requirement for multi-key commands. For most new databases this is safe to enable immediately, but there are cases where you should wait: + +| Database configuration | Recommendation | +|---|---| +| Created with multiple shards | Safe to enable immediately. | +| Created with OSS Cluster API enabled | Safe to enable immediately. | +| Created with a single shard | Wait until after the first scale operation before enabling, to ensure slot-aware behavior is introduced gradually. | +| HA disabled | Do not enable until HA is turned on. | \ No newline at end of file From 54b9aaa21e8b101c0b8a8c45a33ae543626574d3 Mon Sep 17 00:00:00 2001 From: mich-elle-luna Date: Thu, 23 Jul 2026 08:04:56 -0700 Subject: [PATCH 2/2] DOC-6874: Apply SME review feedback on smooth scaling section - Capitalize "Smooth Scaling" as a proper noun (line 103) - Fix OSS Cluster API hashing policy support: both Standard and Redis hashing policies are supported (pre-existing inaccuracy) - Replace "legacy" with "traditional" throughout - Remove scale-down comparison claims (not a customer-visible differentiator) - Reframe availability: any DB meeting prerequisites, not "new DBs only" - Reframe prerequisites as automatic conditions, not user-enabled settings - Remove "New database" prerequisite row (inaccurate framing) - Update hashing policy detail to clarify Standard/Custom use traditional scaling - Remove "Cluster version" row (internal detail, not visible to RC users) - Remove "High availability" row (limitation was removed) - Replace backward compatibility table with a note that no app code changes are needed Co-Authored-By: Claude Sonnet 4.6 --- .claude/state/assess-comments.coverage.md | 12 +++++----- .../rc/databases/configuration/clustering.md | 24 ++++++------------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/.claude/state/assess-comments.coverage.md b/.claude/state/assess-comments.coverage.md index 6f91355a1b..11dc89dd1d 100644 --- a/.claude/state/assess-comments.coverage.md +++ b/.claude/state/assess-comments.coverage.md @@ -27,11 +27,11 @@ whether to commit the change. | Capability | Confidence | Real encounters | Last verified | Evidence | |---|---|---|---|---| -| Branch/PR identification + arg handling | 🟒 corroborated | 12 | 2026-07-15 | #3415, #3507, #3374, #3536, #3542, #3543, #3573, #2531, #3585, #3604, #3612, #3627 | -| Multi-source collection (inline + top-level + reviews) | 🟒 corroborated | 13 | 2026-07-15 | #3415, #3507, #3510, #3374, #3536, #3542, #3543, #3573, #2531, #3585, #3604, #3612, #3627 | -| GraphQL thread-resolution pull (`isResolved`/`isOutdated`) | 🟒 corroborated | 10 | 2026-07-10 | #3510 (12/12 resolved), #3374 (15/15), #3536 (2/2 open), #3542 (3 resolved/1 open), #3543 (1/1 open), #3573 (2/2 open), #2531 (r1: 11 open/2 res-outdated/1 open; r2: 11 of 14 outdated after fixes + APPROVED), #3585 (r1 2 open; r2 3 open + 2 resolved β€” one outdated, one resolved-not-outdated); #3604 (r1 2/2 open; r2 4/4 open; r3 5 threads = 2 resolved [one outdated, one resolved-not-outdated] / 3 open, hasNextPage:false); #3612 (r1 4/4 open, hasNextPage:false) | -| Source-role tagging (bugbot/security/history/summary/ci/human) | 🟒 corroborated | 11 | 2026-07-10 | #3415, #3507, #3374, #3536, #3542, #3543, #3573, #2531, #3585, #3604, #3612, #3627 (bugbot inline + github-actions Jira-link ci; no human/summary this PR) | -| Open/resolved split | 🟒 corroborated | 10 | 2026-07-10 | #3510, #3374, #3536 (0 resolved/2 open), #3542 (3 resolved/1 open), #3543, #3573 (r1/r2 mixed), #2531 (11 open / 3 resolved), #3585 (r1 2 open/0 res; r2 3 open/2 resolved), #3604 (r1 0 res/2 open; r2 0 res/4 open; r3 2 res/3 open), #3612 (0 res/4 open), #3627 (0 res/1 open) | +| Branch/PR identification + arg handling | 🟒 corroborated | 13 | 2026-07-23 | #3415, #3507, #3374, #3536, #3542, #3543, #3573, #2531, #3585, #3604, #3612, #3627, #3687 | +| Multi-source collection (inline + top-level + reviews) | 🟒 corroborated | 14 | 2026-07-23 | #3415, #3507, #3510, #3374, #3536, #3542, #3543, #3573, #2531, #3585, #3604, #3612, #3627, #3687 | +| GraphQL thread-resolution pull (`isResolved`/`isOutdated`) | 🟒 corroborated | 10 | 2026-07-10 | #3510 (12/12 resolved), #3374 (15/15), #3536 (2/2 open), #3542 (3 resolved/1 open), #3543 (1/1 open), #3573 (2/2 open), #2531 (r1: 11 open/2 res-outdated/1 open; r2: 11 of 14 outdated after fixes + APPROVED), #3585 (r1 2 open; r2 3 open + 2 resolved β€” one outdated, one resolved-not-outdated); #3604 (r1 2/2 open; r2 4/4 open; r3 5 threads = 2 resolved [one outdated, one resolved-not-outdated] / 3 open, hasNextPage:false); #3612 (r1 4/4 open, hasNextPage:false). **#3687: GraphQL unavailable** (no `gh` CLI in this environment β€” `gh api graphql` requires the `gh` CLI, which is absent; curl returned 401 because no token was found). Fell back to context-based inference (CHANGES_REQUESTED + no post-review commits β†’ all 9 threads open). Known failure mode: when `gh` is absent, resolution state is inferred, not confirmed. | +| Source-role tagging (bugbot/security/history/summary/ci/human) | 🟒 corroborated | 12 | 2026-07-23 | #3415, #3507, #3374, #3536, #3542, #3543, #3573, #2531, #3585, #3604, #3612, #3627, #3687 (yoavredis=human CHANGES_REQUESTED; github-actions=ci Jira+staging; no bots) | +| Open/resolved split | 🟒 corroborated | 11 | 2026-07-23 | #3510, #3374, #3536 (0 resolved/2 open), #3542 (3 resolved/1 open), #3543, #3573 (r1/r2 mixed), #2531 (11 open / 3 resolved), #3585 (r1 2 open/0 res; r2 3 open/2 resolved), #3604 (r1 0 res/2 open; r2 0 res/4 open; r3 2 res/3 open), #3612 (0 res/4 open), #3627 (0 res/1 open), #3687 (9 open/0 resolved β€” inferred from context, GraphQL unavailable) | | Fix-quality spot-check (genuinely fixed vs silenced) | 🟒 corroborated | 8 | 2026-07-10 | #3510 (term removals landed), #3374 (`num_docs`, dropIndex landed), #3542 (xargs+guard, narrowed exclude, SHA pin landed), #3573 (relpath + `--add` dedup landed), #2531 (r1 found decimal thread 2619563419 reverted; r2 doc fixes landed + engineer ZdravkoDonev **APPROVED**), #3585 r2 (both r1 findings genuinely fixed β€” byId multimap + isError wrapping present in code, not silenced); #3604 r3 (reactive race 3544441638 resolved+outdated by 6735cf9cc β€” sequential `.then()` chain present + harness PASS; smismember 3545172677 resolved-not-outdated, genuinely fixed in client sources not the anchored sets.md line); #3612 (r1's 3 doc-consistency fixes + r2 commit-gap all resolved; r2 3558314964 resolved+**outdated** by 7044aefc1 β€” consolidation genuinely present in Step 5, not silenced; **structural de-dup confirmed**: bugbot re-scan of the collapsed manifest Β§5 (`03ec1e1f5`) raised nothing on it β€” the copy-drift class is genuinely closed, not merely silenced) | | "Resolved β‰  fixed" flag β€” **legitimate deferral** variant | 🟑 seen once | 1 | 2026-06-23 | #3510 (TS.BGET:122 left pending eng) | | "Resolved β‰  fixed" flag β€” **still-broken / reverted** variant | 🟑 seen once | 1 | 2026-06-30 | #2531 (resolved+outdated thread 2619563419 said decimal default=`string`; a later rewrite reverted current code to `precise`, so the resolved fix is no longer in the code β€” engineer re-raised it as 3496835587). Regression flavour; see worked examples | @@ -39,7 +39,7 @@ whether to commit the change. | **Contradiction** detection | 🟒 corroborated | 4 | 2026-07-15 | #3415 (approval vs open bugbot finding); #2531 (RDI engineer's repo ground truth contradicts the page's Debezium-docs claims on β‰₯4 points β€” version, decimal default, temporal pass-through, MariaDB connector β€” **and** engineer-vs-existing-doc on temporal normalization); #3612 (**new flavour: internal doc-vs-doc within one PR's own files** β€” bugbot 3558223727: `park-manifest.md` "On pickup, then" drops labels *before* `/reflect`+`/finalize` while `pickup` Step 5 drops them *after*; `/park` copies the manifest into every PR body so the guard could lift early); #3627 (**new flavour: tool-finding vs verified-harness-reality + author design-intent** β€” bugbot 3587084676 "auth2 needs missing ACL user" claims the AUTH examples "break on the same environment the harness uses elsewhere"; verified `build/example-test-harness/run.sh` has **zero** `cmds_cnxmgmt` entries so the harness never runs them, and they are illustrative-by-design [matching the pre-existing shipped redis_py/node auth examples using the same `temp_pass`/`test-user` creds]. bugbot flagged only auth2 though auth1 has the identical property β€” a tell it's about call-shape not a runtime contract). *(#3507 was an off-branch manual demo β€” not counted.)* | | **Ping-pong loop** detection | ❓ untested | 0 | 2026-07-09 | still no true tool A↔B loop across #3536 (4 rounds), #3542 (r2 "empty-scope"), #3573 (r1 fixed point; r2 independent), #2531, #3585, or #3604 (r2: SMISMEMBER finding fixed by 9bf49b2f4 with no re-flag; node-dep FP independent; r3: new `Double.MIN_VALUE` finding in `SortedSetExample.java`, a file *untouched* by the 6735cf9cc push that triggered the re-scan β€” new-independent-in-different-file, textbook normal iteration). #3542/#3573/#3585 were churn not loops; #3585 r2 was the closest yet (the r1 fix *caused* r2's findings) but still not a loop β€” new independent findings + no fix undone, no A↔B cycle. #2531's nearest was the decimal regression (resolved β†’ reverted by a rewrite β†’ re-raised), a regression not a cycle. #3627 (r1) had a single bugbot finding on the PR's first review β€” no prior fix to undo, so no loop possible | | **Subsystem churn** detection (repeated findings on one patched area) | 🟒 corroborated | 5 PRs | 2026-07-10 | 5 distinct PRs. #3536 β€” 3 instances (review-handling / churn-feature / cap↔report contract). #3542 β€” 2 instances on the extraction *fail-loud-on-empty* contract. #3573 β€” 2 instances on the `--add` virtual-merge mechanism. #3585 β€” get_page/search **resolution** subsystem: r1 fix (dup-id β†’ byId multimap + matchByUrlSuffix + ambiguous-url early-return) directly caused 2 of r2's 3 findings (suffix path-boundary High, url-blocks-id-fallback) plus adjacent version-default gap. Cleanest "fix-caused-its-own-next-round" churn yet. #3612 β€” pickup **closing sequence** (Step 4β†’5), **3 rounds**: r1 label-drop ordering (3558223727) + r2 commit-before-reflect High (3558314964) + r3 push-before-merge High (3558614316). The r2 "consolidation" (explicit ordered commitβ†’reflectβ†’finalizeβ†’drop-labels) was **scoped too narrowly** β€” it threaded *commit* but not the full localβ†’remoteβ†’squash dependency, so r3 landed on that very commit. 2nd PR to show the #3536-r6 "consolidation boundary too narrow" meta-pattern. Worked examples below | -| Approval-over-open-finding cross-check | 🟒 corroborated | 8 | 2026-07-15 | #3415 (dwdougherty), #3374 (low-confidence over open HIGH), #3536 (high-confidence over 2 open Mediums: benign), #3542 (paoloredis "yep go ahead" 7 min after open Medium #3498159511; unacknowledged), #3573 (dwdougherty "Sure, why not?" APPROVED 13:41 over open findings; 2 bot findings landed 13:49 after), #2531 (run1 correct **negative** β€” no approval; run2 **positive** β€” ZdravkoDonev APPROVED 13:13 then bugbot finding 3499796857 landed 15:08, and he approved over 2-3 of his own still-open findings incl. the temporal one), #3585 (correct **negative** both rounds β€” open bugbot findings, only bot COMMENTED verdicts, no human approval); #3604 (correct **negative** all 3 rounds β€” r3 3 open bugbot findings, only cursor COMMENTED verdicts, no human approval); #3612 (correct **negative** β€” 4 open bugbot findings, only cursor COMMENTED verdict, no human approval); #3627 (correct **negative** β€” 1 open bugbot finding, only cursor COMMENTED verdict, no human approval) | +| Approval-over-open-finding cross-check | 🟒 corroborated | 9 | 2026-07-23 | #3415 (dwdougherty), #3374 (low-confidence over open HIGH), #3536 (high-confidence over 2 open Mediums: benign), #3542 (paoloredis "yep go ahead" 7 min after open Medium #3498159511; unacknowledged), #3573 (dwdougherty "Sure, why not?" APPROVED 13:41 over open findings; 2 bot findings landed 13:49 after), #2531 (run1 correct **negative** β€” no approval; run2 **positive** β€” ZdravkoDonev APPROVED 13:13 then bugbot finding 3499796857 landed 15:08, and he approved over 2-3 of his own still-open findings incl. the temporal one), #3585 (correct **negative** both rounds β€” open bugbot findings, only bot COMMENTED verdicts, no human approval); #3604 (correct **negative** all 3 rounds β€” r3 3 open bugbot findings, only cursor COMMENTED verdicts, no human approval); #3612 (correct **negative** β€” 4 open bugbot findings, only cursor COMMENTED verdict, no human approval); #3627 (correct **negative** β€” 1 open bugbot finding, only cursor COMMENTED verdict, no human approval); #3687 (correct **negative** β€” CHANGES_REQUESTED only, no human approval over open findings) | | Depth cap / prioritisation under load | 🟒 corroborated | 2 | 2026-07-02 | #3374 (19 candidate findings β†’ 4 deep-verified); #2531 (r1: 14 threads β†’ 5 deep-verified, 6 deferred). *(#3542/#3573 were under cap β€” not load tests)* | | Mandatory deep-verify of resolved+not-outdated HIGH | 🟒 corroborated | 2 | 2026-07-02 | #3542 #3467309496 (High "Grep failure skips link check", resolved + isOutdated:false) β€” deep-verified: xargs+guard genuinely present, legitimately fixed. #3585 #3513924736 (High "Duplicate page IDs break get_page", resolved + isOutdated:false) β€” deep-verified against current code: byId multimap + url-first resolution present, genuinely fixed. 2nd distinct PR β†’ corroborated | | Bot calibration (fixed-vs-dismissed ratio) | 🟒 corroborated | 9 | 2026-07-15 | #3374 (bugbot mostly accepted); #3536 (5/5 valid); #3542 (3/3 valid β€” 2 fixed, 1 open); #3543 (1/1 valid; Jit 0); #3573 (4/4 valid; Jit 0); #2531 (r1 bugbot 0 findings; r2 bugbot 1/1 valid β€” caught the ledger duplicate-rows defect 3499796857; Jit 0); #3585 (bugbot **5/5 valid** across 2 rounds); #3604 (across 3 rounds **3 valid / 2 FP**: valid = reactive `Mono.when` race 3544441638 + SMISMEMBER client-tab parity 3545172677 [fixed by 9bf49b2f4] + `Double.MIN_VALUE`β‰ βˆ’βˆž range bug 3550287458 [r3, a language-semantics catch]; FP = async `allOf` 3544581411 + node harness `@redis/time-series` "missing dep" 3545172685. **Calibration axis**: bugbot is strong on API/language semantics [`Double.MIN_VALUE` is smallest-positive] but both FPs mis-model runtime dependency/ordering it can't see from the diff [async fire-on-call; npm transitive hoisting]. Also found 2 of 3 identical `Double.MIN_VALUE` instances β€” correctly skipped the jedis one, pre-existing on main / outside the PR diff); #3612 (**8 valid / 1 FP across the review cycle** [r7 added 3559171169 rebase-force-lease + 3559171157 scan-mode-stop-rule, both pickup] β€” r1 valid = internal doc-vs-doc label-order contradiction 3558223727 + scan-mode wrong-step-ref 3558223733 + park update-path-only-shows-`gh pr create` 3558223738; r2 valid = commit-before-reflect High 3558314964; r3 valid = push-before-merge High 3558614316; r5 valid = manifest-omits-rebase 3558867168 [manifest copy-drift]; r6 valid = rebase-before-commit 3558994646 [pickup git-op ordering]; FP = r1 High "`merged` field doesn't exist" 3558223722, refuted empirically β€” single-PR REST endpoint returns top-level `merged`. **Calibration axis holds**: all 8 valid catches are cross-file doc-consistency / procedure-completeness / git-correctness [bugbot's strength], and it effectively ran the churn detection one seam per round across 7 rounds; the 1 FP is again an **unseen API mechanic** [list-endpoint vs single-PR-endpoint response shape] β€” same root as #3604's async/npm FPs); #3627 (**0 valid / 1 FP-on-impact**: bugbot 3587084676 correct on the literal [`AUTH test-user` errors on a bare Redis] but wrong on impact [claimed the harness runs these; it does not β€” no `cmds_cnxmgmt` in run.sh]. **Same calibration axis**: bugbot mis-models the runtime/environment it can't see from the diff β€” here that the auth set is illustrative-only and unwired from the harness, exactly the async/npm/endpoint-shape blind spot from #3604/#3612) | diff --git a/content/operate/rc/databases/configuration/clustering.md b/content/operate/rc/databases/configuration/clustering.md index c7476cff63..83ed940cc3 100644 --- a/content/operate/rc/databases/configuration/clustering.md +++ b/content/operate/rc/databases/configuration/clustering.md @@ -100,7 +100,7 @@ The Redis hashing policy is identical to the [hashing policy used by Redis Open - Your application does not use hashtags in database key names. - Your application uses binary data as key names. -The Redis hashing policy allows for [faster scaling](#smooth-scaling) where available. +The Redis hashing policy allows for [Smooth Scaling](#smooth-scaling) where available. ### Standard hashing policy @@ -192,29 +192,26 @@ The OSS Cluster API is only supported on Redis Cloud Pro databases. You can enab After you select OSS Cluster API, you can select **Use external endpoint** if you want to use the external endpoint for the database. Selecting **Use external endpoint** will block the private endpoint for this database. -The OSS Cluster API is supported only when a database uses the [standard hashing policy](#standard-hashing-policy). +The OSS Cluster API is supported when a database uses the [standard hashing policy](#standard-hashing-policy) or the [Redis hashing policy](#redis-hashing-policy). Review [OSS Cluster API architecture]({{< relref "/operate/rs/clusters/optimize/oss-cluster-api" >}}) to determine if you should enable this feature for your database. ## Smooth scaling {#smooth-scaling} -Smooth scaling is an improved resharding method for Redis Cloud Pro databases. Compared to legacy resharding, it is significantly faster, reduces latency spikes and disconnects during scaling, and supports scaling down (decreasing shard count). Legacy resharding always doubles the shard count and does not support scale-down. +Smooth scaling is an improved resharding method for Redis Cloud Pro databases. Compared to traditional resharding, it is significantly faster and reduces latency spikes and disconnects during scaling. {{< note >}} -Smooth scaling is only available for new databases. Existing databases continue to use legacy resharding. +Smooth scaling is available for databases that meet the following prerequisites. Other databases continue to use traditional scaling. {{< /note >}} ### Prerequisites -All of the following conditions must be met to use smooth scaling: +Smooth scaling is used automatically when a database meets all of the following conditions: | Requirement | Detail | |---|---| -| New database | Smooth scaling cannot be enabled on an existing database. | -| Hashing policy | Must use the [Redis hashing policy](#redis-hashing-policy). Standard and Custom hashing policies are not supported. | +| Hashing policy | Must use the [Redis hashing policy](#redis-hashing-policy). Databases using the Standard or Custom hashing policy use traditional scaling instead. | | Database version | Redis 8.4 or later. | -| Cluster version | Redis Cloud cluster version 8.0.18 or later. | -| High availability | HA must be enabled. Without HA, a database restart during scaling risks data loss. | ### Not supported @@ -226,11 +223,4 @@ Smooth scaling is not available for: ### Backward compatibility -Enabling smooth scaling puts shards into cluster mode, which enforces the same-slot requirement for multi-key commands. For most new databases this is safe to enable immediately, but there are cases where you should wait: - -| Database configuration | Recommendation | -|---|---| -| Created with multiple shards | Safe to enable immediately. | -| Created with OSS Cluster API enabled | Safe to enable immediately. | -| Created with a single shard | Wait until after the first scale operation before enabling, to ensure slot-aware behavior is introduced gradually. | -| HA disabled | Do not enable until HA is turned on. | \ No newline at end of file +You do not need to make any changes to your application code. The changes related to smooth scaling are implemented internally and do not affect RESP commands or how clients connect to and communicate with the database. \ No newline at end of file