Skip to main content 首页 创作者 jeremylongshore claude-code-plugins-plus-skills vercel-reliability-patterns
vercel-reliability-patterns Implement reliability patterns for Vercel deployments including circuit breakers, retry logic, and graceful degradation.
Use when building fault-tolerant serverless functions, implementing retry strategies,
or adding resilience to production Vercel services.
Trigger with phrases like "vercel reliability", "vercel circuit breaker",
"vercel resilience", "vercel fallback", "vercel graceful degradation".
跳到安装 Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/jeremylongshore/claude-code-plugins-plus-skills --skill vercel-reliability-patterns命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... 同仓库更多 Skills Implement user sign-up and sign-in flows with Clerk.
Use when building authentication UI, customizing sign-in experience,
or implementing OAuth social login.
Trigger with phrases like "clerk sign-in", "clerk sign-up",
"clerk login flow", "clerk OAuth", "clerk social login".
Implement session management and middleware with Clerk.
Use when managing user sessions, configuring route protection,
or implementing token refresh and custom JWT templates.
Trigger with phrases like "clerk session", "clerk middleware",
"clerk route protection", "clerk token", "clerk JWT".
Configure enterprise SSO, role-based access control, and organization management.
Use when implementing SSO integration, configuring role-based permissions,
or setting up organization-level controls.
Trigger with phrases like "clerk SSO", "clerk RBAC",
"clerk enterprise", "clerk roles", "clerk permissions", "clerk organizations".
jeremylongshore
jeremylongshore/claude-code-plugins-plus-skills
打开 GitHub 仓库 name vercel-reliability-patterns description Implement reliability patterns for Vercel deployments including circuit breakers, retry logic, and graceful degradation.
Use when building fault-tolerant serverless functions, implementing retry strategies,
or adding resilience to production Vercel services.
Trigger with phrases like "vercel reliability", "vercel circuit breaker",
"vercel resilience", "vercel fallback", "vercel graceful degradation".
allowed-tools Read, Write, Edit version 1.18.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","vercel","reliability","resilience","patterns"] compatibility Designed for Claude Code, also compatible with Codex and OpenClaw
Vercel Reliability Patterns
Overview
Build fault-tolerant Vercel deployments with circuit breakers, retry logic, graceful degradation, and instant rollback integration. Addresses reliability at two levels: function-level resilience (protecting against dependency failures) and deployment-level resilience (protecting against bad deploys).
Prerequisites
Vercel project deployed to production
Understanding of failure modes in serverless
External dependencies (databases, APIs) identified
Instructions
Step 1: Circuit Breaker for External Dependencies
type CircuitState = 'CLOSED' | 'OPEN' | 'HALF_OPEN' ;
class CircuitBreaker {
private state : CircuitState = 'CLOSED' ;
private failures = 0 ;
private lastFailure = 0 ;
private readonly threshold : number ;
private readonly resetTimeMs : number ;
constructor (threshold = 5 , resetTimeMs = 30000 ) {
this .threshold = threshold;
this .resetTimeMs = resetTimeMs;
}
async call<T>(fn : () => Promise <T>, fallback : () => T): Promise <T> {
if ( . === ) {
( . () - . > . ) {
. = ;
} {
. ( );
();
}
}
{
result = ();
. ();
result;
} (error) {
. ();
. ( , error);
();
}
}
(): {
. = ;
. = ;
}
(): {
. ++;
. = . ();
( . >= . ) {
. = ;
. ( );
}
}
}
dbCircuit = ( , );
( ) {
users = dbCircuit. (
db. . ({ : }),
[]
);
res. ({ users, : users. === });
}
this
state
'OPEN'
if
Date
now
this
lastFailure
this
resetTimeMs
this
state
'HALF_OPEN'
else
console
warn
'Circuit OPEN — returning fallback'
return
fallback
try
const
await
fn
this
onSuccess
return
catch
this
onFailure
console
error
'Circuit breaker caught error:'
return
fallback
private
onSuccess
void
this
failures
0
this
state
'CLOSED'
private
onFailure
void
this
failures
this
lastFailure
Date
now
if
this
failures
this
threshold
this
state
'OPEN'
console
warn
`Circuit OPENED after ${this .failures} failures`
const
new
CircuitBreaker
3
30000
export
default
async
function
handler
req, res
const
await
call
() =>
user
findMany
take
10
() =>
json
degraded
length
0
Important for serverless: Circuit breaker state lives in a single function instance. Different instances have independent circuits. For global circuit state, use Vercel KV or Edge Config.
Step 2: Retry with Exponential Backoff
interface RetryOptions {
maxRetries ?: number ;
baseDelayMs ?: number ;
maxDelayMs ?: number ;
retryOn ?: (error : unknown ) => boolean ;
}
async function withRetry<T>(
fn : () => Promise <T>,
options : RetryOptions = {}
): Promise <T> {
const { maxRetries = 3 , baseDelayMs = 200 , maxDelayMs = 5000 , retryOn } = options;
for (let attempt = 0 ; attempt <= maxRetries; attempt++) {
try {
return await fn ();
} catch (error) {
if (attempt === maxRetries) throw error;
if (retryOn && !retryOn (error)) throw error;
const delay = Math .min (
baseDelayMs * Math .pow (2 , attempt) + Math .random () * 200 ,
maxDelayMs
);
await new Promise (r => setTimeout (r, delay));
}
}
throw new Error ('Unreachable' );
}
const data = await withRetry (
() => fetch ('https://api.example.com/data' ).then (r => {
if (!r.ok ) throw new Error (`HTTP ${r.status} ` );
return r.json ();
}),
{
maxRetries : 3 ,
retryOn : (err ) => {
if (err instanceof TypeError ) return true ;
return err.message ?.includes ('5' );
},
}
);
Step 3: Graceful Degradation with Stale Cache
import { get, set } from '@vercel/kv' ;
export default async function handler (req, res ) {
const cacheKey = 'products:latest' ;
try {
const freshData = await fetchProductsFromDB ();
await set (cacheKey, JSON .stringify (freshData), { ex : 3600 });
res.setHeader ('x-data-source' , 'live' );
res.json (freshData);
} catch (error) {
const cachedData = await get (cacheKey);
if (cachedData) {
console .warn ('Serving stale cache — primary source unavailable' );
res.setHeader ('x-data-source' , 'cache-stale' );
res.json (JSON .parse (cachedData as string ));
} else {
res.setHeader ('x-data-source' , 'degraded' );
res.status (503 ).json ({
error : 'Service temporarily unavailable' ,
degraded : true ,
});
}
}
}
Step 4: Idempotency Keys for Mutations
import { NextRequest , NextResponse } from 'next/server' ;
import { db } from '@/lib/db' ;
export async function POST (request : NextRequest ) {
const idempotencyKey = request.headers .get ('idempotency-key' );
if (!idempotencyKey) {
return NextResponse .json (
{ error : 'idempotency-key header required' },
{ status : 400 }
);
}
const existing = await db.idempotencyRecord .findUnique ({
where : { key : idempotencyKey },
});
if (existing) {
return NextResponse .json (JSON .parse (existing.responseBody ), {
status : existing.responseStatus ,
headers : { 'x-idempotent-replay' : 'true' },
});
}
const body = await request.json ();
const order = await db.order .create ({ data : body });
const responseBody = JSON .stringify ({ order });
await db.idempotencyRecord .create ({
data : { key : idempotencyKey, responseStatus : 201 , responseBody },
});
return NextResponse .json ({ order }, { status : 201 });
}
Step 5: Health Check with Dependency Status
export const dynamic = 'force-dynamic' ;
interface HealthCheck {
name : string ;
check : () => Promise <boolean >;
}
const checks : HealthCheck [] = [
{
name : 'database' ,
check : async () => {
await db.$queryRaw `SELECT 1` ;
return true ;
},
},
{
name : 'cache' ,
check : async () => {
await kv.ping ();
return true ;
},
},
{
name : 'external-api' ,
check : async () => {
const r = await fetch ('https://api.example.com/health' , { signal : AbortSignal .timeout (3000 ) });
return r.ok ;
},
},
];
export async function GET ( ) {
const results : Record <string , 'ok' | 'error' > = {};
await Promise .all (
checks.map (async ({ name, check }) => {
try {
await check ();
results[name] = 'ok' ;
} catch {
results[name] = 'error' ;
}
})
);
const healthy = Object .values (results).every (v => v === 'ok' );
return Response .json (
{ status : healthy ? 'healthy' : 'degraded' , checks : results },
{ status : healthy ? 200 : 503 }
);
}
Step 6: Deployment-Level Resilience
DEPLOY_URL=$(vercel --prod)
HEALTH=$(curl -s -o /dev/null -w "%{http_code}" "$DEPLOY_URL /api/health" )
if [ "$HEALTH " != "200" ]; then
echo "Health check failed ($HEALTH ) — rolling back"
vercel rollback
exit 1
fi
echo "Deployment healthy"
Reliability Patterns Summary Pattern Protects Against Vercel Implementation Circuit breaker Dependency degradation In-function state or Edge Config Retry + backoff Transient failures withRetry wrapper Stale cache Primary source outage Vercel KV with TTL Idempotency Duplicate mutations Database record per request Health checks Bad deployments /api/health + rollback automationInstant rollback Deployment regression vercel rollback in CI
Output
Circuit breaker protecting all external dependency calls
Retry logic with exponential backoff for transient failures
Graceful degradation serving stale data when primary fails
Idempotency preventing duplicate mutations
Automated health check + rollback pipeline
Error Handling Error Cause Solution Circuit opens too aggressively Threshold too low Increase failure threshold (e.g., 5 → 10) Retry causes duplicate side effects No idempotency Add idempotency-key to mutation endpoints Stale cache expired TTL too short or never populated Increase TTL, seed cache on deploy Health check false positive Timeout too short Increase AbortSignal timeout to 5s Rollback reverts good deployment Flaky health check Add retry to health check before rollback
Resources
Next Steps For policy guardrails, see vercel-policy-guardrails.