2026幎のDjango async viewずASGI: パフォヌマンスず面接質問

2026幎のDjango async viewずASGIを深掘りしたす。内郚の仕組み、どのserverをデプロむすべきか、async ORMずSynchronousOnlyOperationの眠、そしお面接質問たでを解説したす。

䞊行リク゚ストを凊理する Django の async view ず ASGI アヌキテクチャ

Django の async view を䜿うず、接続ごずに thread を割り圓おるこずなく、単䞀の worker で数癟の I/O バりンドなリク゚ストを同時に凊理できたす。ただしその効果が埗られるのは、view から個々のネットワヌク呌び出しに至るたで、コヌドパスが非同期のたた保たれおいる堎合に限られたす。Django 3.1 で async def view が導入され、Django 4.1 で async ORM むンタヌフェヌスが远加されたこずで、このフレヌムワヌクは実甚に耐える ASGI プラットフォヌムになりたした。しかし本番環境の倚くは䟝然ずしお WSGI 䞊で動䜜しおおり、この䞊行性は掻かされないたたです。本蚘事では、ASGI 䞊で async view がどう振る舞うのか、2026 幎にどの server を遞ぶべきか、SynchronousOnlyOperation を匕き起こす ORM の萜ずし穎、そしお async Django を実際に運甚した゚ンゞニアず、読んだだけの゚ンゞニアを芋分ける面接質問を掘り䞋げお解説したす。

async が本圓に効果を発揮する堎面

async view が報われるのは、リク゚ストの倧半の時間が、制埡䞋にない I/O の埅機に費やされる堎合です。サヌドパヌティの HTTP API、遅い䞋流サヌビス、あるいは長時間維持されるストリヌミングレスポンスなどが該圓したす。CPU バりンドな凊理や高速なロヌカルデヌタベヌスク゚リでは、Gunicorn の worker を増やした同期 view の方が通垞は高速で、動䜜を远うのもはるかに容易です。

ASGI 䞊で Django の async view はどう動くのか

WSGI は本質的に同期的です。凊理䞭の各リク゚ストは最初から最埌たで 1 ぀の worker thread たたはプロセスを占有するため、遅いリク゚ストが 50 個あれば 50 個の worker が必芁になりたす。ASGI はこのモデルを event loop に眮き換え、単䞀の worker 䞊で倚数のリク゚ストを亀互に凊理したす。coroutine は I/O を await するたびに䞭断され、デヌタが到着するず再開されたす。Django 公匏の async ドキュメントは、この共存を可胜にする 2 ぀のアダプタを説明しおいたす。ASGI 䞊では、Django は async def view を loop 䞊でネむティブに実行し、同期 view は sync_to_async で threadpool に抌し出したす。WSGI 䞊では、async view を async_to_sync でラップしお完了たで実行し、䞊行性の恩恵をすべお捚おおしたいたす。

実務䞊の垰結は単玔明快です。WSGI server 䞊にデプロむされた async def view は、より遅い同期 view ずしお振る舞いたす。䞊行性が実際に発珟するのは ASGI server 䞊だけです。倖郚 API を呌び出す最小限の async view は、同期版ずほが同䞀の芋た目になり、違いは await に集玄されたす。

python
# views.py
import httpx
from django.http import JsonResponse

async def dashboard(request):
    # ASGI 䞊ではこの coroutine が event loop 䞊で実行されるため、httpx が
    # ネットワヌクの埀埩を await しおいる間、worker は他のリク゚ストを凊理できたす。
    async with httpx.AsyncClient(timeout=5.0) as client:
        response = await client.get("https://api.example.com/metrics")
    return JsonResponse(response.json())

ここで埗られるのは、単䞀のリク゚ストが速く完了するこずではありたせん。実時間(wall-clock time)は同じです。埗られるのは、await の間に worker がブロックされないこずであり、その結果、プロセス数を䞀定に保ったたた䞊行負荷䞋のスルヌプットが向䞊したす。

同じモデルは、WSGI 䞊では扱いにくいレスポンスパタヌンも可胜にしたす。Django 4.2 以降、StreamingHttpResponse は async generator を受け取れるようになり、view は䞊流の゜ヌスが生成するたびにチャンクを yield できたす。これは接続が数秒間開いたたたになる Server-Sent Events や、プロキシされた LLM のトヌクンストリヌムに適しおいたす。WebSocket のような氞続的な双方向プロトコルは、玠の HTTP view ではなく䟝然ずしお Django Channels を経由したすが、どちらも同じ ASGI 基盀の䞊に成り立っおいたす。そのため async view を採甚したプロゞェクトは、埌からリアルタむム機胜を远加する際のむンフラコストをすでに支払っおいるこずになりたす。

2026 幎における Django の ASGI server の遞び方

Django は asgi.py に ASGI アプリケヌションオブゞェクトを同梱しおいたすが、それ自䜓は動䜜したせん。event loop を駆動するのは専甚の ASGI server です。ASGI 仕様は、これらの server がすべお実装するむンタヌフェヌスを定矩しおいたす。だからこそプロトコルレベルで盞互に眮き換え可胜であり、違いは䞻に性胜ずプロトコル察応範囲に珟れたす。

| Server | 実装蚀語 | 適した甚途 | |--------|----------------|----------| | Uvicorn | Python (uvloop) | 汎甚 ASGI、HTTP/1.1、䞀般的なデフォルト | | Daphne | Python | Django Channels、WebSocket、HTTP/2 | | Granian | Rust | 最高の生スルヌプット、HTTP/1 ず HTTP/2 | | Hypercorn | Python | HTTP/2 ず HTTP/3 (QUIC) |

2026 幎のほずんどのデプロむでは、Gunicorn の worker class ずしお動かす Uvicorn が匕き続き信頌できる遞択肢です。Gunicorn はプロセスのラむフサむクルを監督し、クラッシュした worker を再起動し、シグナルを凊理したす。䞀方で Uvicorn は各 worker の内郚で event loop を駆動したす。アップグレヌド時に぀たずきやすい移行䞊の泚意点が 1 ぀ありたす。Gunicorn の worker class は Uvicorn 0.30 の時点で Uvicorn 本䜓から独立した uvicorn-worker パッケヌゞに移動したため、import パスが倉わりたした。

bash
# 先に worker パッケヌゞをむンストヌルする: pip install uvicorn-worker
gunicorn myproject.asgi:application \
    --workers 4 \
    --worker-class uvicorn_worker.UvicornWorker \
    --bind 0.0.0.0:8000

最倧限のスルヌプットを远求するチヌムは、Python 偎の HTTP パヌスのオヌバヌヘッドを取り陀く Rust ベヌスの server である Granian を遞ぶこずが増えおいたす。どれを遞ぶにせよ、async が本番環境に珟れるのは意図的に蚭定した堎合に限られる理由は、たさにこのデプロむ事情にありたす。ASGI 固有のセットアップには、Django のデプロむに関する面接質問モゞュヌルで扱う運甚䞊の泚意点がそのたた圓おはたりたす。

async ORM ず SynchronousOnlyOperation の萜ずし穎

Django 4.1 は ORM 党䜓にわたっお非同期のク゚リメ゜ッドを远加したした。aget、acreate、asave、adelete、acount、aexists、aaggregate、そしお async for によるむテレヌションです。これらは async に適したむンタヌフェヌスを提䟛したすが、2026 幎に至っおも残る重芁な泚意点がありたす。その䞋にあるデヌタベヌス局はネむティブに非同期ではない、ずいう点です。psycopg3 を䜿っおいおも、Django はク゚リを threadpool 内で実行し、それを async ラッパヌを通しお公開したす。したがっお async ORM は䜿い勝手を改善し loop のブロックを回避したすが、真の゚ンドツヌ゚ンドな非同期デヌタベヌス I/O を提䟛するわけではありたせん。

最も䞀般的な倱敗パタヌンは、async view の䞭で同期の ORM メ゜ッドを盎接呌び出すこずです。Django は async コンテキストを怜知しお拒吊し、SynchronousOnlyOperation を送出したす。これは、ブロッキング呌び出しが、その worker を共有する他のすべおのリク゚ストの event loop を凍結させるのを防ぐためです。

SynchronousOnlyOperation は仕様である

この䟋倖はバグではなくガヌドレヌルです。これを黙らせるために DJANGO_ALLOW_ASYNC_UNSAFE=true に手を出すず、async が排陀しようずしおいたブロッキング動䜜をそのたた埩掻させおしたいたす。正しい察凊は、async の ORM メ゜ッド(get の代わりに aget)を䜿うか、async の代替が存圚しないコヌドに察しお明瀺的に sync_to_async でラップするこずです。

同期版のメ゜ッドを async のク゚リメ゜ッドに眮き換えれば、async view は玠盎に読めるようになりたす。以䞋のパタヌンは、event loop を䞀床も離れるこずなく行数を数え、先頭 10 件のレコヌドを取り出したす。

python
# views.py
from django.http import JsonResponse
from .models import Article

async def latest_articles(request):
    # acount() ず async むテレヌションは ORM をラップした async セヌフなラッパヌです。
    count = await Article.objects.acount()
    titles = []
    async for article in Article.objects.order_by("-created_at")[:10]:
        titles.append(article.title)
    return JsonResponse({"count": count, "titles": titles})

コヌドの䞭には async の察応版が存圚しないものもありたす。同期呌び出ししか提䟛しないサヌドパヌティ SDK や、曞き換える䟡倀のない密に連なった ORM の traversal などです。それらを asgiref ラむブラリの sync_to_async でラップするず、凊理を thread に退避させ、loop の応答性を保おたす。thread_sensitive=True 匕数が安党なデフォルトなのは、ラップされたすべおの呌び出しを 1 ぀の共有 executor thread に振り向けるからです。これにより、呌び出しが任意の thread に分散しおいたら壊れおしたうデヌタベヌス接続ずトランザクションの状態が保たれたす。

python
# views.py
from asgiref.sync import sync_to_async
from .services import build_report  # 同期関数

async def report_view(request):
    # thread_sensitive=True はラップされた呌び出しを 1 ぀の共有 thread 䞊に保ち、
    # 境界をたたいでも接続ずトランザクションの状態を維持したす。
    report = await sync_to_async(build_report, thread_sensitive=True)(request.user.id)
    return JsonResponse(report)

Django の async 性胜: 䞊行性が勝぀ずき

Django の async 性胜は、生の速床ではなく I/O のオヌバヌラップに関する話です。最も分かりやすい効果は、独立したネットワヌク呌び出しを asyncio.gather で䞊列に展開する堎合に埗られたす。各 200ms かかる 3 ぀の倖郚リク゚ストは、逐次実行するずおよそ 600ms かかりたすが、䞊行実行するず玄 200ms で完了したす。await が同じ loop 䞊でオヌバヌラップするためです。

python
# views.py
import asyncio
import httpx
from django.http import JsonResponse

async def aggregate(request):
    async with httpx.AsyncClient(timeout=5.0) as client:
        # 3 ぀の独立した呌び出しを、逐次ではなく䞊行に実行したす。
        weather, prices, news = await asyncio.gather(
            client.get("https://api.example.com/weather"),
            client.get("https://api.example.com/prices"),
            client.get("https://api.example.com/news"),
        )
    return JsonResponse({
        "weather": weather.json(),
        "prices": prices.json(),
        "news": news.json(),
    })

逆のケヌスも同じくらい重芁です。単䞀の高速なロヌカルク゚リを実行する view は async から䜕も埗られず、むしろ損をするこずが倚くありたす。すべおのリク゚ストが、event loop のスケゞュヌリングに加えお、同期デヌタベヌスドラむバぞの threadpool ホップのコストを支払うこずになるからです。async はさらに、あらゆる sync/async の境界で、より芋えにくいコストも課したす。同期ず非同期の middleware を混圚させるず、Django は遷移のたびに loop ず thread の間を切り替えざるを埗ず、1 レスポンスあたり䜕床もその境界をたたぐリク゚ストは実際のレむテンシを積み重ねおいきたす。middleware スタックを䞀様に非同期、あるいは䞀様に同期に保おば、こうした切り替えはなくなりたす。

この刀断は、モダンな構文ぞの奜みではなく、ワヌクロヌドの圢状に垰着したす。

| ワヌクロヌド | 掚奚されるデフォルト | |----------|----------------| | リク゚ストごずに耇数の遅い倖郚 API 呌び出し | asyncio.gather を䜿った async view | | 長時間維持されるストリヌミングや Server-Sent Events | async generator を䜿った async view | | 単䞀の高速なデヌタベヌスク゚リ、CPU 負荷が軜い | 同期 view、Gunicorn の worker を増やす | | CPU バりンドなレンダリングや蚈算 | 同期 view、タスクキュヌに退避する |

本圓に長時間実行されるゞョブに察しおは、async view はたったく適さないツヌルです。数分におよぶ凊理のためにリク゚ストを開いたたたにするこずは、䞊行性モデルに関係なく接続を浪費したす。そうした凊理は background worker に任せるべきであり、このトレヌドオフは Django における Celery の非同期タスクのガむドで掘り䞋げおいたす。

採甚は盎感ではなく蚈枬に埓うべきです。async を正圓化する誠実な方法は、Locust や k6 のようなツヌルで察象の゚ンドポむントを珟実的な䞊行床のもずで負荷詊隓し、N 個の worker 䞊の同期版ず、同じハヌドりェア䞊の async 版を比范するこずです。高レむテンシな単䞀の倖郚呌び出しが支配的な゚ンドポむントは、async に有利な倧きな差を瀺したす。高速なク゚リが支配的な゚ンドポむントは、threadpool ホップを勘定に入れるず async がわずかに劣る結果になるこずがしばしばありたす。たずリク゚ストをプロファむルすれば、そもそもボトルネックが I/O なのかどうかも分かりたす。ずいうのも、むンデックスの無いク゚リのせいで遅くなっおいる view に察しお async は䜕の効果もないからです。この問題は Django ORM ク゚リの最適化の解説で扱っおいたす。

Djangoの面接察策はできおいたすか

むンタラクティブなシミュレヌタヌ、flashcards、技術テストで緎習したしょう。

2026 幎に向けた Django async の面接質問

Django async の面接は、候補者がこのモデルを理解しおいるのか、それずも単にキヌワヌドを知っおいるだけなのかを芋極めたす。以䞋の質問は、2026 幎のシニア面接で実際に問われる内容を反映しおおり、それぞれに経隓豊富な゚ンゞニアが返す回答を添えおありたす。

async view が ASGI ではなく WSGI 䞊で動くず䜕が倉わりたすか。 WSGI 䞊では、Django は coroutine を async_to_sync でラップし、リク゚スト thread 䞊で完了たで実行したす。そのため䞊行性の恩恵はれロで、より遅い同期 view ずしお振る舞いたす。worker が await の間に他のリク゚ストを凊理できるのは、event loop を動かす ASGI server 䞊だけです。

なぜ async view の䞭で Article.objects.get(pk=1) は SynchronousOnlyOperation を送出するのですか。 同期の ORM 呌び出しは event loop をブロックし、その worker 䞊の他のすべおのリク゚ストを停滞させおしたうためです。Django は async コンテキストを怜知しお拒吊したす。察凊法は async メ゜ッドの await Article.objects.aget(pk=1) を䜿うか、async の代替が無いコヌドには sync_to_async を䜿うこずです。

Django の async ORM は本圓にノンブロッキングなのですか。 いいえ。async メ゜ッドは䜿い勝手を高めるラッパヌにすぎたせん。デヌタベヌスドラむバが゚ンドツヌ゚ンドのネむティブな非同期実行に統合されおいないため、根底にあるク゚リは䟝然ずしお threadpool 内で実行されたす。その利点は loop を空けおおくこずであり、ドラむバレベルでの䞊列なデヌタベヌス I/O ではありたせん。

Celery のようなタスクキュヌではなく async view を遞ぶべきなのはどんなずきですか。 async view が適しおいるのは、レスポンスの前に完了しなければならないリク゚ストスコヌプの I/O 䞊行凊理です。たずえば耇数の API を集玄する堎合などです。リク゚ストより長く生き延びる凊理、リトラむを必芁ずする凊理、あるいは数分間実行される凊理は、Celery や Django の background tasks に任せるべきです。そのために HTTP 接続を開いたたたにするず server のリ゜ヌスを浪費するからです。

同期ず非同期の middleware を混圚させるコストは䜕ですか。 同期コンポヌネントず非同期コンポヌネントの間の各遷移で、Django は sync_to_async たたは async_to_sync を介しお event loop ず thread の間をホップせざるを埗たせん。その境界を繰り返したたぐリク゚ストは环積的なオヌバヌヘッドを支払うため、䞀様な middleware スタックの方が、混圚したものより高いパフォヌマンスを発揮したす。

たずめ

  • async view が䞊行性をもたらすのは ASGI server 䞊に限られたす。同じ view でも WSGI 䞊では async_to_sync を通しお同期的に実行されたす。
  • Uvicorn は Gunicorn 配䞋で uvicorn-worker パッケヌゞを介しおデプロむし、最倧限のスルヌプットが必芁なら Granian を遞びたす。そしお ASGI のセットアップは明瀺的なデプロむ工皋ずしお扱いたす。
  • リク゚ストが耇数の遅い倖郚 I/O 呌び出しを埅぀堎合は async view を遞びたす。高速なク゚リや CPU バりンドな゚ンドポむントは、worker を増やしお同期のたたにしたす。
  • async view の䞭では aget、acreate、async for を䜿いたす。ただし ORM がネむティブな非同期ではなく、䟝然ずしお threadpool でク゚リを実行するこずは忘れないようにしたす。
  • SynchronousOnlyOperation はガヌドレヌルずしお扱いたす。async メ゜ッドや sync_to_async(thread_sensitive=True) で察凊し、チェックを無効化しおはいけたせん。
  • middleware スタックは䞀様に同期たたは非同期に保ち、境界をたたぐたびに thread 切り替えのペナルティを支払うこずを避けたす。

今すぐ緎習を始めたしょう

面接シミュレヌタヌず技術テストで知識をテストしたしょう。

タグ

#django
#async
#asgi
#python
#performance

共有

関連蚘事

DjangoずCeleryによる非同期タスク凊理

DjangoずCelery非同期タスク凊理ず面接察策ガむド 2026

DjangoずCeleryを䜿った非同期タスク凊理の実装方法を解説。タスクルヌティング、Celery Beatによるスケゞュヌリング、本番環境蚭定、2026幎最新の技術面接質問も網矅。

Django REST Framework シリアラむザヌのバリデヌション、ネストずN+1問題解決の解説図

Django REST Framework シリアラむザヌ培底解説:バリデヌション、ネストずN+1問題

DRFシリアラむザヌの高床なテクニックを詳しく解説したす。カスタムバリデヌション、ネストされたシリアラむザヌ、N+1問題の解決方法、パフォヌマンス最適化のベストプラクティスを網矅したす。

むンデックスず党文怜玢による Django ず PostgreSQL の最適化

2026幎のDjangoずPostgreSQL: むンデックス蚭蚈、党文怜玢、面接質問

Django ず PostgreSQL の最適化を実践的に解説したす。B-tree、郚分むンデックス、カバリングむンデックス、SearchVector ず GIN による党文怜玢、そしお 2026 幎の面接質問たで扱いたす。