Repository navigation
Conversation
82f9870 to
9035425
Compare
The write-pacing guard only started delaying writes once a single invocation's own batch reached the store's maxWritesPerSecond threshold, and sized the delay off that same per-invocation number. Parameter Store's write-rate limit is account-wide: several pools' scale-up/pool lambdas can each stay under the threshold individually while their combined writes exceed the account limit, and a batch below the threshold got no pacing at all. The guard now always paces once a write limit is configured, and divides the per-write delay by a new ssm_parameter_store_max_concurrent_invocations variable so the configured account-wide write budget is shared across the expected number of concurrent invocations instead of assumed available to each one independently. The write limit itself was also hardcoded to SSM's standard-tier default of 40/sec. It's now configurable via a new ssm_parameter_store_max_writes_per_second variable, so accounts that enabled SSM's higher-throughput tier (up to several thousand writes/second) can raise the pacing ceiling to match instead of being paced against a limit that no longer applies to them. Both variables are wired through for the scale-up and pool lambdas; defaults (1 concurrent invocation, 40 writes/sec) match prior behavior. Documented in docs/rate-limits-and-tuning.md alongside the existing SSM/batch_size guidance.
9035425 to
4ec6bcb
Compare
…rate-limit # Conflicts: # lambdas/functions/control-plane/src/scale-runners/github-runner.test.ts
|
@atsikham also implement the changes in https://github.com/github-aws-runners/terraform-aws-github-runner/tree/main/modules/orchestration-providers/webhook and https://github.com/github-aws-runners/terraform-aws-github-runner/tree/main/modules/multi-runner multi-runner is the module to deploy multi runners |
|
@edersonbrilhante digging into the wiring: in modules/runners the two new pacing settings are one flat value shared by scale-up and pool lambda. But multi-runner/orchestration-providers/webhook split lambda config per type with no shared bucket. Duplicate the field under both scale.up and pool, or is there a preferred place for settings shared across lambdas in a runner group? |
…rate-limit # Conflicts: # lambdas/libs/storage-providers/storage-providers.test.ts # lambdas/libs/storage-providers/storage-providers.ts # modules/runners/pool.tf # modules/runners/pool/main.tf # modules/runners/pool/variables.tf # modules/runners/scale-up.tf
…and the webhook modules Wire ssm_parameter_store_max_writes_per_second and ssm_parameter_store_max_concurrent_invocations through: - multi-runner v1: module variables, applied to all runner configurations - multi-runner v2: global_config_storage_provider default with a per-runner override under storage_provider.aws.ssm.parameters - runner-config and the webhook, scale-runners and pool modules, which pass the values to the Lambda environment Without this, the migration test reports the two environment variables as removed when moving from the v1 to the v2 inputs.
cfc3068 to
7fcb8b1
Compare
…rate-limit # Conflicts: # modules/multi-runner/README.md # modules/runners/scale-up.tf
There was a problem hiding this comment.
🟡 Changes recommended
A duplicate import of createAwsSsmRunnerConfigStore causes a syntax error that prevents the test file from loading and breaks type checking.
2 open issues
What changed in this PR
This PR addresses #5410 by making runner configuration write pacing account for expected concurrent Lambda invocations, rather than only large batches within one invocation.
Changes:
- Applies pacing to all nonempty batches when the storage provider defines a write limit.
- Adds configurable write-rate and concurrency settings across root, multi-runner, and webhook orchestration modules, including v2 defaults and per-runner overrides.
- Adds pacing and configuration tests and updates tuning documentation.
| File | Description |
|---|---|
variables.tf |
Declares root-level pacing inputs. |
README.md |
Documents the new root inputs. |
modules/runners/variables.tf |
Declares runner-module pacing inputs. |
modules/runners/scale-up.tf |
Passes pacing settings to scale-up. |
modules/runners/README.md |
Documents runner pacing inputs. |
modules/runners/pool/variables.tf |
Adds pool configuration fields. |
modules/runners/pool/README.md |
Documents pool configuration additions. |
modules/runners/pool/main.tf |
Sets pool Lambda pacing variables. |
modules/runners/pool.tf |
Forwards pacing settings to the pool module. |
modules/runner-config/variables.tf |
Adds storage-provider pacing options. |
modules/runner-config/tests/tags.tftest.hcl |
Checks scale-up environment propagation. |
modules/runner-config/README.md |
Documents storage-provider pacing options. |
modules/runner-config/orchestration-provider.tf |
Forwards settings to webhook orchestration. |
modules/orchestration-providers/webhook/variables.tf |
Extends the storage-provider interface. |
modules/orchestration-providers/webhook/scale-runners/variables.tf |
Accepts scaling pacing settings. |
modules/orchestration-providers/webhook/scale-runners/tests/scale-runners.tftest.hcl |
Checks scale-up pacing variables. |
modules/orchestration-providers/webhook/scale-runners/scale-up.tf |
Configures scale-up pacing variables. |
modules/orchestration-providers/webhook/scale-runners/README.md |
Documents scaling interface additions. |
modules/orchestration-providers/webhook/README.md |
Documents webhook storage settings. |
modules/orchestration-providers/webhook/pool/variables.tf |
Accepts pool pacing settings. |
modules/orchestration-providers/webhook/pool/tests/provider.tftest.hcl |
Checks pool pacing variables. |
modules/orchestration-providers/webhook/pool/README.md |
Documents pool storage settings. |
modules/orchestration-providers/webhook/pool/pool.tf |
Configures pool pacing variables. |
modules/multi-runner/variables.tf |
Adds v1 inputs and v2 per-runner overrides. |
modules/multi-runner/variables.experimental.storage-provider.tf |
Defines v2 global pacing defaults. |
modules/multi-runner/tests/config-translation.tftest.hcl |
Tests translation, inheritance, and overrides. |
modules/multi-runner/runners.tf |
Passes resolved settings to runners. |
modules/multi-runner/README.md |
Documents multi-runner pacing configuration. |
modules/multi-runner/config.experimental.translation.tf |
Translates v1 pacing inputs. |
modules/multi-runner/config.experimental.resolved.tf |
Resolves per-runner overrides against defaults. |
main.tf |
Forwards root pacing inputs. |
lambdas/libs/storage-providers/storage-providers.ts |
Loads the write limit from the environment. |
lambdas/libs/storage-providers/storage-providers.test.ts |
Tests write-limit forwarding. |
lambdas/libs/storage-providers/aws/ssm/runner-config-store.ts |
Makes the store write limit configurable. |
lambdas/libs/storage-providers/aws/ssm/runner-config-store.test.ts |
Tests write-limit configuration and fallback. |
lambdas/functions/control-plane/src/scale-runners/github-runner.ts |
Paces small batches and scales delays by concurrency. |
lambdas/functions/control-plane/src/scale-runners/github-runner.test.ts |
Adds delay calculation and execution tests. |
docs/rate-limits-and-tuning.md |
Updates pacing configuration and tuning guidance. |
Review effort: Balanced
PutParameter is limited to 3 TPS (10 TPS with higher throughput); 40 TPS is the read quota. Keep the default of 40 so pacing is unchanged, and say to lower it when PutParameter is throttled.


Fixes #5410
Summary
The code that slows down writes to Parameter Store (so they don't hit AWS's rate limit) had two problems:
maxWritesPerSecondnumber, and it based the delay only on that one invocation's batch size. But Parameter Store's write limit applies to the whole AWS account, not to one invocation: several pools can each run their own scale-up/pool Lambda at the same time, each one under its own threshold, while their writes added together go over the account's limit. And a batch smaller than the threshold got no slowdown at all.PutParameter(10 with higher throughput).Changes
ssm_parameter_store_max_concurrent_invocations, sets how many scale-up/pool Lambda invocations can realistically be running at the same time across the whole deployment. The delay between writes is divided by that number, so the account-wide write budget is shared across all of them instead of each invocation assuming it has the whole budget to itself.ssm_parameter_store_max_writes_per_second, makes the write rate configurable. Default stays40, so nothing changes for existing setups. Lower it ifPutParametergets throttled.modules/runners,modules/multi-runner, and the webhook orchestration modules (runner-config,webhook,scale-runners,pool). The defaults (1invocation,40writes/sec) match how the code behaved before.global_config_storage_provider.aws.ssm.parameters.max_concurrent_invocationsandmax_writes_per_secondset the default for all runner configurations. A runner configuration can override either value in its ownstorage_provider.aws.ssm.parameters.docs/rate-limits-and-tuning.mdis updated: the Parameter Store section explains both new variables and shows the real AWS limits (before it said reads and writes share 40 TPS). Also fixed a claim in thebatch_sizetable that was no longer true (the slowdown no longer depends on batch size), and updated the advice for large deployments. The Parameter Store section also has a table showing where to set the values in each module.Test plan
yarn test—github-runner.test.tschecks the delay math inaddDelay(including the small-batch case that used to get no delay, and the sharing-across-invocations behavior), plus an end-to-end test using fake timers throughcreateStartRunnerConfig.runner-config-store.test.tsandstorage-providers.test.tscheck that the write-rate limit can be set, falls back to 40 if the value is missing or invalid, and is picked up from the environment correctly.terraform testinmodules/multi-runner(v1 translation, v2 global default, per-runner override),scale-runners,poolandrunner-config: the values reach the scale-up and pool Lambda environment.migration-testCI job no longer reports the two environment variables as removed when moving from v1 to v2 inputs.yarn lint/yarn formattsc --noEmitterraform fmt -check/terraform validate(tflint could not be installed in this environment — no network access to its Homebrew source — so the full set of pre-commit checks was not run locally)