WSGI e ASGI são interfaces entre uma aplicação web Python e o servidor que recebe conexões. WSGI foi desenhado para o modelo síncrono de requisição e resposta. ASGI suporta esse modelo e também conexões assíncronas de longa duração, como WebSockets e streaming. A resposta curta: mantenha WSGI para aplicações síncronas maduras sem recursos em tempo real; escolha ASGI quando o framework, as bibliotecas e a carga se beneficiam de concorrência assíncrona ou protocolos persistentes.
Eles não são frameworks nem servidores. Django, Flask e FastAPI são frameworks; Gunicorn, uWSGI, Uvicorn, Daphne e Hypercorn servem aplicações. WSGI ou ASGI define o contrato entre essas camadas. A especificação PEP 3333 descreve WSGI, enquanto a especificação oficial ASGI define o protocolo assíncrono.
Como WSGI funciona
Um servidor WSGI chama um objeto Python com environ e start_response. A aplicação devolve um iterável de bytes. Cada chamada representa uma requisição HTTP e ocupa o worker enquanto o código está executando ou esperando I/O. A simplicidade produziu um ecossistema estável, fácil de depurar e adequado a grande parte dos sites.
def application(environ, start_response):
body = b"Hello, WSGI!"
start_response("200 OK", [
("Content-Type", "text/plain; charset=utf-8"),
("Content-Length", str(len(body))),
])
return [body]
Concorrência em WSGI costuma vir de múltiplos processos ou threads. Se uma chamada ao banco leva tempo, aquele worker aguarda, mas outros atendem requisições. Isso não significa que WSGI seja lento: para CRUD, templates e aplicações dominadas pelo banco, bom código, índices e cache frequentemente importam mais que trocar a interface. Nosso guia de desenvolvimento web com Python apresenta o ecossistema.
Como ASGI funciona
Um servidor ASGI chama uma aplicação assíncrona com scope, receive e send. O scope descreve a conexão; eventos entram por receive e saem por send. Esse modelo representa HTTP, WebSocket e lifespan sem manter uma thread bloqueada para cada conexão ociosa.
async def application(scope, receive, send):
assert scope["type"] == "http"
await send({
"type": "http.response.start",
"status": 200,
"headers": [[b"content-type", b"text/plain"]],
})
await send({
"type": "http.response.body",
"body": b"Hello, ASGI!",
})
Quando uma coroutine aguarda uma operação de rede não bloqueante, o event loop pode avançar outras conexões. Isso favorece muitas esperas simultâneas, streaming e tempo real. Não acelera código de CPU e não transforma bibliotecas síncronas em assíncronas. Para dominar o mecanismo, leia async e await em Python.
Diferenças que afetam a arquitetura
- Protocolos: WSGI modela HTTP; ASGI modela HTTP, WebSocket e eventos de ciclo de vida.
- Execução: WSGI chama código síncrono; ASGI permite código assíncrono e pode adaptar handlers síncronos.
- Conexões longas: streaming limitado é possível em WSGI, mas WebSocket não integra seu contrato; ASGI trata ambos naturalmente.
- Concorrência: WSGI escala com processos e threads; ASGI também usa processos, além de multiplexar I/O em cada event loop.
- Complexidade: WSGI tem menos fronteiras sync/async; ASGI exige cuidado com bloqueio, cancelamento e recursos compartilhados.
ASGI não elimina workers. Um processo continua limitado por CPU, memória e pelo event loop. Em produção, vários processos dão paralelismo e isolamento. Também não garante maior throughput: meça com uma carga representativa, incluindo banco e serviços externos, em vez de comparar uma rota “hello world”.
Escolha por caso de uso
Prefira WSGI quando a aplicação é inteiramente síncrona, usa bibliotecas bloqueantes, não precisa de WebSockets e já opera com desempenho satisfatório. Um site Django tradicional ou uma API Flask com consultas comuns pode permanecer em WSGI sem dívida técnica. Veja como estruturar esse tipo de projeto no guia de API REST com Flask.
Prefira ASGI para WebSockets, server-sent events, streaming, long polling ou muitas chamadas de rede simultâneas usando clientes async. FastAPI e Starlette são orientados a ASGI; o guia de FastAPI em Python mostra esse modelo. Para comunicação bidirecional, consulte WebSockets com Python.
Para tarefas que devem sobreviver à requisição, nenhum protocolo é uma fila. Enviar e-mail, gerar vídeo ou recalcular um relatório deve ir para um sistema de jobs. ASGI permite criar tarefas no event loop, mas elas podem desaparecer no restart e competem com o tráfego web.
Django em WSGI e ASGI
Django fornece wsgi.py e asgi.py. Implantar sob ASGI permite views async e conexões assíncronas quando o restante da pilha oferece suporte. Middleware síncrono pode forçar adaptações e reduzir o benefício. A documentação de deploy WSGI no Django e a de deploy ASGI no Django apresentam as opções suportadas.
Antes de migrar, liste middleware, driver de banco, cache, autenticação e clientes HTTP. Use versões async quando existirem e mantenha chamadas bloqueantes fora do event loop. Django pode adaptar código, mas alternâncias frequentes têm custo e dificultam o raciocínio. Nosso guia completo de Django cobre a estrutura do framework.
Servidores e implantação
Em WSGI, Gunicorn é uma escolha comum em sistemas Unix, frequentemente atrás de um proxy reverso. Em ASGI, Uvicorn, Daphne e Hypercorn implementam o protocolo. Gunicorn também pode gerenciar processos com um worker ASGI compatível, conforme a documentação das versões instaladas. No Windows, escolha um servidor com suporte explícito ao ambiente.
O proxy termina TLS, define limites de corpo e timeouts e encaminha cabeçalhos confiáveis. Configure corretamente IP e esquema quando houver proxy, sem confiar cabeçalhos enviados diretamente por clientes. Faça graceful shutdown, health checks e limites de concorrência. Para WebSockets, confirme suporte a upgrade e timeouts de conexão ociosa em toda a cadeia.
Erros comuns
- Trocar para ASGI esperando acelerar código de CPU ou queries lentas.
- Chamar
requests, drivers síncronos ou funções pesadas dentro de uma view async. - Executar servidor de desenvolvimento em produção.
- Presumir que um único event loop dispensa múltiplos processos e limites.
- Migrar sem verificar middleware e bibliotecas nas fronteiras sync/async.
- Usar tarefas internas do processo para trabalho que exige entrega confiável.
Meça latência percentil, throughput, erros, uso de CPU, conexões e saturação do banco. Teste desconexões e cancelamento em streaming. Uma aplicação ASGI que bloqueia o loop pode ter desempenho pior que a versão WSGI bem dimensionada.
Perguntas frequentes
ASGI é sempre mais rápido que WSGI?
Não. ASGI pode lidar melhor com muita espera concorrente, mas banco, código, configuração e carga determinam o resultado. Para CPU, processos ou jobs separados continuam necessários.
Posso executar uma aplicação WSGI em servidor ASGI?
Adaptadores existem, mas não adicionam semântica async ao código e podem introduzir custo. Prefira a interface nativa do framework quando possível.
Django precisa de ASGI para views async?
Views async podem ser adaptadas sob WSGI, mas uma pilha ASGI preserva melhor os benefícios de conexões assíncronas e recursos de longa duração.
Qual interface devo usar em um projeto novo?
Use a interface principal do framework e os requisitos do produto. FastAPI aponta para ASGI; uma aplicação Django síncrona pode escolher qualquer uma, sem migrar apenas por tendência.
Conclusão
WSGI continua sendo uma solução sólida para aplicações HTTP síncronas. ASGI amplia o contrato para concorrência assíncrona, streaming e WebSockets, mas exige uma cadeia não bloqueante e operação cuidadosa. Escolha pelo protocolo necessário e pelo perfil de espera, valide bibliotecas, selecione um servidor de produção e meça a carga real. A melhor opção é a mais simples que atende aos requisitos sem ocultar gargalos.