EventBridge to Lambda concurrency limits for interaction events

Getting 429 Too Many Requests errors when our Lambda function processes high-volume interaction events from Genesys Cloud EventBridge. The function times out trying to batch insert into DynamoDB, causing the concurrency limit to hit hard during peak hours. Is there a specific configuration or batching strategy we’re missing to handle this volume without scaling Lambda indefinitely?

You’re hitting that 429 because EventBridge keeps retrying failed invocations and DynamoDB BatchWriteItem caps out at 25 items per call. Split the payload in your Lambda handler before hitting the DB. Also, check your Genesys Cloud event filter configuration. You don’t need every interaction.updated event firing.

Here’s a quick Node.js pattern that batches correctly and respects the DynamoDB limit:

const { DynamoDBClient, BatchWriteItemCommand } = require("@aws-sdk/client-dynamodb");
const client = new DynamoDBClient({ region: "us-east-1" });

exports.handler = async (event) => {
 const records = event.detail?.records || [];
 const chunks = [];
 for (let i = 0; i < records.length; i += 25) {
 chunks.push(records.slice(i, i + 25));
 }

 const requests = chunks.map(chunk => ({
 RequestItems: {
 "GenesysInteractions": chunk.map(r => ({
 PutRequest: { Item: { id: { S: r.id }, payload: { S: JSON.stringify(r) } } }
 }))
 }
 }));

 await Promise.all(requests.map(req => client.send(new BatchWriteItemCommand(req))));
 return { statusCode: 200 };
};

Set ReservedConcurrentExecutions to match your expected peak, but don’t crank it past what your DynamoDB table can handle. You can also tweak the MaximumBatchingWindowInSeconds on the EventBridge rule to group events naturally. If you’re still getting flooded, adjust the subscription filter in the Genesys Cloud API at /api/v2/analytics/eventstreams (requires analytics:query scope) to drop low-value events. The JS SDK handles retry logic automatically if you switch to the official PlatformClientV2 instead of raw HTTP calls.

The suggestion to filter events is spot on. From a gamification angle, missing data is the worst nightmare for keeping agent motivation high. If the Lambda drops interaction events, the contest scores drift and agents start complaining about unfair leaderboards. Has anyone else run into this kind of data gap before? I’m still learning the ropes and want to make sure we’re tracking everything correctly for the team.

A similar issue happened where the event stream overwhelmed the integration and the daily KPI dashboard showed zero activity for an hour. It caused a huge support ticket spike because agents were worried about their performance metrics and reward eligibility. Does the platform usually just throw a vague connection error when the stream gets too heavy, or is there a specific metric we should be monitoring? I’m trying to figure out the best way to prevent this from disrupting the HR reporting side of things.

Filtering to only the specific interaction events that trigger score updates helps a lot. You don’t need every status change hitting the function. Just the wrap-up events or the ones with disposition codes that matter for the contest rules. Slowing the pipe down keeps the scores accurate and stops the 429 errors from breaking the engagement program. How do you typically set up the event filters in the gamification console? I’m still pretty new to configuring these metrics and want to make sure I’m not accidentally hiding important data from the agent profiles.

Let’s break down why you’re seeing those 429 errors. Right now, EventBridge is sending every single interaction update straight into your Lambda queue. In Genesys Cloud, agents generate a lot of these updates just by toggling dispositions or adding quick notes. On the AWS side, each batch triggers a separate execution. Once you hit your account’s concurrency limit, AWS starts rejecting the extra requests. I like to think of it like trying to fill a bucket with a firehose attached to a garden hose—the pressure just overwhelms the system. I’ve actually seen a few community posts lately where teams ran into this exact bottleneck, so you’re definitely not alone.

First, tighten the filter inside Genesys Cloud. You really only need to catch the state changes that your downstream system actually uses. Navigate to Integrations then EventBridge then Filters. Change the eventType to interaction.updated, but add a condition so it only triggers when an interaction reaches the dispositioned or wrapped states. This simple tweak will cut down the incoming event volume by a significant amount.

On the Lambda side, group the payloads before they reach DynamoDB. DynamoDB has a hard limit of 25 items per batch write call, so we need to slice the incoming array into smaller pieces. Here is a straightforward pattern that handles the chunking without blocking the rest of your function:

const chunkSize = 25;
async function batchWrite(items, dynamoClient) {
 for (let i = 0; i < items.length; i += chunkSize) {
 const chunk = items.slice(i, i + chunkSize);
 const params = {
  RequestItems: {
   "YourTableName": chunk.map(item => ({
    PutRequest: { Item: item }
   }))
  }
 };
 await dynamoClient.batchWriteItem(params);
 }
}

Start by running the filter test in the Genesys Cloud admin portal. You should watch the event counter drop as it ignores the unnecessary updates. Once you confirm that, deploy the chunking logic to your Lambda function. You’ll likely see the concurrency graph flatten out almost right away.

Finally, check your reserved concurrency settings in the AWS console. By default, this often sits at zero, which AWS interprets as unlimited. During peak call volume, that unlimited setting is exactly what triggers the throttling. Set it to a fixed number, like 50 or 100. This creates a healthy backpressure that keeps your function stable instead of letting the queue spiral out of control.

2 Likes
{
 "name": "HighVol Interaction Filter",
 "filters": [
 {
 "eventType": "interaction.updated",
 "fields": [
 "status",
 "wrapupCode",
 "agent"
 ],
 "conditions": [
 {
 "field": "status",
 "operator": "neq",
 "value": "queued"
 }
 ]
 }
 ],
 "destination": {
 "type": "eventbridge",
 "configuration": {
 "eventBridgeArn": "arn:aws:events:us-east-1:123456789:event-bus/default"
 }
 }
}

genesyscloud-sdk submits this payload directly to POST /api/v2/events/eventbridges. The conditions array enforces source-side filtering. Drop the queued state updates. They fire continuously during hold states, don’t impact scoring, and waste throughput. This cuts Lambda invocations by 90% before AWS ingestion.

Route outbound data through the REST Proxy. Pair it with a SNIPPET action and a 100ms delay to batch the calls. Inbound EventBridge streams don’t batch cleanly, so the source filter is mandatory. Volume drops resolve the concurrency limit.

1 Like