Visitar URL original
Reduce import memory: load the *Dict TypedDicts in types.py lazily (~2.7 MiB, ~15% of the SDK's own import cost) · Issue #3010 · googleapis/python-genai · GitHub
Skip to content

Reduce import memory: load the *Dict TypedDicts in types.py lazily (~2.7 MiB, ~15% of the SDK's own import cost) #3010

Description

@rafaelborja

Thanks for the recent import-cost work (lazy interactions, _gaos behind TYPE_CHECKING, defer_build=True in 2.18.0). It cut RSS roughly in half for us. Home Assistant's Gemini integration often runs on small devices, such as a Raspberry Pi with 1–2 GB of RAM, where every megabyte counts.

After 2.18, most of what's left of the SDK's own import cost is types.py (863 KB of source). About a third of that file is 457 TypedDict classes (*Dict) plus ~470 *OrDict / *UnionDict aliases built from them. They exist for type hints only: no pydantic field uses them, and the SDK only reads them in annotations, in error messages, and in the Live API.

Measurement (2.25.0, CPython 3.14, RSS of a fresh process, shared deps preloaded):

stock TypedDicts lazy
import google.genai 18.2 MiB 15.7 MiB
import + Client + chats.create with a typical GenerateContentConfig 25.2 MiB 22.5 MiB

That's about 2.7 MiB, or ~15% of the SDK's own import cost.

What we tried (as a build-time patch on our side): move the *Dict classes and the aliases that depend on them into a private module (_types_dicts.py, same source text), and load it from the existing module-level __getattr__ in types.py on first access. types.ContentDict and from google.genai.types import ContentDict keep working. A small set stays eager: the names other SDK modules import at load time (HttpOptionsDict, HttpOptionsOrDict, ContentDict, ContentOrDict, GenerateContentConfigOrDict, PartUnionDict) and everything their definitions and annotations reference, about 100 names.

Risks and mitigations:

  1. Behavioral equivalence: All 1381 public names in google.genai.types are verified identical to stock: same kind, fields, docstrings, __module__, get_type_hints() outcome, and dir(). The bundled test suite gives identical per-test outcomes with the patch applied.

  2. __module__ attribute: Each moved TypedDict has its __module__ set back to google.genai.types after loading, so pickle, inspect, and tooling see the same origin as before. Code doing from google.genai.types import SomeDict continues to work.

  3. First-access latency: The lazy module loads on first use of any deferred name. This is a one-time cost (~5 ms measured) that moves from import time to first use. After that, all names are cached in the module globals, and access is a normal attribute lookup.

  4. Python < 3.14: The savings rely on PEP 649 (3.14+): function annotations such as config: Optional[types.GenerateContentConfigOrDict] in models.py are no longer evaluated at definition time. On 3.10–3.13 those annotations would trigger the load at import. That is still correct but saves nothing, unless the SDK's modules adopt from __future__ import annotations.

  5. Generated code: Since types.py is generated, the natural place for this is the generator. The patch is a build-time transform that could be folded into the code generation pipeline.

Proof of concept: rafaelborja/python-genai@main...lazy-load-typedicts. Happy to open a pull request if that helps, or it can serve as a reference for a generator change on your side.

A further step would be splitting the pydantic models themselves. A typical text + tools + thinking caller reaches only 137 of the 465 models, so that could save roughly another 5 MiB (estimated, not yet measured).

Happy to share the measurement scripts and help with testing.

Activity

  1. added
    priority: p2Moderately-important priority. Fix may not be included in next release.
    type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.
    type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.
    and removed
    type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.
    on Sep 28, 2026
  2. Venkaiahbabuneelam commented on Sep 28, 2026

    @Venkaiahbabuneelam

    Hi @rafaelborja, Thank you for your feedback. We appreciate you taking the time to share your thoughts with us, and we'll be filing a feature request.
    Thanks

  3. rafaelborja commented on Sep 30, 2026

    @rafaelborja
    Author

    Thanks! Could you keep this issue open and link it to the internal request, so we can follow its status? The proof of concept branch (rafaelborja/python-genai@main...lazy-load-typedicts) stays available if it's useful to the team working on the generator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

priority: p2Moderately-important priority. Fix may not be included in next release.type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions