Quart reimplements the Flask API on asyncio. How the two compare on concurrency, WebSockets, extensions and migration effort, with the same endpoint written in each.
Quart is Flask's API rebuilt on asyncio, and it lives under the same Pallets organization. If you know Flask, the Quart documentation says you already know Quart. The comparison is mostly about the server model underneath, and whether your app has enough concurrent I/O to justify moving to it.
The main differences:
The Flask async guide explains that async views run in a thread with their own event loop and that each request still ties up one worker. It also says Flask's async support is less performant than async-first frameworks and points to Quart for mainly async codebases. A typical Flask endpoint stays synchronous:
import os
import psycopg
from flask import Flask, request
app = Flask(__name__)
@app.post("/users")
def create_user():
email = request.get_json()["email"]
with psycopg.connect(os.environ["DATABASE_URL"]) as conn:
conn.execute("INSERT INTO users (email) VALUES (%s)", (email,))
return {"email": email}, 201
This model is simple to reason about, and most Flask extensions assume it.
Quart runs on asyncio coroutines and tasks, and its Flask migration guide describes the move as changing imports and adding async and await. The same endpoint with an asyncpg pool opened before serving:
import os
import asyncpg
from quart import Quart, request
app = Quart(__name__)
@app.before_serving
async def open_pool() -> None:
app.config["POOL"] = await asyncpg.create_pool(os.environ["DATABASE_URL"])
@app.after_serving
async def close_pool() -> None:
await app.config["POOL"].close()
@app.post("/users")
async def create_user():
body = await request.get_json()
await app.config["POOL"].execute("INSERT INTO users (email) VALUES ($1)", body["email"])
return {"email": body["email"]}, 201
request.get_json() becomes awaitable, which is an easy change for an AI coding agent to miss when porting Flask code to Quart. Quart apps are usually served with Hypercorn, an ASGI server from the same author.
Quart helps when requests spend most of their time waiting on other services, or when the app needs WebSockets and server-sent events. For a CRUD app on a local database with modest traffic, Flask with a few more workers is often the simpler path.
Encore combines the framework you chose with infrastructure declared in Python. The infrastructure SDK is the encore-dev package, and Flask or Quart 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 Quart, encore.start() runs in before_serving, and routes await the declared database directly:
import encore
from encore.storage import postgres
from quart import Quart, request
db = postgres.Database("users", migrations="./migrations")
app = Quart(__name__)
@app.before_serving
async def start_encore() -> None:
await encore.start()
@app.post("/users")
async def create_user():
body = await request.get_json()
await db.exec("INSERT INTO users (email) VALUES ($1)", body["email"])
return {"email": body["email"]}, 201
In Flask, the same declaration works from synchronous views. Code that uses psycopg connects with db.connection_string, and async SDK calls such as bucket uploads go through asgiref.sync.async_to_sync.
encore run starts Postgres locally and applies the migrations, along with any topics and buckets, and the CLI reference covers encore test.
A deploy provisions the same declarations in your own AWS or GCP account, so a Flask app moving to Quart keeps its database and buckets.
Cloud access sits with Encore's IAM role, not the agent, so an agent porting routes from Flask to Quart changes code and declarations rather than cloud configuration. The AI integration guide covers how to give an agent Encore's conventions.
Python support is in beta, and you can request access.
Encore works with either when you want Postgres and buckets running locally and provisioned in your own cloud account.
Flask is a WSGI framework where each request holds a worker. Quart is an asyncio reimplementation of the Flask API on ASGI, so one process can serve many concurrent requests and WebSockets.
Flask async views run each request's event loop in a thread and still hold a worker per request. They suit a view that makes a few concurrent calls. If most of the codebase is async, the Flask documentation itself suggests considering Quart.
Quart's migration guide describes two steps: change imports from flask to quart, then add async and await where Quart's API is asynchronous, such as route functions and request.get_json(). Extensions that depend on Flask internals may need Quart-specific versions.
Install the encore-dev package, declare postgres.Database at module scope and call await encore.start() in a before_serving hook. Routes then call db.exec and db.query directly. encore run starts Postgres locally, and a deploy provisions it 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.