Reduce StripeClient() cold start latency for serverless environments#1834
Draft
jar-stripe wants to merge 4 commits into
Draft
Reduce StripeClient() cold start latency for serverless environments#1834jar-stripe wants to merge 4 commits into
jar-stripe wants to merge 4 commits into
Conversation
asyncio was imported at module level in _http_client.py but only used by AIOHTTPClient.sleep_async(). Since _http_client is loaded eagerly by stripe/__init__.py, every user paid ~1.8s on CPU-constrained environments (e.g. Lambda cold starts) for a module they likely never use. Move the import into AIOHTTPClient.__init__ so only users with aiohttp installed incur the cost. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
The uuid module pulls in 20 transitive modules (including re, enum, platform) and takes 300-700ms to import under Lambda-like CPU constraints. Since os is already imported in this file and os.urandom(16).hex() produces an equivalent 32-char hex string with cryptographic randomness, we can drop the uuid dependency entirely. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
Instead of detecting and importing HTTP libraries (requests, httpx, etc.) inside StripeClient.__init__, resolve them once at module load time. This shifts the expensive import cost from the invoke phase (3s Lambda timeout) to the init phase (10s budget). The resolved class is stored directly — new_default_http_client() and new_http_client_async_fallback() just instantiate it. Adding a new client means defining the class and adding one entry to the resolution cascade at the bottom of the file. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
This reverts commit 8cf83cd.
Contributor
Author
Benchmark ResultsMethodology: Each measurement is a separate Docker container ( Baseline (master)Fixed (this PR)Summary
The key result: StripeClient() drops from ~2s to ~0.15s. The import cost for HTTP libraries such as requests shifts to |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why?
Users in serverless environments (AWS Lambda with 128MB memory / 3s timeout) report that
stripe.StripeClient()initialization alone can exceed their invocation timeout budget. A major contributor to this is the fact that HTTP client library imports (requests,httpx) happen insideStripeClient.__init__(), putting their cost in the invoke phase (3s budget) rather than the module init phase (10s budget).Additionally,
uuid(used only for generating idempotency keys) pulls in 20 transitive modules includingre,enum, andplatform, adding 300-700ms at Lambda-scale CPU.What?
stripe._http_clientis first imported, sonew_default_http_client()andnew_http_client_async_fallback()just instantiate the pre-resolved class without any imports.uuid.uuid4()withos.urandom(16).hex()for idempotency key generation. Produces an equivalent 32-char cryptographically random hex string without importing theuuidmodule.osis already imported in_api_requestor.py.See Also
Changelog