Skip to content

fix(ecs): share single AWS client across all ECS plugin executions#119

Open
Will Graham (wlggraham) wants to merge 1 commit into
mainfrom
ecs_plugin_single_client
Open

fix(ecs): share single AWS client across all ECS plugin executions#119
Will Graham (wlggraham) wants to merge 1 commit into
mainfrom
ecs_plugin_single_client

Conversation

@wlggraham

Copy link
Copy Markdown
Contributor

Summary

  • ecs.Client and cloudwatchlogs.Client are now initialized once in New() on commandContext and reused across all Execute() calls, rather than being created fresh per job
  • PullLogs now accepts a *cloudwatchlogs.Client parameter instead of constructing its own
  • buildExecutionContext assigns the shared clients from commandContext to executionContext

Background

Diagnosed via a prod OOM incident on heimdall-task-definition:422. Two ECS task instances of the Heimdall server were OOM-killed within ~68 minutes of each other. In both cases, multiple amazon_serp_backfill_replay_* shards (large caterpillar-task-l jobs, 4096 CPU / 8192 MB) were running concurrently.

The root cause: each concurrent ECS job called config.LoadDefaultConfig and created independent ecs.Client and cloudwatchlogs.Client instances with their own HTTP connection pools and TLS sessions. With many parallel shards in-flight, these accumulated in the Heimdall process until the kernel OOM-killed it.

The AWS SDK v2 clients are goroutine-safe, so sharing a single instance across all executions of the same command is safe and idiomatic.

Test plan

  • Existing ECS plugin unit tests pass
  • Deploy to prod and monitor Heimdall memory under concurrent ECS job load

Previously, each ECS job execution called config.LoadDefaultConfig and
constructed new ecs.Client and cloudwatchlogs.Client instances in
buildExecutionContext and PullLogs. Under high concurrency (e.g. many
parallel amazon_serp_backfill_replay shards), this caused N independent
HTTP connection pools and TLS sessions to accumulate in the heimdall
process, contributing to OOM kills.

Clients are now initialized once in New() on the commandContext and
reused across all Execute() calls. The AWS SDK v2 clients are
goroutine-safe so no locking is required.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants