mirror of
https://github.com/better-auth/better-auth.git
synced 2026-10-19 11:24:57 -05:00
docs: add background tasks (#8395)
This commit is contained in:
committed by
Maxwell
parent
11c3959e15
commit
d2fe0463eb
@@ -250,6 +250,52 @@ This may be useful to use instead of using your db directly to get access to `da
|
||||
|
||||
You can use `ctx.context.generateId` to generate Id for various reasons.
|
||||
|
||||
#### runInBackground
|
||||
|
||||
Schedules a task to run after the response is sent. Use for fire-and-forget operations (cleanup, analytics, rate limit counter updates). Configure the handler in [advanced.backgroundTasks](/docs/reference/options#backgroundtasks).
|
||||
|
||||
```ts title="auth.ts"
|
||||
import { betterAuth } from "better-auth";
|
||||
import { createAuthMiddleware } from "better-auth/api";
|
||||
|
||||
export const auth = betterAuth({
|
||||
hooks: {
|
||||
after: createAuthMiddleware(async (ctx) => {
|
||||
if (ctx.path.startsWith("/sign-up")) {
|
||||
const newSession = ctx.context.newSession;
|
||||
if (newSession) {
|
||||
ctx.context.runInBackground(sendAnalyticsEvent(newSession.user.id));
|
||||
}
|
||||
}
|
||||
}),
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### runInBackgroundOrAwait
|
||||
|
||||
Defers the task when a handler is configured, otherwise awaits it. Use for operations that must complete (e.g. sending emails) but benefit from not blocking when a handler exists. Configure the handler in [advanced.backgroundTasks](/docs/reference/options#backgroundtasks).
|
||||
|
||||
```ts title="auth.ts"
|
||||
import { betterAuth } from "better-auth";
|
||||
import { createAuthMiddleware } from "better-auth/api";
|
||||
|
||||
export const auth = betterAuth({
|
||||
hooks: {
|
||||
after: createAuthMiddleware(async (ctx) => {
|
||||
if (ctx.path.startsWith("/sign-up")) {
|
||||
const newSession = ctx.context.newSession;
|
||||
if (newSession) {
|
||||
await ctx.context.runInBackgroundOrAwait(
|
||||
sendWelcomeEmail(newSession.user)
|
||||
);
|
||||
}
|
||||
}
|
||||
}),
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Reusable Hooks
|
||||
|
||||
If you need to reuse a hook across multiple endpoints, consider creating a plugin. Learn more in the [Plugins Documentation](/docs/concepts/plugins).
|
||||
|
||||
@@ -121,6 +121,31 @@ Here are examples of how you can do caching in different frameworks and environm
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Background Tasks
|
||||
|
||||
On serverless platforms (Vercel, Cloudflare Workers), you can improve response times by deferring non-critical work—cleanup, analytics, rate limit updates, email sending—to run after the response is sent. Configure [`advanced.backgroundTasks`](/docs/reference/options#backgroundtasks) and use `ctx.context.runInBackground` or `ctx.context.runInBackgroundOrAwait` in hooks.
|
||||
|
||||
```ts title="auth.ts"
|
||||
import { betterAuth } from "better-auth";
|
||||
import { createAuthMiddleware } from "better-auth/api";
|
||||
import { waitUntil } from "@vercel/functions";
|
||||
|
||||
export const auth = betterAuth({
|
||||
advanced: {
|
||||
backgroundTasks: { handler: waitUntil },
|
||||
},
|
||||
hooks: {
|
||||
after: createAuthMiddleware(async (ctx) => {
|
||||
if (ctx.path === "/sign-up/email") {
|
||||
ctx.context.runInBackground(logSignUp(ctx.context.newSession?.user.id));
|
||||
}
|
||||
}),
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
See the [Context documentation](/docs/concepts/hooks#runinbackground) for more examples.
|
||||
|
||||
## SSR Optimizations
|
||||
|
||||
If you're using a framework that supports server-side rendering, it's usually best to pre-fetch the user session on the server and use it as a fallback on the client.
|
||||
|
||||
@@ -585,6 +585,9 @@ export const auth = betterAuth({
|
||||
defaultFindManyLimit: 100,
|
||||
experimentalJoins: false,
|
||||
},
|
||||
backgroundTasks: {
|
||||
handler: (promise) => { /* e.g. waitUntil(promise) */ }
|
||||
},
|
||||
skipTrailingSlashes: true
|
||||
},
|
||||
})
|
||||
@@ -599,9 +602,55 @@ export const auth = betterAuth({
|
||||
- `defaultCookieAttributes`: Default attributes for all cookies
|
||||
- `cookiePrefix`: Prefix for cookies
|
||||
- `database`: Database configuration options
|
||||
- `backgroundTasks`: Configure background task handling for deferred operations
|
||||
- `skipTrailingSlashes`: Skip trailing slash validation in route matching. (default: `false`)
|
||||
- OAuth state configuration options (`storeStateStrategy`, `skipStateCookieCheck`) are now part of the `account` option
|
||||
|
||||
### `backgroundTasks`
|
||||
|
||||
Configure background task handling for deferred operations. Background tasks allow non-critical operations (like cleanup, analytics, timing-attack mitigation, or rate limit counter updates) to run after the response is sent. This can significantly improve response times on serverless platforms.
|
||||
|
||||
Some examples are: `waitUntil` from `@vercel/functions` on Vercel, or `ctx.waitUntil` on Cloudflare Workers. See the examples below for more details.
|
||||
|
||||
<Callout type="warn">
|
||||
Enabling this introduces eventual consistency where the response returns optimistic data before the database is updated. Only enable if your application can tolerate this trade-off for improved latency.
|
||||
</Callout>
|
||||
|
||||
<Tabs items={["Vercel", "Cloudflare Workers"]}>
|
||||
<Tab value="Vercel">
|
||||
```ts
|
||||
import { betterAuth } from "better-auth";
|
||||
import { waitUntil } from "@vercel/functions";
|
||||
|
||||
export const auth = betterAuth({
|
||||
advanced: {
|
||||
backgroundTasks: {
|
||||
handler: waitUntil,
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
</Tab>
|
||||
<Tab value="Cloudflare Workers">
|
||||
```ts
|
||||
import { betterAuth } from "better-auth";
|
||||
import { AsyncLocalStorage } from "node:async_hooks";
|
||||
|
||||
const execCtxStorage = new AsyncLocalStorage<ExecutionContext>();
|
||||
|
||||
export const auth = betterAuth({
|
||||
advanced: {
|
||||
backgroundTasks: {
|
||||
handler: (p) => execCtxStorage.getStore()?.waitUntil(p),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// In your request handler, wrap with execCtxStorage.run(ctx, ...)
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## `logger`
|
||||
|
||||
Logger configuration for Better Auth.
|
||||
|
||||
Reference in New Issue
Block a user