# Django Async View'ler ve ASGI (2026): Performans ve Mülakat Soruları > 2026'da Django async view'ler ve ASGI üzerine derinlemesine bir inceleme: perde arkasında nasıl çalıştıkları, hangi sunucunun tercih edileceği, async ORM ile SynchronousOnlyOperation tuzağı ve mülakat soruları. - Published: 2026-07-03 - Updated: 2026-07-07 - Author: SharpSkill - Tags: django, async, asgi, python, performance - Reading time: 10 min --- Django async view'ler, kod yolu view'den her ağ çağrısına kadar asenkron kaldığı sürece tek bir worker'ın her bağlantıya ayrı bir thread ayırmadan yüzlerce eşzamanlı I/O bağımlı isteği işlemesine olanak tanır. Django 3.1 ile `async def` view'ler, Django 4.1 ile de async ORM arayüzü geldiğinden bu yana framework güvenilir bir ASGI platformu hâline geldi; ancak çoğu production dağıtımı hâlâ WSGI altında çalışıyor ve bu eşzamanlılığı kullanılmadan bırakıyor. Bu derinlemesine inceleme, async view'lerin ASGI altında nasıl davrandığını, 2026'da hangi sunucuların çalıştırılacağını, `SynchronousOnlyOperation` hatasını fırlatan ORM tuzaklarını ve async Django'yu gerçekten canlıya almış mühendisleri yalnızca okumuş olanlardan ayıran mülakat sorularını açıklıyor. > **Async Gerçekten Ne Zaman İşe Yarar** > > Async view'ler, bir istek zamanının büyük kısmını kontrol edemediği bir I/O'yu beklerken geçirdiğinde işe yarar: üçüncü taraf HTTP API'leri, yavaş downstream servisler veya uzun ömürlü streaming yanıtları. CPU bağımlı işler ya da hızlı yerel veritabanı sorguları için, daha fazla Gunicorn worker ile desteklenen senkron bir view genellikle hem daha hızlıdır hem de üzerinde akıl yürütmesi çok daha basittir. ## Django Async View'ler ASGI Altında Nasıl Çalışır WSGI temelde senkrondur: her aktif istek baştan sona bir worker thread'ini veya process'ini işgal eder, dolayısıyla 50 yavaş istek 50 worker gerektirir. ASGI bu modeli, tek bir worker üzerinde birçok isteği iç içe geçiren bir event loop ile değiştirir; bir coroutine bir I/O'yu await ettiğinde onu askıya alır ve veri geldiğinde kaldığı yerden devam ettirir. [Resmî Django async dokümantasyonu](https://docs.djangoproject.com/en/5.2/topics/async/), bu bir arada çalışmayı mümkün kılan iki adaptörü açıklar: ASGI altında Django `async def` view'leri doğrudan loop üzerinde çalıştırır ve senkron view'leri `sync_to_async` ile bir threadpool'a taşır; WSGI altında ise async view'leri `async_to_sync` ile sarmalayıp tamamlanana kadar çalıştırır ve tüm eşzamanlılık kazanımını harcar. Pratik sonuç açıktır: bir WSGI sunucusunda dağıtılan bir `async def` view, daha yavaş bir senkron view gibi davranır. Eşzamanlılık yalnızca bir ASGI sunucusunda ortaya çıkar. Harici bir API'yi çağıran minimal bir async view, farkın `await` üzerinde yoğunlaştığı senkron karşılığıyla neredeyse aynı görünür. ```python # views.py import httpx from django.http import JsonResponse async def dashboard(request): # ASGI altında bu coroutine event loop üzerinde çalışır, böylece worker # httpx ağ turunu await ederken diğer istekleri karşılamakta serbesttir. async with httpx.AsyncClient(timeout=5.0) as client: response = await client.get("https://api.example.com/metrics") return JsonResponse(response.json()) ``` Buradaki kazanım tek bir isteğin daha hızlı bitmesi değildir; istek aynı süreyi alır. Kazanım, worker'ın `await` sırasında bloklanmamasıdır; böylece eşzamanlı yük altında throughput artarken process sayısı sabit kalır. Aynı model, WSGI altında zahmetli olan yanıt kalıplarının önünü açar. Django 4.2'den itibaren `StreamingHttpResponse` bir async generator kabul eder; böylece bir view, bir upstream kaynak parçaları ürettikçe onları yield edebilir. Bu, bağlantının saniyelerce açık kaldığı Server-Sent Events ve proxy'lenen LLM token akışları için uygundur. WebSockets gibi kalıcı çift yönlü protokoller hâlâ düz HTTP view'ler yerine Django Channels üzerinden yönlendirilir; ancak her ikisi de aynı ASGI temeline dayanır, dolayısıyla async view'leri benimseyen bir proje, ileride eklenecek gerçek zamanlı özellikler için altyapı bedelini şimdiden ödemiştir. ## 2026'da Django ASGI Sunucusu Seçmek Django, `asgi.py` içinde bir ASGI uygulama nesnesi sağlar; ancak bu nesne kendi kendine çalışmaz, event loop'u ayrı bir ASGI sunucusu sürer. [ASGI spesifikasyonu](https://asgi.readthedocs.io/en/latest/), bu sunucuların her birinin uyguladığı arayüzü tanımlar; bu yüzden protokol düzeyinde birbirlerinin yerine kullanılabilirler ve temelde performans ile protokol kapsamı bakımından farklılaşırlar. | Sunucu | Geliştirildiği dil | En uygun kullanım | |--------|----------------|----------| | Uvicorn | Python (uvloop) | Genel ASGI, HTTP/1.1, yaygın varsayılan | | Daphne | Python | Django Channels, WebSockets, HTTP/2 | | Granian | Rust | En yüksek ham throughput, HTTP/1 ve HTTP/2 | | Hypercorn | Python | HTTP/2 ve HTTP/3 (QUIC) | 2026'daki çoğu dağıtım için, bir Gunicorn worker sınıfı olarak çalıştırılan [Uvicorn](https://www.uvicorn.org/) güvenilir seçim olmaya devam ediyor: Gunicorn process yaşam döngüsünü denetler, çöken worker'ları yeniden başlatır ve sinyalleri işlerken Uvicorn her worker'ın içinde event loop'u sürer. Bir migration ayrıntısı yükseltmeleri zorlar: Uvicorn 0.30 itibarıyla Gunicorn worker sınıfları Uvicorn çekirdeğinden çıkarılıp ayrı bir `uvicorn-worker` paketine taşındı, dolayısıyla import yolu değişti. ```bash # Önce worker paketini kurun: pip install uvicorn-worker gunicorn myproject.asgi:application \ --workers 4 \ --worker-class uvicorn_worker.UvicornWorker \ --bind 0.0.0.0:8000 ``` Maksimum throughput peşindeki ekipler giderek daha çok, Python tarafındaki HTTP ayrıştırma yükünü ortadan kaldıran Rust tabanlı bir sunucu olan Granian'a yöneliyor. Seçim ne olursa olsun, dağıtım süreci, async'in yalnızca bilinçli olarak yapılandırıldığında production'da görünmesinin nedenidir; ASGI'ye özgü kurulum, [Django deployment mülakat soruları](/technologies/django/interview-questions/django-deployment) modülünde ele alınan operasyonel özeni yansıtır. ## Async ORM ve SynchronousOnlyOperation Tuzağı Django 4.1, ORM genelinde asenkron sorgu metotları ekledi: `aget`, `acreate`, `asave`, `adelete`, `acount`, `aexists`, `aaggregate` ve `async for` ile iterasyon. Bunlar async dostu bir yüzey sunar; ancak kritik bir uyarı 2026'ya kadar geçerliliğini koruyor: alttaki veritabanı katmanı doğası gereği asenkron değildir. psycopg3 ile bile Django sorguları bir threadpool içinde yürütür ve onları async wrapper'lar aracılığıyla sunar; dolayısıyla async ORM, gerçek uçtan uca async veritabanı I/O'su sağlamadan ergonomiyi iyileştirir ve loop'u bloklamaktan kaçınır. En yaygın hata biçimi, bir async view içinde doğrudan senkron bir ORM metodu çağırmaktır. Django async bağlamı algılar ve reddeder; bloklayan bir çağrının, o worker'ı paylaşan diğer tüm istekler için event loop'u dondurmasını önlemek amacıyla `SynchronousOnlyOperation` fırlatır. > **SynchronousOnlyOperation Bir Özelliktir** > > Bu istisna bir hata değil, bir koruma bariyeridir. Onu susturmak için `DJANGO_ALLOW_ASYNC_UNSAFE=true`'ya başvurmak, tam da async'in ortadan kaldırmayı amaçladığı bloklama davranışını geri getirir. Doğru çözüm, bir async ORM metodudur (`get` yerine `aget`) veya async karşılığı olmayan kodun etrafına açıkça bir `sync_to_async` wrapper'ı koymaktır. Async sorgu metotları senkron ikizlerinin yerini aldığında async view'ler temiz okunur. Aşağıdaki kalıp, event loop'tan hiç çıkmadan satırları sayar ve ilk on kaydı akıtır. ```python # views.py from django.http import JsonResponse from .models import Article async def latest_articles(request): # acount() ve async iterasyon, ORM etrafındaki async-güvenli wrapper'lardır. 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}) ``` Bazı kodların async karşılığı yoktur: yalnızca senkron çağrılar sunan üçüncü taraf bir SDK ya da yeniden yazmaya değmeyecek yoğun bir ORM gezinme zinciri. Bunu [asgiref kütüphanesindeki](https://github.com/django/asgiref) `sync_to_async` ile sarmalamak, işi bir thread'e devreder ve loop'u yanıt verebilir tutar. `thread_sensitive=True` argümanı güvenli varsayılandır; çünkü sarmalanan her çağrıyı tek bir paylaşılan executor thread'ine yönlendirir ve çağrılar gelişigüzel thread'lere dağılsaydı bozulacak olan veritabanı bağlantısı ile transaction durumunu korur. ```python # views.py from asgiref.sync import sync_to_async from .services import build_report # senkron bir fonksiyon async def report_view(request): # thread_sensitive=True sarmalanan çağrıları tek bir paylaşılan thread'de tutar, # sınır boyunca bağlantı ve transaction durumunu korur. report = await sync_to_async(build_report, thread_sensitive=True)(request.user.id) return JsonResponse(report) ``` ## Django Async Performansı: Eşzamanlılık Ne Zaman Kazanır Django async performansı ham hızla değil, I/O örtüşmesiyle ilgili bir konudur. En net kazanım, bağımsız ağ çağrılarını `asyncio.gather` ile dağıtmaktan gelir: her biri 200ms süren üç harici istek sırayla yaklaşık 600ms tutar; ancak eşzamanlı olarak yaklaşık 200ms'de tamamlanır, çünkü await'ler aynı loop üzerinde örtüşür. ```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: # Üç bağımsız çağrı birbiri ardına değil, eşzamanlı olarak çalışır. 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(), }) ``` Tersi durum da en az onun kadar önemlidir. Tek bir hızlı yerel sorgu çalıştıran bir view, async'ten hiçbir şey kazanmaz ve çoğu zaman kaybeder; çünkü artık her istek, event loop zamanlaması ile senkron veritabanı sürücüsüne yapılan bir threadpool sıçraması bedelini öder. Async ayrıca her sync/async sınırında daha ince bir bedel dayatır: senkron ve asenkron middleware'i karıştırmak, Django'yu her geçişte loop ile bir thread arasında geçiş yapmaya zorlar ve yanıt başına bu çizgiyi birkaç kez aşan bir istek gerçek gecikme biriktirir. Middleware yığınını tümüyle async ya da tümüyle sync tutmak bu geçişleri ortadan kaldırır. Karar, modern söz dizimine duyulan bir tercihe değil, iş yükünün biçimine indirgenir. | İş yükü | Daha iyi varsayılan | |----------|----------------| | İstek başına birden çok yavaş harici API çağrısı | `asyncio.gather` ile async view | | Uzun ömürlü streaming veya Server-Sent Events | Async generator ile async view | | Tek hızlı veritabanı sorgusu, düşük CPU | Sync view, daha fazla Gunicorn worker | | CPU bağımlı render veya hesaplama | Sync view, işi bir task queue'ya devret | Gerçekten uzun süren işler için async view'ler tümüyle yanlış araçtır; dakikalarca sürecek bir işi yapmak için bir isteği açık tutmak, eşzamanlılık modelinden bağımsız olarak bağlantıyı boşa harcar. Bu iş, bir background worker'a aittir; bu ödünleşim [Django'da Celery async görevleri](/blog/django/django-celery-async-tasks-interview-2026) rehberinde ele alınmıştır. Benimseme, sezgiyi değil ölçümü izlemelidir. Async'i haklı çıkarmanın dürüst yolu, ilgili endpoint'i Locust veya k6 gibi bir araçla gerçekçi eşzamanlılık altında yük testine tabi tutmak ve N worker üzerindeki senkron bir sürümü, aynı donanımdaki bir async sürümle karşılaştırmaktır. Yüksek gecikmeli tek bir harici çağrının hâkim olduğu endpoint'ler async lehine geniş bir fark gösterir; hızlı sorguların hâkim olduğu endpoint'lerde ise, threadpool sıçraması hesaba katıldığında async çoğu zaman biraz geride kalır. İsteği önce profillemek, darboğazın gerçekten I/O olup olmadığını da ortaya koyar; çünkü async, indekssiz sorgular yüzünden yavaş olan bir view için hiçbir şey yapmaz. Bu sorun [Django ORM sorgularını optimize etme](/blog/django/django-orm-optimizing-queries) anlatımında ele alınmıştır. ## 2026 İçin Django Async Mülakat Soruları Bir Django async mülakatı, bir adayın modeli mi anladığını yoksa yalnızca anahtar kelimeleri mi tanıdığını yoklar. Aşağıdaki sorular, 2026'da senior mülakatlarının gerçekten ne sorduğunu yansıtır ve her biri deneyimli bir mühendisin vereceği yanıtla eşleştirilmiştir. **Bir async view, ASGI yerine WSGI altında çalıştığında ne değişir?** WSGI altında Django, coroutine'i `async_to_sync` ile sarmalar ve onu istek thread'inde tamamlanana kadar çalıştırır; dolayısıyla sıfır eşzamanlılık kazanımıyla daha yavaş bir senkron view gibi davranır. Yalnızca bir event loop çalıştıran bir ASGI sunucusu, worker'ın bir `await` sırasında diğer istekleri karşılamasına izin verir. **Bir async view içinde `Article.objects.get(pk=1)` neden `SynchronousOnlyOperation` fırlatır?** Senkron ORM çağrısı event loop'u bloklar ve o worker üzerindeki diğer tüm istekleri durdururdu. Django async bağlamı algılar ve reddeder. Çözüm, async metot olan `await Article.objects.aget(pk=1)` ya da async karşılığı olmayan kod için `sync_to_async`'tir. **Django'nun async ORM'i gerçekten bloklamayan mıdır?** Hayır. Async metotlar ergonomik wrapper'lardır; alttaki sorgular hâlâ bir threadpool içinde çalışır, çünkü veritabanı sürücüleri uçtan uca native async yürütme için entegre değildir. Kazanım, sürücü düzeyinde paralel veritabanı I/O'su değil, loop'u serbest tutmaktır. **Async view'ler, Celery gibi bir task queue yerine ne zaman tercih edilmelidir?** Async view'ler, birkaç API'yi bir araya getirmek gibi, yanıttan önce bitmesi gereken istek kapsamlı I/O eşzamanlılığı için uygundur. İstekten daha uzun yaşayan, retry gerektiren ya da dakikalarca çalışan işler Celery'ye veya Django'nun background görevlerine aittir; çünkü bunun için bir HTTP bağlantısını açık tutmak sunucu kaynaklarını boşa harcar. **Sync ve async middleware'i karıştırmanın maliyeti nedir?** Bir sync ve bir async bileşen arasındaki her geçiş, Django'yu `sync_to_async` veya `async_to_sync` aracılığıyla event loop ile bir thread arasında sıçramaya zorlar. Bu sınırı tekrar tekrar aşan bir istek kümülatif ek yük öder; dolayısıyla tekdüze bir middleware yığını, iç içe geçmiş bir yığından daha iyi performans gösterir. ## Sonuç - Async view'ler eşzamanlılığı yalnızca bir ASGI sunucusunda sağlar; aynı view WSGI altında `async_to_sync` üzerinden senkron çalışır. - Uvicorn'u Gunicorn altında `uvicorn-worker` paketiyle ya da maksimum throughput için Granian'ı dağıtın ve ASGI kurulumunu açık bir dağıtım adımı olarak ele alın. - Bir istek birden çok yavaş harici I/O çağrısını beklediğinde async view'lere başvurun; hızlı sorgulu ve CPU bağımlı endpoint'leri daha fazla worker ile senkron tutun. - Async view'ler içinde `aget`, `acreate` ve `async for` kullanın ve ORM'in sorguları hâlâ native async yerine bir threadpool içinde çalıştırdığını unutmayın. - `SynchronousOnlyOperation`'ı bir koruma bariyeri olarak görün: onu async metotlarla ya da `sync_to_async(thread_sensitive=True)` ile çözün, asla kontrolü devre dışı bırakarak değil. - Her sınır geçişinde thread değişim cezası ödememek için middleware yığınını tümüyle sync ya da tümüyle async tutun. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/tr/blog/django/django-async-views-asgi-2026