# Async URL: /docs/syntax/async/ Section: syntax Tags: syntax, async -------------------------------------------------------------------------------- Async Kida supports native async/await syntax for async template rendering. Async For Iterate over async iterables: {% async for user in fetch_users() %} <li>{{ user.name }}</li> {% end %} The template must be rendered with render_async(): import asyncio from kida import Environment async def main(): env = Environment() template = env.from_string(""" {% async for item in items %} {{ item }} {% end %} """) async def items(): for i in range(3): yield i result = await template.render_async(items=items()) print(result) asyncio.run(main()) Await Expressions Await async functions in expressions: {{ await fetch_data(user_id) }} Async Context When using render_async(), the template runs in an async context: async def render_page(): template = env.get_template("page.html") return await template.render_async( user=await get_user(), posts=await get_posts(), ) Sync vs Async Rendering Method Use Case render() Sync code, no async operations render_async() Async code, async for/await # Sync rendering (blocks) html = template.render(name="World") # Async rendering (non-blocking) html = await template.render_async(items=async_generator()) Async Patterns Parallel Fetching Fetch data concurrently before rendering: import asyncio async def render_dashboard(): # Parallel fetching user, posts, stats = await asyncio.gather( fetch_user(), fetch_posts(), fetch_stats(), ) template = env.get_template("dashboard.html") return await template.render_async( user=user, posts=posts, stats=stats, ) Streaming Iteration Process large async iterables without buffering: {% async for record in database_cursor() %} {{ record.name }} {% end %} Free-Threading Kida is designed for Python 3.14t free-threading (PEP 703). Combined with async, you can achieve high concurrency: from concurrent.futures import ThreadPoolExecutor import asyncio async def render_many(templates): """Render multiple templates concurrently.""" return await asyncio.gather(*[ t.render_async(data=data) for t, data in templates ]) Error Handling Async errors propagate normally: async def main(): try: result = await template.render_async(items=failing_generator()) except TemplateError as e: print(f"Render failed: {e}") Best Practices Use Async Sparingly Not everything needs async: {# ✅ Async for I/O-bound operations #} {% async for user in fetch_users_from_api() %} {# ❌ Sync iteration is fine for in-memory data #} {% for item in items %} Pre-Fetch When Possible # ✅ Better: Parallel fetch, then sync render users = await fetch_users() posts = await fetch_posts() html = template.render(users=users, posts=posts) # Slower: Sequential async in template # {% async for user in fetch_users() %} See Also Thread Safety — Free-threading support Performance — Performance optimization API Reference — Template.render_async() -------------------------------------------------------------------------------- Metadata: - Word Count: 361 - Reading Time: 2 minutes