- Newest
- Most votes
- Most comments
Your proposed architecture is a solid approach for distributing outbound campaign calls throughout the day based on percentage allocations. Since Amazon Connect Outbound Campaigns now supports hourly segment refresh (reduced from the previous 24-hour minimum), you can leverage this native capability as part of your solution, though your custom orchestration layer still provides valuable control for percentage-based throttling.
Here's how to optimize your approach:
Leverage Native Hourly Refresh: Configure your campaign to refresh segments hourly. This allows the campaign to pick up newly eligible customers throughout the day rather than in a single batch. However, this alone won't give you percentage-based distribution control.
Your Custom Throttling Layer: Your proposed architecture using DynamoDB tracking, EventBridge Scheduler, and a Release Lambda is the right approach for percentage-based distribution. The key elements work well:
- Using S3 event notifications to trigger ingestion eliminates polling overhead
- Tracking records in DynamoDB with a running total gives you the denominator for percentage calculations
- The hourly EventBridge Scheduler firing your Release Lambda provides the cadence for batch releases
- Capping each hour at 1.5x nominal share is a smart safeguard against late-arriving batches causing spikes
- Using PutOutboundRequestBatch in chunks of 25 is the correct API approach for submitting contacts programmatically
Important Considerations:
-
Campaign Quotas: Be aware of two critical limits - concurrent active calls and calls per second (CPS). Your percentage-based throttling helps, but monitor CloudWatch metrics like ThrottledCalls, CallsBreachingConcurrencyQuota, and ConcurrentCallsPercentage to ensure you're not hitting quota ceilings during peak hours.
-
Contact Priority: If certain contacts are more important, you can configure priority ordering based on up to 10 profile attributes. Initial dial attempts always take precedence over reattempts, maintaining your priority throughout execution.
-
Agentless Campaign Setup: Creating the campaign with no source and using PutOutboundRequestBatch is correct for your event-driven model. You can pass attributes directly with each batch submission.
-
Monitoring: Beyond Kinesis for outcomes, also monitor campaign-level CloudWatch metrics to detect throttling patterns early. If you see concentrated throttle events in specific hours, you may need to adjust your percentage distribution.
Your architecture provides the granular control needed for percentage-based distribution that native campaign scheduling doesn't offer directly. The combination of hourly segment refresh capability with your custom throttling layer gives you both flexibility and control over call pacing throughout the day.
Sources
Amazon Connect outbound campaigns now supports hourly segment refresh - AWS
Amazon Connect Outbound Campaigns now supports contact priority ordering - AWS
Amazon Connect Outbound Campaigns V2 - Amazon Connect Customer
How to Diagnose Amazon Connect Outbound Campaign Throttling Using CloudWatch and CloudTrail | AWS re:Post
answered 4 days ago
PutOutboundRequestBatchis a standard API for Campaigns V2, and your understanding of the 25-item-per-batch limit is correct. Injecting records via API into a campaign that wasn't created with a source file is an intended use case.- For agentless campaigns, the
dialingCapacityparameter (ranging from 0.01 to 1) allows you to control the allocation of dialing capacity across campaigns. However, since this controls the rate per second rather than a percentage allocation based on time of day, your decision to implement external logic to manage this is sound. - Please use
UpdateCampaignCommunicationTimein conjunction with this. Currently, EventBridge cron is the only mechanism for time-based control, leaving a risk of calls being placed late at night due to a Lambda bug; you should implement a safety mechanism on the service side as well.
The system fails in scenarios where, for example, you start with 1,000 records in the morning and add 9,000 more at midday. If you allocate 10% (100 records) based on a total of 1,000 records at 9:00 AM, that initial allocation effectively becomes 1% once the total reaches 10,000. The "1.5x cap" only limits sudden spikes; it does not solve this underlying issue.
You need to choose one of the following approaches:
- Option A: Fixed denominator — Agree with the client that "all files must arrive by X AM" and finalize the count after the deadline. This makes behavior predictable.
- Option B: Remaining-count based — Redefine the logic to "allocate remaining records based on remaining time." Added files are automatically redistributed to subsequent time slots, eliminating the need for a cumulative counter.
Throttling handling (Critical)
RequestThrottled signals that you should stop sending and wait due to insufficient capacity. You need logic to examine the failedRequests and successfulRequests in the response, return failed requests to a "pending" state, and implement backoff when throttling occurs.
expirationTime
It is recommended to set this for a time a few minutes in the future. Since submitting a full hour's worth of records at once could result in most of them expiring, the design needs to break the batch down into smaller slices.
Idempotency
Generate the clientToken deterministically based on the record ID. Random generation leads to duplicate calls during Lambda retries.
API Rate Limits
Quotas apply at the account/region level and are shared across instances. Calculate the time required to send a full hour's worth of requests and verify that it fits within the 15-minute Lambda execution limit.
DynamoDB
- A Global Secondary Index (GSI) is essential for retrieving "pending" records. Using
statusalone as a key creates a hot partition; use a composite key likestatus#shardto distribute the load. - Updating a single item for a cumulative counter causes contention (adopting "Plan B" eliminates this issue).
- Since there is no
TRUNCATEoperation, use TTL (Time to Live) to clear the table. Deletions can be delayed by up to 48 hours, so implement date filters on the query side as well.
Result Collection
We recommend using EventBridge contact events alongside CTRs. While dispositions (e.g., EXPIRED, TELECOM_PROBLEM) can be tracked via either contact records or contact events, CTRs are written only after the call completes, delaying the detection of cases where the call could not be placed.
Other Undefined Items
Retry design (attempt counts are recorded, but re-submission logic is missing), alignment with concurrent call quotas, DNC/opt-out cross-referencing, and monitoring of RequestThrottled error rates.
answered 4 days ago
Relevant content
asked 2 years ago
- AWS OFFICIALUpdated 3 years ago
