Skip to content

Lazy load model data classes - #851

Open
kuhe wants to merge 2 commits into
developfrom
kuhe/chore/models
Open

kuhe wants to merge 2 commits into
developfrom
kuhe/chore/models

Conversation

@kuhe

@kuhe kuhe commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

@dataclass annotations in the models.py file take up too much CPU time on initialization. As things stand, a 128mb lambda would OOM just by loading a handful of AWS SDK clients, if they are any of the somewhat large ones (not necessarily even to EC2's level).

To avoid this, the PR:

  • makes models.pyi declare the classes as type interfaces only
  • has models.py generate the classes on-demand

Cold-start benchmark

AWS Lambda w/ 512 MB, Python 3.12

Imports (does not instantiate) 5 generated clients at module scope: bedrock-agentcore-control, bedrock, guardduty, bedrock-agent, lambda.

Init Duration, median of 3 cold starts.

models source-only hash-pinned .pyc
eager (develop) ~3.9s ~2.3s
lazy (this PR) ~1.6s ~0.8s

@kuhe
kuhe force-pushed the kuhe/chore/models branch 6 times, most recently from e403e39 to 1578269 Compare October 15, 2026 17:15
@kuhe

kuhe commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

4% serde slowdown after cold start, but we'll reclaim that performance in another PR.

The SDK has to start up without going OOM first.

@kuhe
kuhe marked this pull request as ready for review October 15, 2026 18:50
@kuhe
kuhe requested a review from a team as a code owner October 15, 2026 18:50
@kuhe
kuhe force-pushed the kuhe/chore/models branch 2 times, most recently from 9836707 to c68bef4 Compare October 15, 2026 20:02
@kuhe
kuhe force-pushed the kuhe/chore/models branch from c68bef4 to 987e77b Compare October 15, 2026 21:14
if scalar is not None:
return scalar
if st == ShapeType.STRUCTURE:
target = member.expect_member_target().id.name

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we lose the namespace here?

Comment thread packages/smithy-core/src/smithy_core/_dynamic_models.py Outdated
Comment thread packages/smithy-core/src/smithy_core/_dynamic_models.py
fields.append((field_names[i], _py_type(member)))
else:
fields.append((field_names[i], _py_type(member), spec))
bases: tuple[type, ...] = (ModeledError,) if is_error else ()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don’t modeled errors still need to extend the service’s ServiceError? Right now except ServiceError won’t catch them

Comment on lines +452 to +457
return {
"serialize": serialize,
"serialize_members": serialize_members,
"deserialize": deserialize,
"_smithy_default": _smithy_default,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we mean to drop deserialize_kwargs? It’s still in the stub, but it isn’t on the runtime class

@kuhe
kuhe force-pushed the kuhe/chore/models branch 3 times, most recently from d62499b to aaf2366 Compare October 16, 2026 14:43
@kuhe
kuhe force-pushed the kuhe/chore/models branch from aaf2366 to 6c16a24 Compare October 17, 2026 18:30
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