Stripe Thin Events: Best Practices Guide
Stripe uses a thin events pattern where webhook payloads contain minimal information—just an event ID and type. Your system must fetch the complete event data from Stripe's API to access the full resource details.
This guide shows you how to implement Stripe's thin events pattern using Hookdeck's Event Gateway to avoid API rate limits and handle events reliably at scale. For a detailed explanation of thin events concepts and patterns, see Handling Thin Events with Hookdeck.
The Core Challenge: Stripe's API Rate Limiting
Stripe enforces API rate limits to ensure platform stability. For most read operations, including event retrieval, Stripe allows 100 requests per second in live mode. The primary operational challenge with Stripe's thin events is that every webhook triggers an API call to fetch the full event object using stripe.events.retrieve().
When you receive hundreds or thousands of Stripe webhooks during peak periods—such as a product launch, subscription renewal cycle, or flash sale—your downstream service can easily exceed Stripe's 100 requests/second limit, resulting in 429 Too Many Requests errors and failed event processing.
Hookdeck's solution: The Event Gateway acts as a durable queue that decouples webhook ingestion from processing. By setting a Max Delivery Rate on your Destination , you control how quickly events are delivered to your application, which directly controls how quickly your handlers fetch event data from Stripe's API.
Configuring Rate Limiting for Stripe's API
Set your Hookdeck max delivery rate to 90 events per second—safely below Stripe's 100 requests/second limit while leaving headroom for other API operations.
Quick setup: In your Hookdeck Connection settings, set Rate Limit to 90 per second on the destination that receives Stripe webhooks. See the rate limiting guide for detailed configuration steps.
Implementation Pattern with Stripe SDK
With rate limiting in place, your webhook handler can use a straightforward synchronous pattern to fetch and process Stripe events:
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
async function handleStripeWebhook(request) {
const thinEvent = request.body;
// Safe to fetch synchronously - Hookdeck Event Gateway controls delivery rate
const fullEvent = await stripe.events.retrieve(thinEvent.id);
// Access the complete resource data
const eventType = fullEvent.type;
const resource = fullEvent.data.object;
// Process based on event type
switch (eventType) {
case 'customer.subscription.updated':
await handleSubscriptionUpdate(resource);
break;
case 'invoice.payment_succeeded':
await handleSuccessfulPayment(resource);
break;
case 'charge.refunded':
await handleRefund(resource);
break;
default:
console.log(`Unhandled event type: ${eventType}`);
}
return { status: 200 };
}
async function handleSubscriptionUpdate(subscription) {
// Process the complete subscription object
console.log(`Subscription ${subscription.id} updated`);
console.log(`Status: ${subscription.status}`);
console.log(`Current period end: ${new Date(subscription.current_period_end * 1000)}`);
// Update your database with the latest state
await database.subscriptions.upsert({
stripe_subscription_id: subscription.id,
customer_id: subscription.customer,
status: subscription.status,
current_period_end: subscription.current_period_end,
items: subscription.items.data
});
}
Because the Event Gateway acts as the queue and controls the delivery rate, you don't need to build queueing or batching logic in your application. It handles backpressure for you—events that arrive faster than your configured rate are automatically queued and delivered at a steady pace, preventing Stripe API rate limit errors.
Deduplication Strategies for Stripe Events
Stripe can send duplicate or retry events, especially during network issues or endpoint downtime. Use Deduplication to prevent unnecessary stripe.events.retrieve() calls.
Deduplication Example: Stripe Event IDs
The most effective deduplication strategy for Stripe is to use the event ID as the deduplication key. Stripe guarantees that each event has a unique ID (e.g., evt_1A2B3C4D5E6F7G8H), so this ensures you only process each distinct event once.
Configuration:
{
"type": "deduplicate",
"window": 300000,
"include_fields": [
"body.id"
]
}
This configuration suppresses duplicate events with the same id within a 5-minute window. If Stripe retries sending the same event multiple times (which can happen during network issues or webhook endpoint failures), only the first one is delivered, saving unnecessary stripe.events.retrieve() calls.
Recommended deduplication rule for preventing retry duplicates:
{
"type": "deduplicate",
"window": 300000,
"include_fields": ["body.id"]
}
If Stripe retries the same event multiple times during temporary failures, only one delivery reaches your application. See the deduplication guide for advanced patterns.
Debugging Event Processing Failures
With rate limiting configured, Stripe API rate limit errors should not occur. When issues do arise—such as application errors during event processing or failed stripe.events.retrieve() calls due to temporary Stripe API outages—use Hookdeck's dashboard to debug and recover.
Check the Requests section only if Stripe is reporting delivery failures to Hookdeck itself (e.g., authentication misconfiguration on your Hookdeck source).
Check the Events section to view delivery attempts to your application and your handler's responses. For each failed event, you can:
- Review your handler's error response
- Examine the Stripe webhook payload that was delivered
- Click Retry to re-trigger delivery and the
stripe.events.retrieve()call after fixing the issue
For detailed guidance on observability and recovery, see the thin events guide observability section.
Next Steps
With rate limiting set to 90/sec and deduplication configured, your Stripe webhook handler can safely fetch events using stripe.events.retrieve() without hitting API limits.
Key takeaways for Stripe:
- Set max delivery rate to 90 events/second to stay under Stripe's 100 req/sec limit
- Deduplicate by event ID (
body.id) to prevent processing retried events - Use Hookdeck's dashboard to debug Stripe API errors and replay failed events
For additional patterns like transformations and advanced deduplication strategies, see the complete thin events guide.
Related Resources
- What Are Thin Events? - Understanding the thin events pattern
- Webhooks Fetch Before Process Pattern - Detailed implementation strategies
- Handling Thin Events with Hookdeck - Generic thin events guide
- Deduplication Implementation Guide - Advanced deduplication patterns
- Control Throughput and Queue Events - Detailed guide to rate limiting
- Stripe API Rate Limits - Official Stripe documentation
- Stripe Event Object - Understanding Stripe's thin event structure