Python Tornado

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the section bibliography.

This section is written against Tornado 6.5.10 (released 2026-09-15) on Python 3.13, checked on 2026-10-07. Tornado 6.5 supports Python 3.9 and newer. Tornado 6.6 is not released yet: only the alpha 6.6a1 (2026-09-22) is on PyPI and its final release notes are still dated "Oct XX, 2026", so everything described as 6.6 in this section (Python 3.11 as the minimum, the cross_origin_protection and trusted_origins settings, the deprecation of OpenIdMixin) is upcoming and can still change. Every page notes the version in which a feature appeared, because Tornado changed a lot between 4.x and 6.x and most tutorials on the web still show the older idioms.

What Tornado is

Tornado is a Python web framework and asynchronous networking library that started life at FriendFeed. It bundles four things that other stacks keep in separate projects: a web framework (tornado.web: Application, RequestHandler, templates, cookies, XSRF protection, WebSockets), an HTTP server and client (HTTPServer, AsyncHTTPClient), a non-blocking networking layer (IOLoop and IOStream, now thin wrappers around asyncio), and coroutine tools (tornado.gen, tornado.queues, tornado.locks).

The defining design choice is that Tornado is not a WSGI framework. It brings its own HTTP server and runs every request of a process on one thread and one event loop. A handler that waits (for a database, a remote service or a client) does so with await and lets the loop serve other connections meanwhile. That makes Tornado a good fit for workloads with many long-lived or idle connections, such as WebSockets, long polling and Server-Sent Events, and for services that spend their time calling other services. It is a poor fit for CPU-heavy handlers and for code built on blocking libraries, unless that work is moved off the loop.

This section is for developers who:

  • know Python and want to build real-time or high-concurrency services without a second framework for the networking layer

  • are coming from Flask, Django, FastAPI or Pyramid and want to understand what a single-threaded, single-loop server changes about handlers, databases, tests and deployment

  • maintain Tornado 4.x or 5.x code (callbacks, @gen.coroutine, IOLoop.instance()) and need the current async def idioms and the upgrade path

  • need one coherent path from a first handler to WebSockets, security, testing and a multi-process deployment behind nginx

The Bookshelf Live scenario

Every example builds one small original service, Bookshelf Live, so the pages fit together instead of being isolated snippets. It is the real-time companion of the Flask Bookshelf and the FastAPI Bookshelf API, and it shows what Tornado is for:

  • a JSON API for books and reviews backed by an async driver

  • a WebSocket chat room per book, and a "new reviews" feed over long polling and Server-Sent Events

  • cover metadata fetched concurrently from an external service with AsyncHTTPClient, driven by a bounded queue of workers (a local fake service in tests)

  • signed-cookie login, XSRF and cross-origin protection, and Google OAuth 2.0 sign-in

  • tests with AsyncHTTPTestCase, and deployment as one process per CPU behind nginx

Diagram of Bookshelf Live. Clients such as browsers, curl, WebSocket chat, EventSource and long-poll loops reach nginx, which terminates TLS and forwards upgrade headers. nginx balances requests across Tornado processes, one per CPU, each a single thread running one asyncio event loop. A process contains a JSON API, authentication with signed cookies and XSRF, a WebSocket chat per book, a new-reviews feed over long polling and SSE, a cover fetcher built from a bounded queue and workers, and the Application and IOLoop. The processes talk to PostgreSQL through an async driver pool, to Redis for publish and subscribe fan-out, to an external metadata API, and to Google for OAuth 2.0 sign-in.
Figure 1. Bookshelf Live: clients, nginx, Tornado processes and the services they talk to

Reading path

The pages are ordered so that each one builds on the previous ones. Read them in this order the first time, then use them as a reference:

  1. Foundations: what Tornado is made of, a first running app, why blocking the event loop is the cardinal sin, coroutines, and the queue and lock primitives.

  2. The web framework: applications and handlers, routing, error pages, templates and UI modules, static files and translations.

  3. Security: signed cookies and login, XSRF and cross-origin protection, and sign-in with third-party providers.

  4. HTTP clients, real-time and networking: AsyncHTTPClient, WebSockets, streaming with long polling and SSE, and the low-level TCP layer.

  5. Data, configuration and testing: async database drivers, options and logging, and AsyncHTTPTestCase.

  6. Production: one process per CPU, nginx, graceful shutdown, serving WSGI apps next to Tornado handlers, and what changed between releases.

The cheat sheet at Tornado Cheat Sheet condenses the whole section onto one page for quick lookup.

mindmap root((Python Tornado)) Foundations Introduction and architecture Getting started Event loop and blocking Coroutines and asyncio Queues and locks Web framework Applications and handlers Routing Error handling Templates and UI modules Static files Localization Security Signed cookies and login XSRF and cross-origin Third-party auth Clients and real-time AsyncHTTPClient WebSockets Streaming, long polling, SSE TCP and IOStream Data and testing Async drivers Options and logging AsyncHTTPTestCase Production Processes and nginx WSGI interoperability Changes and migration
Figure 2. The section at a glance

The Tornado pages link to existing material instead of repeating it, and cover only what Tornado adds.

Topic Where it lives How the Tornado section relates

The Python language, asyncio, virtual environments, pytest

Python Reference, including Concurrency & Async, Virtual Environments & Packaging and Testing

Tornado pages link here for general Python and cover only the Tornado layer on top of asyncio.

Other Python web frameworks

Python Flask, Python Pyramid, Python FastAPI and Django

The introduction compares the frameworks, and the WSGI page shows how to serve a Flask or Pyramid app next to Tornado handlers.

Django Channels and async Django

Channels & WebSockets and Async Support

The WebSocket and event-loop pages point here for the comparison with Django’s ASGI route.

OAuth 2.0, OpenID Connect, JWT theory

OAuth Reference

The third-party authentication page covers only the tornado.auth mixins and points here for the protocols.

Docker and containers

Docker

The deployment page shows only the Tornado-specific one-process-per-container setup.

Kubernetes

Kubernetes Reference and Health Probes & Lifecycle

The deployment page shows only graceful shutdown and probes for a Tornado process.

Database engines

SQL Reference, MongoDB Reference and Redis Reference

The data page covers only the async drivers and how to wire their pools into handlers.

Messaging and scheduling

Messaging Reference and Scheduling

The queue and WebSocket pages point here for work that outgrows an in-process queue or a single process.

CORS

CORS

The XSRF page covers only how to set the headers from a Tornado handler.

Bibliography

Every source used to prepare this section is listed here, each linked to its official site. Individual pages list the subset they derive from under their own == References heading.

Security guidance

No book was consulted for this section: the official documentation linked above is authoritative, and where it differs from older tutorials, the documentation of the version you run prevails.