Skip to content

Conversation

@Ostico
Copy link

@Ostico Ostico commented Jan 13, 2026

PR Documentation: Optional PSR-6 Caching for CloudWatch Initialization

What kind of change does this PR introduce?

Feature / Performance Optimization.

What is the current behavior?

When the CloudWatch handler is configured with $createGroup = true or $createStream = true, it performs an initialization check every time a new instance is created (typically once per request in most PHP applications).

This check involves calling AWS APIs (describeLogGroups and describeLogStreams) to verify existence before attempting creation. In high-traffic environments or serverless contexts (like AWS Lambda), these repetitive API calls can lead to:

  1. Increased Latency: Each request waits for the AWS API round-trip before sending logs.
  2. AWS Rate Limiting: Frequent "Describe" calls can trigger ThrottlingException from CloudWatch Logs, potentially causing log loss or delays.
  3. Unnecessary Overhead: Since log groups and streams are rarely deleted, checking their existence on every single execution is redundant.

What is the new behavior?

This PR introduces an optional PSR-6 Cache System integration.

By providing a CacheItemPoolInterface to the handler, the initialization status of Log Groups and Log Streams is persisted. Subsequent requests will check the local cache first; if the "initialized" flag is present and not expired, the handler skips the AWS describe and create API calls entirely.

Key Features:

  • Reduced Latency: Skips network calls to AWS for initialization when cache is hit.
  • Configurable TTL: The $cacheItemTtl parameter (defaulting to 5 minutes) allows you to control how often the handler re-verifies existence with AWS.
  • Fail-Safe: If no cache is provided, the handler falls back to its original behavior (checking AWS every time).

Why implement a Cache system if $createGroup and $createStream already exist?

You might wonder: "If I set these parameters to true, the code already checks if they exist before creating them. Why do I need a cache?"

The existing parameters control intent (should we ensure they exist?), but the implementation requires API calls to verify that existence.

  • Without Cache: Even if the group exists, the handler must ask AWS "Does this group exist?" on every execution to decide whether to call createLogGroup.
  • With Cache: The handler asks the local cache "Do we already know this group exists?". If the answer is yes, we avoid the network overhead and API quotas associated with describeLogGroups.

This is particularly beneficial for horizontally scaled applications where hundreds of processes might otherwise hammer the AWS API simultaneously just to confirm that a long-existing log group is still there.

Why not just set both to false?

A common suggestion to improve performance is to set $createGroup and $createStream to false (assuming the resources were created manually or by infrastructure-as-code). However, this is often not viable for the following reasons:

  1. Risk of Silent Failure: If for any reason the Log Group or Stream is deleted or was never created (e.g., a new environment deployment), setting these to false will cause the putLogEvents call to fail. Without the "create" logic enabled, the handler cannot recover automatically.
  2. Dynamic Resources: In many applications, log streams are named dynamically (e.g., by date or instance ID). It is impossible to set $createStream to false if the stream name changes frequently and hasn't been pre-created.
  3. Developer Experience: Keeping these set to true ensures "plug-and-play" functionality where logs "just work" in any environment without manual AWS console intervention.

The Cache System provides the best of both worlds: It maintains the safety of auto-creation (true) while achieving the performance of pre-created resources (false) by skipping the redundant API checks once the first check succeeds.

Does this PR introduce a breaking change?

No. The parameters are optional, and the default behavior remains identical to the current version.

Other information

An InvalidArgumentException is thrown if a cacheItemPool is provided while both createGroup and createStream are set to false, as the cache would serve no purpose in that configuration.

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.

1 participant