{"slug": "agentic-runtime-python-startup-time-and-import-optimization-4s-2s", "title": "Agentic Runtime: Python Startup Time and Import Optimization (4s –> 2s)", "summary": "A developer optimized the cold-start time of the Vex agentic runtime from roughly 4 seconds to about 2 seconds by deferring heavy imports, using TYPE_CHECKING guards for annotation-only imports, and moving modules such as langgraph into function-scoped on-demand imports. Profiling with tuna and Python's -X importtime identified the bottleneck, including a single `from langgraph.graph.state import END` import that consumed 1.36 seconds. Utility commands like --help and --ls now bypass main program initialization entirely by short-circuiting before the heavy engine imports.", "body_md": "# Architecture Deep Dive: Startup Time & Import Optimization\n\nHere's where I started about 4s of cold start for both utility functions and main vex program - just disgusting speed for a *cutting-edge* agentic runtime.\n\n## The difference between main app and utility functions\n\nAll *utility* functions are a shortcuts that usually avoid main program functionality, for example \n\n- `--help` - just show help message\n- `--ls` - list session, touch only sqlite database\n\nObviously such functions should work almost immediately.\nHow to speed up *utility* functionality in this case ? \nJust bypass main program initialization:\n\n``` python\n# Main CLI start point\nasync def run_agent(args):\n    # ...\n\n    # Short circuits for utility functions \n    if args.init:\n        init_workspace(console=console)\n        return\n    if args.list_sessions:\n        await list_sessions(settings,console)\n        return\n\n    # Start agent, heavy lift imports\n    from vex_shell.engine import core\n    from vex_shell.engine.agent import Agent\n\n    tools,mcp_manager = await core.get_tools(settings)\n    graph = core.build_graph(settings, tools)\n    agent = await Agent.create(graph, args.session, settings, mcp_manager)\n```\n\nAll heavy imports occur after utility args checking(`from vex_shell.engine import core` etc).\n\n## Main App Startup Optimization\n\nOkay let's consider that we have blazingly fast utility functions, but what about main app startup ?\nUsing some extremely useful tools, like  *[tuna](https://pypi.org/project/tuna/)* and `-X importtime`. I have investigated which modules slow down startup. Tuna generated visual map  showing the exact time required for module imports.\n\nBased on this map, I found several bottlenecks in the codebase.\n\n### Type Annotation-Only Imports\n\nDuring development, module-level imports are often added purely for type annotations:\n\n``` python\nfrom vex_shell.utils.config import Settings\n```\n\nEven if `Settings` is used for type hints only, the **entire** `config` module, will still be loaded.\nTo prevent this unexpected behavior, we can use the following pattern:\n\n``` python\nfrom __future__ import annotations\nfrom typing import TYPE_CHECKING\n\nif TYPE_CHECKING:\n    from vex_shell.engine.agent import Agent\n    from rich.console import Console\n    from vex_shell.utils.config import Settings\n```\n\n`TYPE_CHECKING` evaluates to `False` during runtime, ensuring these imports are used strictly for static type checking during development. This yields **zero** resource overhead during execution.\n\n### Function-Scoped Imports\n\nUsually we just import most of modules at the top of `.py` file, but in this case we transfer all imports to application start time. Which isn't always a good choice. Alternatively we can use `on-demand imports`, thus import module during function call. Of course it will slow down function call time, but we can achieve shorter start time, moving delays to runtime, and it's also worth noting that any imports loaded only on the first call, after modules are already in cache.\n\n``` php\ndef build_graph(settings: Settings, tools:List[BaseTool]) -> StateGraph:\n    # On demand importing for heavy modules, only when function CALLED\n    from langgraph.graph.state import  StateGraph\n    from langgraph.prebuilt import ToolNode\n\n    from .nodes import llm_call_node, verification_node, should_continue, should_verify\n    from .state import State\n\n    tool_names = [e.name for e in tools]\n    \n    graph = StateGraph(State)\n    \n    # LLM Nodes\n    graph.add_node(\n        \"llm_call\", partial(llm_call_node, settings=settings, tool_names=tool_names)\n    )\n    graph.add_node(\"tool_node\", ToolNode(tools))\n    graph.add_node(\"verification_node\", partial(verification_node, settings=settings))\n    # ...\n```\n\n### Fun to note\n\nIn [nodes.py](https://codeberg.org/Enji/vex/src/branch/main/src/vex_shell/engine/nodes.py) I used `from langgraph.graph.state import END`\nonly for `END` constant, but it leads to a whole module import which consumes `1.36s`. By  just replacing this import with `END = \"__end__\"` I saved this time.\n\n## Approximate results\n\n1. MCPManager - imported only if defined in CONFIG.toml, saves 1 second.\n2. Move all annotation-only imports into a `TYPE_CHECKING` guard.\n3. Move all heavy imports inside functions (`ChatOpenAI` ,`langchain.messages` ,etc)\n\n## Timings\n\n- Utility functions - `-ls/--help/--reset` ~400ms\n- Main app start time (without MCP tools) ~2.1 seconds\n- Main app start time (with MCP tools) ~2.7 seconds\n\n## Tuna diagrams here\n\n## P.S.\n\nVEX shell source code: [https://codeberg.org/Enji/vex](https://codeberg.org/Enji/vex)\n\nThanks for reading, Bye ₍^. .^₎⟆", "url": "https://wpnews.pro/news/agentic-runtime-python-startup-time-and-import-optimization-4s-2s", "canonical_source": "https://enjii.pages.dev/blog/Optimizations/vex_startup_time_optimization/", "published_at": "2026-10-02 08:39:35+00:00", "updated_at": "2026-10-02 09:06:20.465475+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-tools"], "entities": ["Vex", "tuna", "langgraph", "Python", "vex_shell.engine.core", "vex_shell.engine.agent.Agent", "TYPE_CHECKING"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/agentic-runtime-python-startup-time-and-import-optimization-4s-2s", "markdown": "https://wpnews.pro/news/agentic-runtime-python-startup-time-and-import-optimization-4s-2s.md", "text": "https://wpnews.pro/news/agentic-runtime-python-startup-time-and-import-optimization-4s-2s.txt", "jsonld": "https://wpnews.pro/news/agentic-runtime-python-startup-time-and-import-optimization-4s-2s.jsonld"}}