{"title":"Asynchronous support","version":"6.1","locale":"en","docname":"topics/async","url":"/en/6.1/topics/async/","canonical":"https://djangodocs.dev/en/6.1/topics/async/","summary":"Django has support for writing asynchronous (“async”) views, along with an entirely async-enabled request stack if you are running under ASGI . Async views will…","html":"<h1>Asynchronous support<a class=\"heading-anchor\" href=\"#asynchronous-support\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Django has support for writing asynchronous (“async”) views, along with an\nentirely async-enabled request stack if you are running under <a class=\"reference internal\" href=\"/en/6.1/howto/deployment/asgi/\"><span class=\"doc\">ASGI</span></a>. Async views will still work under WSGI, but\nwith a small per-request adaptation cost (see <a class=\"reference internal\" href=\"#async-performance\"><span class=\"std std-ref\">Performance</span></a>), and\nwithout the ability to have efficient long-running requests.</p>\n<p>Many parts of Django provide asynchronous APIs, including <a class=\"reference internal\" href=\"/en/6.1/topics/db/queries/#async-queries\"><span class=\"std std-ref\">the ORM</span></a>, the cache framework, authentication, sessions, and signals.\nFor other code, the <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> adapter is a low-cost bridge (see\n<a class=\"reference internal\" href=\"#async-performance\"><span class=\"std std-ref\">Performance</span></a>). A wide range of async-native Python libraries can\nalso be integrated.</p>\n<section id=\"async-views\">\n<h2>Async views<a class=\"heading-anchor\" href=\"#async-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Any view can be declared async by making the callable part of it return a\ncoroutine - commonly, this is done using <code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">def</span></code>. For a function-based\nview, this means declaring the whole view using <code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">def</span></code>. For a\nclass-based view, this means declaring the HTTP method handlers, such as\n<code class=\"docutils literal notranslate\"><span class=\"pre\">get()</span></code> and <code class=\"docutils literal notranslate\"><span class=\"pre\">post()</span></code> as <code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">def</span></code> (not its <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code>, or\n<code class=\"docutils literal notranslate\"><span class=\"pre\">as_view()</span></code>).</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Django uses <code class=\"docutils literal notranslate\"><span class=\"pre\">inspect.iscoroutinefunction</span></code> to test if your view is\nasynchronous or not. If you implement your own method of returning a\ncoroutine, ensure you use <code class=\"docutils literal notranslate\"><span class=\"pre\">inspect.markcoroutinefunction</span></code> so this\nfunction returns <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>.</p>\n</aside>\n<p>Under a WSGI server, async views will run in their own, one-off event loop.\nThis means you can use async features, like concurrent async HTTP requests,\nwithout any issues, but you will not get the benefits of an async stack.</p>\n<p>The main benefits are the ability to service hundreds of connections without\nusing Python threads. This allows you to use slow streaming, long-polling, and\nother exciting response types.</p>\n<p>If you want to use these, you will need to deploy Django using\n<a class=\"reference internal\" href=\"/en/6.1/howto/deployment/asgi/\"><span class=\"doc\">ASGI</span></a> instead.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>A fully asynchronous request stack requires async middleware end-to-end.\nWhere a piece of synchronous middleware sits between an ASGI server and an\nasync view, Django adapts it by running it in its own thread; see\n<a class=\"reference internal\" href=\"#async-performance\"><span class=\"std std-ref\">Performance</span></a> for the cost trade-off.</p>\n<p>Django’s bundled middleware supports both <a class=\"reference internal\" href=\"/en/6.1/topics/http/middleware/#async-middleware\"><span class=\"std std-ref\">sync and async</span></a>. Third-party middleware may not. To see which\nmiddleware Django adapts, turn on debug logging for the <code class=\"docutils literal notranslate\"><span class=\"pre\">django.request</span></code>\nlogger and look for log messages about <em>“Asynchronous handler adapted for\nmiddleware …”</em>.</p>\n</aside>\n<p>In both ASGI and WSGI mode, you can still safely use asynchronous support to\nrun code concurrently rather than serially. This is especially handy when\ndealing with external APIs or data stores.</p>\n<p>If you want to call a part of Django that is still synchronous, you will need\nto wrap it in a <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> call. For example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">sync_to_async</span>\n\n<span class=\"n\">results</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"n\">sync_to_async</span><span class=\"p\">(</span><span class=\"n\">sync_function</span><span class=\"p\">,</span> <span class=\"n\">thread_sensitive</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)(</span><span class=\"n\">pk</span><span class=\"o\">=</span><span class=\"mi\">123</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>If you accidentally try to call a part of Django that is synchronous-only\nfrom an async view, you will trigger Django’s\n<a class=\"reference internal\" href=\"#async-safety\"><span class=\"std std-ref\">asynchronous safety protection</span></a> to protect your data from\ncorruption.</p>\n<section id=\"decorators\">\n<h3>Decorators<a class=\"heading-anchor\" href=\"#decorators\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The following decorators can be used with both synchronous and asynchronous\nview functions:</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/en/6.1/topics/http/decorators/#django.views.decorators.cache.cache_control\" title=\"django.views.decorators.cache.cache_control\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">cache_control()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/topics/http/decorators/#django.views.decorators.cache.never_cache\" title=\"django.views.decorators.cache.never_cache\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">never_cache()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/topics/http/decorators/#django.views.decorators.common.no_append_slash\" title=\"django.views.decorators.common.no_append_slash\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">no_append_slash()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/ref/csp/#django.views.decorators.csp.csp_override\" title=\"django.views.decorators.csp.csp_override\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csp_override()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/ref/csp/#django.views.decorators.csp.csp_report_only_override\" title=\"django.views.decorators.csp.csp_report_only_override\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csp_report_only_override()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/ref/csrf/#django.views.decorators.csrf.csrf_exempt\" title=\"django.views.decorators.csrf.csrf_exempt\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_exempt()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/ref/csrf/#django.views.decorators.csrf.csrf_protect\" title=\"django.views.decorators.csrf.csrf_protect\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">csrf_protect()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/ref/csrf/#django.views.decorators.csrf.ensure_csrf_cookie\" title=\"django.views.decorators.csrf.ensure_csrf_cookie\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">ensure_csrf_cookie()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/ref/csrf/#django.views.decorators.csrf.requires_csrf_token\" title=\"django.views.decorators.csrf.requires_csrf_token\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">requires_csrf_token()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/howto/error-reporting/#django.views.decorators.debug.sensitive_variables\" title=\"django.views.decorators.debug.sensitive_variables\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sensitive_variables()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/howto/error-reporting/#django.views.decorators.debug.sensitive_post_parameters\" title=\"django.views.decorators.debug.sensitive_post_parameters\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sensitive_post_parameters()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/topics/http/decorators/#django.views.decorators.gzip.gzip_page\" title=\"django.views.decorators.gzip.gzip_page\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">gzip_page()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/topics/http/decorators/#django.views.decorators.http.condition\" title=\"django.views.decorators.http.condition\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">condition()</span></code></a></p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">conditional_page()</span></code></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/topics/http/decorators/#django.views.decorators.http.etag\" title=\"django.views.decorators.http.etag\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">etag()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/topics/http/decorators/#django.views.decorators.http.last_modified\" title=\"django.views.decorators.http.last_modified\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">last_modified()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/topics/http/decorators/#django.views.decorators.http.require_http_methods\" title=\"django.views.decorators.http.require_http_methods\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">require_http_methods()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/topics/http/decorators/#django.views.decorators.http.require_GET\" title=\"django.views.decorators.http.require_GET\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">require_GET()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/topics/http/decorators/#django.views.decorators.http.require_POST\" title=\"django.views.decorators.http.require_POST\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">require_POST()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/topics/http/decorators/#django.views.decorators.http.require_safe\" title=\"django.views.decorators.http.require_safe\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">require_safe()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/topics/http/decorators/#django.views.decorators.vary.vary_on_cookie\" title=\"django.views.decorators.vary.vary_on_cookie\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">vary_on_cookie()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/6.1/topics/http/decorators/#django.views.decorators.vary.vary_on_headers\" title=\"django.views.decorators.vary.vary_on_headers\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">vary_on_headers()</span></code></a></p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">xframe_options_deny()</span></code></p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">xframe_options_sameorigin()</span></code></p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">xframe_options_exempt()</span></code></p></li>\n</ul>\n<p>For example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.cache</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">never_cache</span>\n\n\n<span class=\"nd\">@never_cache</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_sync_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n\n\n<span class=\"nd\">@never_cache</span>\n<span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_async_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p><a class=\"reference internal\" href=\"/en/6.1/ref/utils/#django.utils.decorators.method_decorator\" title=\"django.utils.decorators.method_decorator\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">method_decorator()</span></code></a> can be used with asynchronous\nmethods, including <code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">def</span></code> view handlers. Note, though, that if\ndecorating <a class=\"reference internal\" href=\"/en/6.1/ref/class-based-views/base/#django.views.generic.base.View.dispatch\" title=\"django.views.generic.base.View.dispatch\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">dispatch()</span></code></a> on a <code class=\"docutils literal notranslate\"><span class=\"pre\">View</span></code> with\nasynchronous handlers, you will need to override <code class=\"docutils literal notranslate\"><span class=\"pre\">dispatch</span></code> to make it\n<code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">def</span></code> as well:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyClass</span><span class=\"p\">(</span><span class=\"n\">View</span><span class=\"p\">):</span>\n    <span class=\"nd\">@method_decorator</span><span class=\"p\">(</span><span class=\"n\">never_cache</span><span class=\"p\">)</span>\n    <span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">dispatch</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">dispatch</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">)</span>\n\n    <span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n\n    <span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">post</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>Here, because we are decorating <code class=\"docutils literal notranslate\"><span class=\"pre\">dispatch</span></code>, rather than the individual\nhandler methods, we need to make <code class=\"docutils literal notranslate\"><span class=\"pre\">dispatch</span></code> asynchronous so that\n<code class=\"docutils literal notranslate\"><span class=\"pre\">method_decorator</span></code> can correctly mark the resulting method as a coroutine\nfunction.</p>\n</section>\n<section id=\"queries-the-orm\">\n<h3>Queries &amp; the ORM<a class=\"heading-anchor\" href=\"#queries-the-orm\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>With some exceptions, Django can run ORM queries asynchronously:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">async</span> <span class=\"k\">for</span> <span class=\"n\">author</span> <span class=\"ow\">in</span> <span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name__startswith</span><span class=\"o\">=</span><span class=\"s2\">&quot;A&quot;</span><span class=\"p\">):</span>\n    <span class=\"n\">book</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"n\">author</span><span class=\"o\">.</span><span class=\"n\">books</span><span class=\"o\">.</span><span class=\"n\">afirst</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Detailed notes can be found in <a class=\"reference internal\" href=\"/en/6.1/topics/db/queries/#async-queries\"><span class=\"std std-ref\">Asynchronous queries</span></a>, but in short:</p>\n<ul class=\"simple\">\n<li><p>All <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> methods that cause an SQL query to occur have an\n<code class=\"docutils literal notranslate\"><span class=\"pre\">a</span></code>-prefixed asynchronous variant.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">for</span></code> is supported on all QuerySets (including the output of\n<code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> and <code class=\"docutils literal notranslate\"><span class=\"pre\">values_list()</span></code>.)</p></li>\n</ul>\n<p>Asynchronous model methods that use the database are also supported:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">make_book</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"n\">book</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">)</span>\n    <span class=\"k\">await</span> <span class=\"n\">book</span><span class=\"o\">.</span><span class=\"n\">asave</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"s2\">&quot;secondary&quot;</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">make_book_with_tags</span><span class=\"p\">(</span><span class=\"n\">tags</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"n\">book</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">acreate</span><span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">)</span>\n    <span class=\"k\">await</span> <span class=\"n\">book</span><span class=\"o\">.</span><span class=\"n\">tags</span><span class=\"o\">.</span><span class=\"n\">aset</span><span class=\"p\">(</span><span class=\"n\">tags</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Transactions do not yet work in async mode. If you have a piece of code that\nneeds transactions behavior, we recommend you write that piece as a single\nsynchronous function and call it using <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a>.</p>\n<p><a class=\"reference internal\" href=\"/en/6.1/ref/databases/#persistent-database-connections\"><span class=\"std std-ref\">Persistent database connections</span></a>, set\nvia the <a class=\"reference internal\" href=\"/en/6.1/ref/settings/#std-setting-CONN_MAX_AGE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CONN_MAX_AGE</span></code></a> setting, should also be disabled in async mode.\nInstead, use your database backend’s built-in connection pooling if available,\nor investigate a third-party connection pooling option if required. As in\nsynchronous Django, concurrent requests in a single process share that pool, so\nsize it to the target in-flight query concurrency.</p>\n</section>\n<section id=\"performance\">\n<span id=\"async-performance\"></span><h3>Performance<a class=\"heading-anchor\" href=\"#performance\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>When running in a mode that does not match the view (e.g. an async view under\nWSGI, or a traditional sync view under ASGI), Django must emulate the other\ncall style to allow your code to run. The per-call cost of this adaptation is\nsmall: tens of microseconds in the in-request ASGI path, where the running\nevent loop is reused, and a few hundred microseconds in the cold-start path\nused by management commands, background tasks, and scripts. Against typical\nrequest times measured in milliseconds, this is rarely visible in itself, but\ncan become so under GIL contention as the number of active threads grows.</p>\n<p>If you find yourself wrapping individual rows or operations in a tight loop,\nrestructure your code so the loop runs inside a single <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a>\n(or <a class=\"reference internal\" href=\"#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a>) crossing. The per-call cost of the context switch is\nthen spread across the whole loop and effectively disappears.</p>\n<p>The same per-call adaptation cost applies to middleware. Django will attempt to\nminimize the number of context-switches between sync and async. If you have an\nASGI server, but all your middleware and views are synchronous, it will switch\njust once, before it enters the middleware stack.</p>\n<p>However, if you put synchronous middleware between an ASGI server and an\nasynchronous view, it will have to switch into sync mode for the middleware and\nthen back to async mode for the view. Django will also hold the sync thread\nopen for middleware exception propagation. For request/response views that hit\nthe ORM and return, this is not usually a meaningful penalty. It matters most\nwhen you are using ASGI for high in-process concurrency over non-ORM I/O (for\nexample upstream HTTP fan-out, server-sent events, or other long-lived\nrequests), where the extra thread per request caps that concurrency.</p>\n<p>You should do your own performance testing to see what effect ASGI versus WSGI\nhas on your code. In some cases, there may be a performance increase even for\na purely synchronous codebase under ASGI because the request-handling code is\nstill all running asynchronously. In general you will only want to enable ASGI\nmode if you have asynchronous code in your project.</p>\n</section>\n<section id=\"handling-disconnects\">\n<span id=\"async-handling-disconnect\"></span><h3>Handling disconnects<a class=\"heading-anchor\" href=\"#handling-disconnects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>For long-lived requests, a client may disconnect before the view returns a\nresponse. In this case, an <code class=\"docutils literal notranslate\"><span class=\"pre\">asyncio.CancelledError</span></code> will be raised in the\nview. You can catch this error and handle it if you need to perform any\ncleanup:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"c1\"># Do some work</span>\n        <span class=\"o\">...</span>\n    <span class=\"k\">except</span> <span class=\"n\">asyncio</span><span class=\"o\">.</span><span class=\"n\">CancelledError</span><span class=\"p\">:</span>\n        <span class=\"c1\"># Handle disconnect</span>\n        <span class=\"k\">raise</span>\n</code></pre></div>\n<p>You can also <a class=\"reference internal\" href=\"/en/6.1/ref/request-response/#request-response-streaming-disconnect\"><span class=\"std std-ref\">handle client disconnects in streaming responses</span></a>.</p>\n</section>\n</section>\n<section id=\"async-safety\">\n<span id=\"id1\"></span><h2>Async safety<a class=\"heading-anchor\" href=\"#async-safety\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<dl class=\"std envvar\">\n<dt class=\"sig sig-object std\" id=\"envvar-DJANGO_ALLOW_ASYNC_UNSAFE\">\n<span class=\"sig-name descname\"><span class=\"pre\">DJANGO_ALLOW_ASYNC_UNSAFE</span></span><a class=\"heading-anchor\" href=\"#envvar-DJANGO_ALLOW_ASYNC_UNSAFE\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Certain key parts of Django are not able to operate safely in an async\nenvironment, as they have global state that is not coroutine-aware. These parts\nof Django are classified as “async-unsafe”, and are protected from execution in\nan async environment. The synchronous API of the ORM is the main example, but\nthere are other parts that are also protected in this way.</p>\n<p>If you try to run any of these parts from a thread where there is a <em>running\nevent loop</em>, you will get a\n<a class=\"reference internal\" href=\"/en/6.1/ref/exceptions/#django.core.exceptions.SynchronousOnlyOperation\" title=\"django.core.exceptions.SynchronousOnlyOperation\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">SynchronousOnlyOperation</span></code></a> error. Note that you\ndon’t have to be inside an async function directly to have this error occur. If\nyou have called a sync function directly from an async function,\nwithout using <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> or similar, then it can also occur. This is\nbecause your code is still running in a thread with an active event loop, even\nthough it may not be declared as async code.</p>\n<p>If you encounter this error, you should fix your code to not call the offending\ncode from an async context. Instead, write your code that talks to async-unsafe\nfunctions in its own, sync function, and call that using\n<a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">asgiref.sync.sync_to_async()</span></code></a> (or any other way of running sync code in\nits own thread).</p>\n<p>The async context can be imposed upon you by the environment in which you are\nrunning your Django code. For example, <a class=\"reference external\" href=\"https://jupyter.org/\">Jupyter</a> notebooks and <a class=\"reference external\" href=\"https://ipython.org\">IPython</a>\ninteractive shells both transparently provide an active event loop so that it\nis easier to interact with asynchronous APIs.</p>\n<p>If you’re using an IPython shell, you can disable this event loop by running:</p>\n<div class=\"code-block\" data-language=\"shell\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code>%autoawait<span class=\"w\"> </span>off\n</code></pre></div>\n<p>as a command at the IPython prompt. This will allow you to run synchronous code\nwithout generating <a class=\"reference internal\" href=\"/en/6.1/ref/exceptions/#django.core.exceptions.SynchronousOnlyOperation\" title=\"django.core.exceptions.SynchronousOnlyOperation\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">SynchronousOnlyOperation</span></code></a>\nerrors; however, you also won’t be able to <code class=\"docutils literal notranslate\"><span class=\"pre\">await</span></code> asynchronous APIs. To turn\nthe event loop back on, run:</p>\n<div class=\"code-block\" data-language=\"shell\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code>%autoawait<span class=\"w\"> </span>on\n</code></pre></div>\n<p>If you’re in an environment other than IPython (or you can’t turn off\n<code class=\"docutils literal notranslate\"><span class=\"pre\">autoawait</span></code> in IPython for some reason), you are <em>certain</em> there is no chance\nof your code being run concurrently, and you <em>absolutely</em> need to run your sync\ncode from an async context, then you can disable the warning by setting the\n<span class=\"target\" id=\"index-0\"></span><a class=\"reference internal\" href=\"#envvar-DJANGO_ALLOW_ASYNC_UNSAFE\"><code class=\"xref std std-envvar docutils literal notranslate\"><span class=\"pre\">DJANGO_ALLOW_ASYNC_UNSAFE</span></code></a> environment variable to any value.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Warning</p>\n<p>If you enable this option and there is concurrent access to the\nasync-unsafe parts of Django, you may suffer data loss or corruption. Be\nvery careful and do not use this in production environments.</p>\n</aside>\n<p>If you need to do this from within Python, do that with <code class=\"docutils literal notranslate\"><span class=\"pre\">os.environ</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">os</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">environ</span><span class=\"p\">[</span><span class=\"s2\">&quot;DJANGO_ALLOW_ASYNC_UNSAFE&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;true&quot;</span>\n</code></pre></div>\n</section>\n<section id=\"async-adapter-functions\">\n<h2>Async adapter functions<a class=\"heading-anchor\" href=\"#async-adapter-functions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>It is necessary to adapt the calling style when calling sync code from an async\ncontext, or vice-versa. For this there are two adapter functions, from the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">asgiref.sync</span></code> module: <a class=\"reference internal\" href=\"#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a> and <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a>. They\nare used to transition between the calling styles while preserving\ncompatibility.</p>\n<p>These adapter functions are widely used in Django. The <a class=\"extlink-pypi reference external\" href=\"https://pypi.org/project/asgiref/\">asgiref</a> package\nitself is part of the Django project, and it is automatically installed as a\ndependency when you install Django with <code class=\"docutils literal notranslate\"><span class=\"pre\">pip</span></code>.</p>\n<section id=\"async-to-sync\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code><a class=\"heading-anchor\" href=\"#async-to-sync\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"asgiref.sync.async_to_sync\">\n<span class=\"sig-name descname\"><span class=\"pre\">async_to_sync</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">async_function</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">force_new_loop</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#asgiref.sync.async_to_sync\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Takes an async function and returns a sync function that wraps it. Can be used\nas either a direct wrapper or a decorator:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">async_to_sync</span>\n\n\n<span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_data</span><span class=\"p\">():</span> <span class=\"o\">...</span>\n\n\n<span class=\"n\">sync_get_data</span> <span class=\"o\">=</span> <span class=\"n\">async_to_sync</span><span class=\"p\">(</span><span class=\"n\">get_data</span><span class=\"p\">)</span>\n\n\n<span class=\"nd\">@async_to_sync</span>\n<span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_other_data</span><span class=\"p\">():</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>The async function is run in the event loop for the current thread, if one is\npresent. If there is no current event loop, a new event loop is spun up\nspecifically for the single async invocation and shut down again once it\ncompletes. In either situation, the async function will execute on a different\nthread to the calling code.</p>\n<p>Threadlocals and contextvars values are preserved across the boundary in both\ndirections.</p>\n<p><a class=\"reference internal\" href=\"#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a> is essentially a more powerful version of the\n<a class=\"reference external\" href=\"https://docs.python.org/3/library/asyncio-runner.html#asyncio.run\" title=\"(in Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">asyncio.run()</span></code></a> function in Python’s standard library. As well as ensuring\nthreadlocals work, it also enables the <code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive</span></code> mode of\n<a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> when that wrapper is used below it. In the cold path\n(no running event loop) it pays the cost of starting a fresh event loop, like\n<a class=\"reference external\" href=\"https://docs.python.org/3/library/asyncio-runner.html#asyncio.run\" title=\"(in Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">asyncio.run()</span></code></a>; when an event loop is already running (the in-request ASGI\ncase), the running loop is reused and the cost drops accordingly.</p>\n</section>\n<section id=\"sync-to-async\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code><a class=\"heading-anchor\" href=\"#sync-to-async\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"asgiref.sync.sync_to_async\">\n<span class=\"sig-name descname\"><span class=\"pre\">sync_to_async</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sync_function</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">thread_sensitive</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">True</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#asgiref.sync.sync_to_async\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Takes a sync function and returns an async function that wraps it. Can be used\nas either a direct wrapper or a decorator:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">sync_to_async</span>\n\n<span class=\"n\">async_function</span> <span class=\"o\">=</span> <span class=\"n\">sync_to_async</span><span class=\"p\">(</span><span class=\"n\">sync_function</span><span class=\"p\">,</span> <span class=\"n\">thread_sensitive</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n<span class=\"n\">async_function</span> <span class=\"o\">=</span> <span class=\"n\">sync_to_async</span><span class=\"p\">(</span><span class=\"n\">sensitive_sync_function</span><span class=\"p\">,</span> <span class=\"n\">thread_sensitive</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n\n<span class=\"nd\">@sync_to_async</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">sync_function</span><span class=\"p\">():</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>Threadlocals and contextvars values are preserved across the boundary in both\ndirections.</p>\n<p>Sync functions tend to be written assuming they all run in the main\nthread, so <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> has two threading modes:</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive=True</span></code> (the default): the sync function will run in the\nsame thread as all other <code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive</span></code> functions. This will be the\nmain thread, if the main thread is synchronous and you are using the\n<a class=\"reference internal\" href=\"#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a> wrapper.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive=False</span></code>: the sync function will run in a brand new thread\nwhich is then closed once the invocation completes.</p></li>\n</ul>\n<p>Thread-sensitive mode is quite special, and does a lot of work to run all\nfunctions in the same thread. Note, though, that it <em>relies on usage of</em>\n<a class=\"reference internal\" href=\"#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a> <em>above it in the stack</em> to correctly run things on the\nmain thread. If you use <code class=\"docutils literal notranslate\"><span class=\"pre\">asyncio.run()</span></code> or similar, it will fall back to\nrunning thread-sensitive functions in a single, shared thread, but this will\nnot be the main thread.</p>\n<p>The reason this is needed in Django is that many libraries, specifically\ndatabase adapters, require that they are accessed in the same thread that they\nwere created in. Also a lot of existing Django code assumes it all runs in the\nsame thread, e.g. middleware adding things to a request for later use in views.</p>\n<p>Rather than introduce potential compatibility issues with this code, we instead\nopted to add this mode so that all existing Django sync code runs in the same\nthread and thus is fully compatible with async mode. Note that sync code will\nalways be in a <em>different</em> thread to any async code that is calling it, so you\nshould avoid passing raw database handles or other thread-sensitive references\naround.</p>\n<p>Within a single request, multiple <code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive</span></code> calls serialize on that\nrequest’s worker thread, but each request gets its own per-context worker, so\nconcurrent requests do <em>not</em> serialize against each other. This mirrors\nDjango’s connection-per-thread model, and the same constraint applies in other\nasync database libraries, where concurrent queries on a single connection\nserialize on a lock. To support more concurrent requests, increase the\nconnection pool size accordingly rather than disabling <code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive</span></code>.</p>\n<p>In practice this restriction means that you should not pass features of the\ndatabase <code class=\"docutils literal notranslate\"><span class=\"pre\">connection</span></code> object when calling <code class=\"docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code>. Doing so will\ntrigger the thread safety checks:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"go\"># DJANGO_SETTINGS_MODULE=settings.py python -m asyncio</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">asyncio</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">sync_to_async</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">connection</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># In an async context so you cannot use the database directly:</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"n\">cursor</span><span class=\"p\">()</span>\n<span class=\"go\">django.core.exceptions.SynchronousOnlyOperation: You cannot call this from</span>\n<span class=\"go\">an async context - use a thread or sync_to_async.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># Nor can you pass resolved connection attributes across threads:</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">await</span> <span class=\"n\">sync_to_async</span><span class=\"p\">(</span><span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"n\">cursor</span><span class=\"p\">)()</span>\n<span class=\"go\">django.db.utils.DatabaseError: DatabaseWrapper objects created in a thread</span>\n<span class=\"go\">can only be used in that same thread. The object with alias &#39;default&#39; was</span>\n<span class=\"go\">created in thread id 4371465600 and this is thread id 6131478528.</span>\n</code></pre></div>\n<p>Rather, you should encapsulate all database access within a helper function\nthat can be called with <code class=\"docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code> without relying on the connection\nobject in the calling code.</p>\n</section>\n</section>","rootId":"asynchronous-support","toc":[{"title":"Async views","anchor":"async-views","children":[{"title":"Decorators","anchor":"decorators","children":[]},{"title":"Queries & the ORM","anchor":"queries-the-orm","children":[]},{"title":"Performance","anchor":"performance","children":[]},{"title":"Handling disconnects","anchor":"handling-disconnects","children":[]}]},{"title":"Async safety","anchor":"async-safety","children":[]},{"title":"Async adapter functions","anchor":"async-adapter-functions","children":[{"title":"async_to_sync()","anchor":"async-to-sync","children":[]},{"title":"sync_to_async()","anchor":"sync-to-async","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Using Django","url":"/en/6.1/topics/"}],"prev":{"docname":"topics/checks","title":"System check framework","url":"/en/6.1/topics/checks/"},"next":{"docname":"topics/tasks","title":"Django’s Tasks framework","url":"/en/6.1/topics/tasks/"},"formats":{"html":"/en/6.1/topics/async/","markdown":"/en/6.1/topics/async.md","json":"/en/6.1/topics/async.json"},"source":"https://github.com/django/django/blob/stable/6.1.x/docs/topics/async.txt","official":"https://docs.djangoproject.com/en/6.1/topics/async/","inVersions":["dev","6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}