AWS Lambda
Async Programming
Python 3.6
Serverless Functions
Event-driven Architecture

Can you have an async handler in Lambda Python 3.6?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

No. In AWS Lambda, the Python handler itself must be a normal synchronous function, not an async def handler. That rule applies to Python runtimes broadly, and it matters even more for old Python 3.6-era Lambda code. You can still use asynchronous code inside the function, but the exported Lambda entry point must remain synchronous.

What Lambda Expects as a Handler

A Python Lambda handler takes event and context as ordinary function arguments and returns a normal result.

python
1def lambda_handler(event, context):
2    return {
3        "statusCode": 200,
4        "body": "ok"
5    }

If you try to expose an async def handler directly, Lambda will not await it for you.

Use Async Code Inside a Sync Handler

If you need asynchronous I/O, keep the handler synchronous and run your coroutine from inside it.

python
1import asyncio
2
3
4async def fetch_message():
5    await asyncio.sleep(0.1)
6    return "done"
7
8
9
10def lambda_handler(event, context):
11    loop = asyncio.new_event_loop()
12    try:
13        asyncio.set_event_loop(loop)
14        message = loop.run_until_complete(fetch_message())
15        return {
16            "statusCode": 200,
17            "body": message,
18        }
19    finally:
20        loop.close()

This pattern keeps Lambda happy while still letting you use await inside helper functions.

Why This Limitation Exists

Lambda invokes the handler according to the runtime contract, not according to Python web-framework conventions. In other words, Lambda expects a callable that it can invoke directly and get a final response from. The runtime does not treat the handler like an async-aware application server.

That is why the outer function stays synchronous even when internal work is asynchronous.

Be Careful with Python 3.6 Specifically

Python 3.6 introduced async and await, but it is now long past end of life. Even if you are maintaining legacy code with this question in mind, new Lambda work should use a supported Python runtime.

The design principle stays the same, though:

  • synchronous handler at the Lambda boundary
  • optional async helpers inside the handler

That separation also makes migrations easier. If the runtime changes later, most of the async business logic can stay in helper functions while the Lambda entry point remains a thin synchronous wrapper.

Async Does Not Replace Lambda Concurrency

Another common misunderstanding is thinking an async handler would increase Lambda concurrency. Lambda concurrency is managed by AWS at the invocation level. Asynchronous code inside one invocation can help with overlapping I/O, but it does not change how many parallel invocations Lambda can scale to.

That means async is mainly useful when a single invocation needs to coordinate several network-bound operations efficiently.

Keep the Event Loop Lifecycle Simple

In short-lived Lambda code, creating a dedicated event loop inside the handler is often the least surprising option. It avoids hidden assumptions about a reused global loop and keeps cleanup explicit, which matters when maintaining older Python 3.6 code.

Common Pitfalls

  • Declaring the exported Lambda handler with async def and expecting Lambda to await it.
  • Creating async helper functions but forgetting to drive them with an event loop.
  • Assuming async code changes Lambda’s external concurrency model.
  • Keeping legacy Python 3.6 code instead of planning a runtime upgrade.
  • Overcomplicating simple handlers with asyncio when ordinary synchronous code is enough.

Summary

  • AWS Lambda Python handlers must be synchronous functions.
  • You cannot use async def as the exported handler.
  • You can still run asynchronous helper code from inside a normal handler.
  • Async is useful for overlapping I/O inside one invocation, not for changing Lambda scaling behavior.
  • For new work, use a supported Python runtime even though the handler rule stays the same.

Course illustration
Course illustration

All Rights Reserved.