Oct 23, 20265 min read

Litestar vs FastAPI

How Litestar and FastAPI compare on scope, dependency injection, serialization, class-based controllers and governance, with the same endpoint written in each.

Litestar and FastAPI are both async, type-driven Python API frameworks that generate OpenAPI docs from your annotations. FastAPI is the better known of the two, with a large ecosystem and a single original author. Litestar ships more features in the core and is run by a team of maintainers. The overlap is large enough that the decision usually comes down to scope and governance rather than syntax.

The main differences:

  • Litestar includes class-based controllers, DTOs, sessions and caching, while FastAPI keeps a smaller core and relies on Starlette and add-on libraries.
  • Litestar serializes with msgspec by default and also accepts Pydantic, while FastAPI is built around Pydantic.
  • Both use dependency injection, but Litestar declares dependencies with Provide at any layer of the app, while FastAPI declares them with Depends in the handler signature.
  • FastAPI has the larger community, which means more examples for developers and for AI coding agents to draw on.

Litestar vs FastAPI at a glance

CapabilityEncoreLitestarFastAPI
RoleInfrastructure SDK added to either frameworkAPI frameworkAPI framework
SerializationFrom the frameworkmsgspec by default, Pydantic supportedPydantic
Dependency injectionFrom the frameworkProvide at app, router, controller or handler levelDepends in the signature
ControllersFrom the frameworkClass-based controllers built inFunction routes with APIRouter
Built-in extrasFrom the frameworkSessions, caching, DTOs, OpenTelemetry integrationKept to add-on libraries

Litestar: more in the core

The Litestar documentation describes it as not a microframework and lists ORM integration, sessions, caching and OpenTelemetry support among the built-in features. It also notes the project is community-driven with a core team of maintainers. The signup endpoint, with a pool opened in a startup hook:

import os from dataclasses import dataclass import asyncpg from litestar import Litestar, post from litestar.datastructures import State @dataclass class Signup: email: str async def open_pool(app: Litestar) -> None: app.state.pool = await asyncpg.create_pool(os.environ["DATABASE_URL"]) async def close_pool(app: Litestar) -> None: await app.state.pool.close() @post("/users") async def create_user(data: Signup, state: State) -> dict[str, str]: await state.pool.execute("INSERT INTO users (email) VALUES ($1)", data.email) return {"email": data.email} app = Litestar( route_handlers=[create_user], on_startup=[open_pool], on_shutdown=[close_pool] )

The request body arrives as data, and a plain dataclass is enough to validate it. Serialization goes through msgspec, a separate library focused on fast JSON encoding and validation. Litestar's dependency injection lets you register a provider once on the app or a controller instead of repeating it per handler.

FastAPI: a small core and a large ecosystem

FastAPI builds on Starlette for the web layer and Pydantic for data. In the 2024 Python Developers Survey run by the Python Software Foundation and JetBrains, 38% of respondents used FastAPI, up from 21% in 2021. Litestar was not among the frameworks listed separately. FastAPI dependencies are declared with Depends in each handler signature, and they can be nested and shared through routers.

import os from contextlib import asynccontextmanager import asyncpg from fastapi import FastAPI, Request from pydantic import BaseModel class Signup(BaseModel): email: str @asynccontextmanager async def lifespan(app: FastAPI): app.state.pool = await asyncpg.create_pool(os.environ["DATABASE_URL"]) yield await app.state.pool.close() app = FastAPI(lifespan=lifespan) @app.post("/users", status_code=201) async def create_user(req: Signup, request: Request) -> dict: await request.app.state.pool.execute( "INSERT INTO users (email) VALUES ($1)", req.email ) return {"email": req.email}

FastAPI's strength is the number of people who already know it. Most Python developers have seen a FastAPI app, and the volume of public FastAPI code means coding agents have many examples to follow.

Adding infrastructure to either framework with Encore

Encore combines the framework you chose with infrastructure declared in Python. The infrastructure SDK is the encore-dev package, and Litestar or FastAPI keeps routing and request handling. Postgres databases, Pub/Sub topics, object storage buckets, cron jobs and secrets are module-level declarations that Encore discovers and provisions.

In Litestar, encore.start goes in on_startup, and the handler uses the declared database directly instead of a pool on State:

import encore from encore.storage import postgres from litestar import Litestar, post from pydantic import BaseModel db = postgres.Database("users", migrations="./migrations") class Signup(BaseModel): email: str @post("/users") async def create_user(data: Signup) -> dict[str, str]: await db.exec("INSERT INTO users (email) VALUES ($1)", data.email) return {"email": data.email} app = Litestar(route_handlers=[create_user], on_startup=[encore.start])

In FastAPI, the same db declaration works, and await encore.start() goes in the lifespan function.

encore run starts Postgres locally and applies the migrations, along with any topics and buckets, and the CLI reference covers encore test for tests that get their own database.

A deploy provisions the same declarations in your own AWS or GCP account.

Cloud access sits with Encore's IAM role, not the agent, so an agent adding a topic to a Litestar controller writes a declaration rather than cloud configuration. The AI integration guide covers how to give an agent these conventions.

Python support is in beta, and you can request access.

Try Encore →

How to choose

  • FastAPI when ecosystem size and familiarity matter most, including for agent-written code.
  • Litestar when you want controllers and DTOs in the framework and prefer team governance.

Encore works with either when you want databases and queues running locally and provisioned in your own cloud account.

Frequently asked questions

Should I use Litestar or FastAPI?

FastAPI is the more common choice when you want the largest ecosystem and the widest familiarity among developers and AI coding agents. Litestar fits teams that want more built in, such as class-based controllers and DTOs, and that prefer a framework run by a team of maintainers.

Is Litestar faster than FastAPI?

Litestar uses msgspec for serialization by default, which often makes it faster in serialization-heavy benchmarks. For most APIs the database and network calls dominate response time, so the difference rarely decides the choice.

Does Litestar support Pydantic?

Yes. Litestar accepts Pydantic models, dataclasses, TypedDicts and msgspec Structs for request and response data.

How do I add Postgres to a Litestar app?

Install the encore-dev package, declare postgres.Database at module scope and pass encore.start to on_startup. Handlers call db.exec and db.query directly. encore run starts Postgres locally, and a deploy provisions the database in your own AWS or GCP account.

Deploy to your cloud on AWS and Google Cloud
without managing infrastructure

Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.

~/orders — claude
Claude Code
Claude Code v2.1.180Opus 5.5~/orders