[GH-ISSUE #7586] auth.api.updateUser triggers multiple session fetch/update cycles when KV is configured as secondary storage #10846

Closed
opened 2026-04-13 07:12:47 -05:00 by GiteaMirror · 3 comments
Owner

Originally created by @sabaturgay on GitHub (Jan 24, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/7586

Originally assigned to: @bytaesu on GitHub.

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

const { headers } = await auth.api.updateUser({
  body: {
    ...publicMetadata,
  },
  headers: c.req.raw.headers,
  returnHeaders: true,
})

Current vs. Expected behavior

When using Better Auth with KV configured as secondary storage, calling auth.api.updateUser results in multiple session-related operations occurring within a single request.

A single call to auth.api.updateUser produces the following sequence:

  1. User record is updated in the database
  2. Active sessions are fetched
  3. Individual session(s) are fetched
  4. Session(s) are updated and written to storage (KV)
  5. After this completes, the flow continues with:
    • another fetch of active sessions
    • another fetch of the same session(s)
    • another session write to KV

All of the above occurs during the same updateUser request lifecycle.

Impact

With Cloudflare KV as the secondary storage, this behavior causes runtime errors due to KV rate limits.

Cloudflare KV enforces a limit of 1 PUT per key per second. During api.updateUser, the repeated session write operations exceed this limit, resulting in errors such as:
KV PUT failed: 429 Too Many Requests

What version of Better Auth are you using?

1.4.4

System info

{
  "node": {
    "version": "v22.14.0",
    "env": "development"
  },
  "packageManager": {
    "name": "bun",
    "version": "1.3.2"
  },
  "frameworks": [
    {
      "name": "react",
      "version": "19.1.0"
    },
    {
      "name": "hono",
      "version": "4.11.4"
    }
  ],
  "databases": [
    {
      "name": "drizzle",
      "version": "0.45.1"
    }
  ],
  "betterAuth": {
    "version": "1.4.4",
    "config": null
  }
}

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
database: drizzleAdapter(orm.getDrizzleInstance(), {
			provider: 'sqlite',
			usePlural: true,
			camelCase: true,
		}),
		emailAndPassword: {
			enabled: true,
			requireEmailVerification: false,
			minPasswordLength: 8,
			maxPasswordLength: 128,
			autoSignIn: true,
		},
		secondaryStorage: kvStorage.auth,
		session: {
			expiresIn: 60 * 60 * 24 * 7, // 7 days
			updateAge: 60 * 60 * 24, // 1 day
			cookieCache: {
				enabled: true,
				// maxAge: 20, // 5 minutes
				maxAge: 5 * 60, // 5 minutes
			},
		},
		advanced: {
			useSecureCookies: true,
			cookiePrefix: BETTER_AUTH_COOKIE_PREFIX,
			crossSubDomainCookies: {
				enabled: false,
			},
			ipAddress: {
				ipAddressHeaders: ['cf-connecting-ip', 'x-real-ip'],
			},
		},
		plugins: [username(), admin(), expo({ disableOriginOverride: true })],
});

Additional context

No response

Originally created by @sabaturgay on GitHub (Jan 24, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/7586 Originally assigned to: @bytaesu on GitHub. ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce ```ts const { headers } = await auth.api.updateUser({ body: { ...publicMetadata, }, headers: c.req.raw.headers, returnHeaders: true, }) ``` ### Current vs. Expected behavior When using Better Auth with KV configured as secondary storage, calling `auth.api.updateUser` results in multiple session-related operations occurring within a single request. A single call to `auth.api.updateUser` produces the following sequence: 1. User record is updated in the database 2. Active sessions are fetched 3. Individual session(s) are fetched 4. Session(s) are updated and written to storage (KV) 5. After this completes, the flow continues with: - another fetch of active sessions - another fetch of the same session(s) - another session write to KV All of the above occurs during the same `updateUser` request lifecycle. ### Impact With **Cloudflare KV** as the secondary storage, this behavior causes runtime errors due to KV rate limits. Cloudflare KV enforces a limit of **1 PUT per key per second**. During `api.updateUser`, the repeated session write operations exceed this limit, resulting in errors such as: `KV PUT failed: 429 Too Many Requests` ### What version of Better Auth are you using? 1.4.4 ### System info ```bash { "node": { "version": "v22.14.0", "env": "development" }, "packageManager": { "name": "bun", "version": "1.3.2" }, "frameworks": [ { "name": "react", "version": "19.1.0" }, { "name": "hono", "version": "4.11.4" } ], "databases": [ { "name": "drizzle", "version": "0.45.1" } ], "betterAuth": { "version": "1.4.4", "config": null } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ database: drizzleAdapter(orm.getDrizzleInstance(), { provider: 'sqlite', usePlural: true, camelCase: true, }), emailAndPassword: { enabled: true, requireEmailVerification: false, minPasswordLength: 8, maxPasswordLength: 128, autoSignIn: true, }, secondaryStorage: kvStorage.auth, session: { expiresIn: 60 * 60 * 24 * 7, // 7 days updateAge: 60 * 60 * 24, // 1 day cookieCache: { enabled: true, // maxAge: 20, // 5 minutes maxAge: 5 * 60, // 5 minutes }, }, advanced: { useSecureCookies: true, cookiePrefix: BETTER_AUTH_COOKIE_PREFIX, crossSubDomainCookies: { enabled: false, }, ipAddress: { ipAddressHeaders: ['cf-connecting-ip', 'x-real-ip'], }, }, plugins: [username(), admin(), expo({ disableOriginOverride: true })], }); ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-13 07:12:47 -05:00
Author
Owner

@better-auth-agent[bot] commented on GitHub (Jan 24, 2026):

It seems you are experiencing an issue where calling auth.api.updateUser results in multiple session-related operations when using Cloudflare KV as the secondary storage, which leads to hitting KV rate limits. This is indeed a problem as it can trigger errors due to excessive requests to KV.

Currently, there is an open issue regarding this behavior as it seems to indicate that multiple session writes occur within the same updateUser request lifecycle, which is not expected [1].

To address this, consider the following troubleshooting steps:

  1. Review your usage of session handling: Ensure that the session lifecycle is not redundantly invoking multiple fetch and update cycles within a single request.
  2. Implement rate-limiting logic: If possible, add your own rate-limiting layer to manage how many requests are made to Cloudflare KV within a given timeframe.

If this issue persists or for more targeted assistance, I recommend tagging @bekacru or @ping__ in your follow-up message for their expertise.

What have you tried so far to resolve the issue? Would you like guidance on specific troubleshooting techniques?

If you need more help, tag @better-auth-agent in a comment so I can respond.

DiagramDiscordGitHub

Diagram Join Star

<!-- gh-comment-id:3793346158 --> @better-auth-agent[bot] commented on GitHub (Jan 24, 2026): It seems you are experiencing an issue where calling `auth.api.updateUser` results in multiple session-related operations when using Cloudflare KV as the secondary storage, which leads to hitting KV rate limits. This is indeed a problem as it can trigger errors due to excessive requests to KV. Currently, there is an open issue regarding this behavior as it seems to indicate that multiple session writes occur within the same `updateUser` request lifecycle, which is not expected [[1]](https://github.com/better-auth/better-auth/issues/5696). To address this, consider the following troubleshooting steps: 1. **Review your usage of session handling**: Ensure that the session lifecycle is not redundantly invoking multiple fetch and update cycles within a single request. 2. **Implement rate-limiting logic**: If possible, add your own rate-limiting layer to manage how many requests are made to Cloudflare KV within a given timeframe. If this issue persists or for more targeted assistance, I recommend tagging @bekacru or @ping__ in your follow-up message for their expertise. What have you tried so far to resolve the issue? Would you like guidance on specific troubleshooting techniques? _If you need more help, tag @better-auth-agent in a comment so I can respond._ <!-- bot:webhook reply v1 --> [Diagram](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) • [Discord](https://discord.gg/better-auth) • [GitHub](https://github.com/better-auth/better-auth) [![Diagram](https://img.shields.io/badge/Diagram-2b3137?style=flat-square)](https://repodiagrams.s3.eu-north-1.amazonaws.com/better-auth_ultra_detailed_interactive.html) [![Join](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&style=flat-square)](https://discord.gg/better-auth) [![Star](https://img.shields.io/badge/star-181717?logo=github&logoColor=white&style=flat-square)](https://github.com/better-auth/better-auth)
Author
Owner

@dosubot[bot] commented on GitHub (Jan 24, 2026):

This is a known architectural behavior in Better Auth when using KV (like Cloudflare KV) as secondary storage: a single updateUser call triggers multiple session fetch and write cycles because the user update logic calls refreshUserSessions, which iterates through all active sessions for the user and rewrites each session entry in KV with the updated user data. The session middleware and session cookie update logic can also trigger additional session fetches and writes within the same request. There is no built-in batching or debouncing for these writes, so multiple rapid KV PUTs can exceed Cloudflare's rate limit of 1 PUT per key per second, resulting in 429 errors. This is not unique to Cloudflare KV; similar issues have been reported with Redis and other secondary storage backends source.

Current documentation covers how sessions are managed with secondary storage and options like storeSessionInDatabase and preserveSessionInDatabase, but does not address batching or rate limit mitigation source. There are workarounds for TTL issues with Cloudflare KV (using rateLimit.customStorage), but no built-in solution for excessive session writes during user updates source.

If you need to avoid hitting KV rate limits, consider reducing the number of active sessions per user, increasing the interval between updates, or switching to a backend with higher write throughput. For immediate mitigation, you could implement custom logic to batch or debounce session writes, but this would require changes outside of Better Auth's current API.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

Chat with Dosu Open in Cursor Join Discord Share on X

<!-- gh-comment-id:3793365909 --> @dosubot[bot] commented on GitHub (Jan 24, 2026): <!-- Answer --> This is a known architectural behavior in Better Auth when using KV (like Cloudflare KV) as secondary storage: a single `updateUser` call triggers multiple session fetch and write cycles because the user update logic calls `refreshUserSessions`, which iterates through all active sessions for the user and rewrites each session entry in KV with the updated user data. The session middleware and session cookie update logic can also trigger additional session fetches and writes within the same request. There is no built-in batching or debouncing for these writes, so multiple rapid KV PUTs can exceed Cloudflare's rate limit of 1 PUT per key per second, resulting in 429 errors. This is not unique to Cloudflare KV; similar issues have been reported with Redis and other secondary storage backends [source](https://github.com/better-auth/better-auth/blob/d1602ef0ae9822e462a5a42497072a0a1756e804/packages/better-auth/src/db/internal-adapter.ts#L45-L871). Current documentation covers how sessions are managed with secondary storage and options like `storeSessionInDatabase` and `preserveSessionInDatabase`, but does not address batching or rate limit mitigation [source](https://github.com/better-auth/better-auth/pull/7168). There are workarounds for TTL issues with Cloudflare KV (using `rateLimit.customStorage`), but no built-in solution for excessive session writes during user updates [source](https://github.com/better-auth/better-auth/issues/7124). If you need to avoid hitting KV rate limits, consider reducing the number of active sessions per user, increasing the interval between updates, or switching to a backend with higher write throughput. For immediate mitigation, you could implement custom logic to batch or debounce session writes, but this would require changes outside of Better Auth's current API. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/d3f55745-9704-4497-858c-d45021266370?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/d3f55745-9704-4497-858c-d45021266370?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/d3f55745-9704-4497-858c-d45021266370?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/d3f55745-9704-4497-858c-d45021266370?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/d3f55745-9704-4497-858c-d45021266370?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/d3f55745-9704-4497-858c-d45021266370?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/d3f55745-9704-4497-858c-d45021266370?feedback_type=other)</sup> [![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=This%20is%20a%20known%20architectural%20behavior%20in%20Better%20Auth%20when%20using%20KV%20%28like%20Cloudflare%20KV%29%20as%20secondary%20storage%3A%20a%20single%20%60updateUser%60%20call%20triggers%20multiple%20session%20fetch%20and%20write%20cycles%20because%20the%20user%20update%20logic%20calls%20%60refreshUserSessions%60%2C%20which%20iterates%20through%20all%20active%20sessions%20for%20the%20user%20and%20rewrites%20each%20session%20entry%20in%20KV%20with%20the%20updated%20user%20data.%20The%20session%20middleware%20and%20session%20cookie%20update%20logic%20can%20also%20trigger%20additional%20session%20fetches%20and%20writes%20within%20the%20same%20request.%20There%20is%20no%20built-in%20batching%20or%20debouncing%20for%20these%20writes%2C%20so%20multiple%20rapid%20KV%20PUTs%20can%20exceed%20Cloudflare%27s%20rate%20limit%20of%201%20PUT%20per%20key%20per%20second%2C%20resulting%20in%20429%20errors.%20This%20is%20not%20unique%20to%20Cloudflare%20KV%3B%20similar%20issues%20have%20been%20reported%20with%20Redis%20and%20other%20secondary%20storage%20backends%20%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/blob/d1602ef0ae9822e462a5a42497072a0a1756e804/packages/better-auth/src/db/internal-adapter.ts%23L45-L871%29.%0A%0ACurrent%20documentation%20covers%20how%20sessions%20are%20managed%20with%20secondary%20storage%20and%20options%20like%20%60storeSessionInDatabase%60%20and%20%60preserveSessionInDatabase%60%2C%20but%20does%20not%20address%20batching%20or%20rate%20limit%20mitigation%20%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/pull/7168%29.%20There%20are%20workarounds%20for%20TTL%20issues%20with%20Cloudflare%20KV%20%28using%20%60rateLimit.customStorage%60%29%2C%20but%20no%20built-in%20solution%20for%20excessive%20session%20writes%20during%20user%20updates%20%5Bsource%5D%28https%3A//github.com/better-auth/better-auth/issues/7124%29.%0A%0AIf%20you%20need%20to%20avoid%20hitting%20KV%20rate%20limits%2C%20consider%20reducing%20the%20number%20of%20active%20sessions%20per%20user%2C%20increasing%20the%20interval%20between%20updates%2C%20or%20switching%20to%20a%20backend%20with%20higher%20write%20throughput.%20For%20immediate%20mitigation%2C%20you%20could%20implement%20custom%20logic%20to%20batch%20or%20debounce%20session%20writes%2C%20but%20this%20would%20require%20changes%20outside%20of%20Better%20Auth%27s%20current%20API.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/7586)
Author
Owner

@bytaesu commented on GitHub (Jan 24, 2026):

Hi @sabaturgay, I'm checking this!

<!-- gh-comment-id:3793689622 --> @bytaesu commented on GitHub (Jan 24, 2026): Hi @sabaturgay, I'm checking this!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#10846