Executing Asynchronous Scheduled Tasks with Database-Based Distributed Locking in FastAPI

Introduction When implementing scheduled tasks in FastAPI applications, Celery is often the go-to choice. However, Celery is relatively heavyweight and requires dependencies like Redis or RabbitMQ as message brokers. For smaller-scale services that don’t already utilize Redis or RabbitMQ, introducing these dependencies solely for scheduled task functionality adds unnecessary operational overhead. Another popular Python scheduling framework is APScheduler, but it presents two significant challenges in practice: Duplicate Execution in Multi-Process Environments: When running with Uvicorn’s multi-process mode, each worker process independently executes scheduled tasks, leading to duplicate executions. Poor Asynchronous Function Compatibility: Although APScheduler provides AsyncIOScheduler, its support for asynchronous functions is incomplete. The official documentation explicitly states: “If you’re running an asynchronous web framework like aiohttp, you probably want to use a different scheduler in order to take some advantage of the asynchronous nature of the framework.” For APScheduler users facing these issues, potential solutions include: ...

February 8, 2026 · 14 min · Rainux He

FastAPI - Calling Synchronous Methods in FastAPI Asynchronous Methods

Introduction Directly calling synchronous methods within asynchronous methods blocks the entire event loop, preventing the application from handling any other concurrent requests while executing the synchronous method. This severely impacts the overall performance and responsiveness of the service. To address this issue, the core approach is to delegate synchronous methods to external thread pools or process pools for execution, thereby avoiding blocking the main event loop. Method 1: Using asyncio.to_thread Python 3.9 and later versions provide the asyncio.to_thread method, which runs synchronous functions in a separate thread and returns a coroutine object that can be awaited. ...

January 6, 2026 · 2 min · Rainux He

FastAPI - Design of tracking_id

Introduction In real business scenarios, tracing a request’s complete processing path in logs based on a tracking_id is a common requirement. However, FastAPI does not provide this functionality out of the box, so developers need to implement it themselves. This article introduces how to add a tracking_id to the entire request lifecycle based on contextvars and automatically record it in logs. What is contextvars Python 3.7 added a module contextvars to the standard library, which stands for “Context Variables”. It is typically used to implicitly pass some environmental information variables, similar to threading.local(). However, threading.local() is thread-specific, isolating data states between threads, while contextvars can be used in asynchronous coroutines within the asyncio ecosystem. PS: contextvars can not only be used in asynchronous coroutines but can also replace threading.local() in multi-threaded functions. ...

December 11, 2025 · 11 min · Rainux He