NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #1176 most downloaded on PyPI
A distributed background task system for Python functions
Last release 2 days ago
02 Oct 2026
Ships fairly regularly
a new release about every 2 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
2 years old
89 releases · first in 2025
One column per month.
Be careful when you set reasoning to max , you may get more than you bargained for!
Be careful when you set reasoning to max, you may get more than you bargained for!
In preparation for adding Docket implementations in some new languages 🦀 🐹, I'm shoring up the Python implementation and its tests. During that process, Opus 5.5 on max found a lot of things to work through. All of these are material reliability improvements in the handling of cancellations and shutdown, and all have been tested against the major downstream libraries, like Prefect and FastMCP.
Also big thanks for the first contribution, @skulitom!
Full Changelog: 0.25.2...0.26.0
Allow --schedule-automatic-tasks to be disabled from the CLI by @omikader in #475
Full Changelog: 0.25.1...0.25.2
Survive Redis refusals, not only disconnects by @chrisguidry in #477
Full Changelog: 0.25.0...0.25.1
Inspired by competition, I took Docket out for a spin at 500k concurrent tasks and found several performance improvements that really improve the scal
Inspired by competition, I took Docket out for a spin at 500k concurrent tasks and found several performance improvements that really improve the scalability of the system.
Full Changelog: 0.24.1...0.25.0
Propagate external cancellation through worker waits on Python 3.10 and 3.11 by @chrisguidry in https://github.com/chrisguidry/docket/pull/456
Full Changelog: https://github.com/chrisguidry/docket/compare/0.24.0...0.24.1
Full Changelog: 0.24.0...0.24.1
Bump the all-dependencies group with 14 updates by @dependabot[bot] in https://github.com/chrisguidry/docket/pull/449
Full Changelog: https://github.com/chrisguidry/docket/compare/0.23.1...0.24.0
Full Changelog: 0.23.1...0.24.0
Share ssl_* options with the Sentinel daemon connections on TLS URLs by @fatih-acar in https://github.com/chrisguidry/docket/pull/445
Full Changelog: https://github.com/chrisguidry/docket/compare/0.23.0...0.23.1
Full Changelog: 0.23.0...0.23.1
Bump starlette from 1.2.1 to 1.3.1 by @dependabot[bot] in https://github.com/chrisguidry/docket/pull/434
Full Changelog: https://github.com/chrisguidry/docket/compare/0.22.0...0.23.0
Full Changelog: 0.22.0...0.23.0
Big thanks to @fatih-acar for giving us Redis Sentinel support!
Big thanks to @fatih-acar for giving us Redis Sentinel support!
Full Changelog: https://github.com/chrisguidry/docket/compare/0.21.1...0.22.0
Big thanks to @fatih-acar for giving us Redis Sentinel support!
Full Changelog: 0.21.1...0.22.0
redis-py==8.0.0 changed a default timeout that broke long-lived blocking connections (like pubsub and streams). With this release, that's fixed and we
redis-py==8.0.0 changed a default timeout that broke long-lived blocking connections (like pubsub and streams). With this release, that's fixed and we support (and have tests for) redis-py 5.x, 6.x, 7.x, and 8.x
Full Changelog: https://github.com/chrisguidry/docket/compare/0.21.0...0.21.1
redis-py==8.0.0 changed a default timeout that broke long-lived blocking connections (like pubsub and streams). With this release, that's fixed and we support (and have tests for) redis-py 5.x, 6.x, 7.x, and 8.x
Full Changelog: 0.21.0...0.21.1
This is a performance-tuning release focused on reducing how chatty Docket is with Redis, and folding several separate operations into single pipeline
This is a performance-tuning release focused on reducing how chatty Docket is with Redis, and folding several separate operations into single pipelines and scripts.
Full Changelog: https://github.com/chrisguidry/docket/compare/0.20.3...0.21.0
This is a performance-tuning release focused on reducing how chatty Docket is with Redis, and folding several separate operations into single pipelines and scripts.
Full Changelog: 0.20.3...0.21.0
Bump urllib3 from 2.6.3 to 2.7.0 by @dependabot[bot] in https://github.com/chrisguidry/docket/pull/413
Full Changelog: https://github.com/chrisguidry/docket/compare/0.20.2...0.20.3
Full Changelog: 0.20.2...0.20.3
Add the audit-docs skill and apply its first findings by @chrisguidry in https://github.com/chrisguidry/docket/pull/406
Full Changelog: https://github.com/chrisguidry/docket/compare/0.20.1...0.20.2
Full Changelog: 0.20.1...0.20.2
Bump the all-dependencies group with 16 updates by @dependabot[bot] in https://github.com/chrisguidry/docket/pull/402
Full Changelog: https://github.com/chrisguidry/docket/compare/0.20.0...0.20.1
Full Changelog: 0.20.0...0.20.1
Huge thanks to @desertaxle for his excellent `burner-redis`, the new in-memory Redis implementation. burner-redis supplants the venerable fake-redis a
Huge thanks to @desertaxle for his excellent burner-redis, the new in-memory Redis implementation. burner-redis supplants the venerable fake-redis as a production-oriented, high-performance implementation. This should mean major improvements to memory usage, runtime performance, and installation heft.
burner-redis>=0.1.6 by @chrisguidry in https://github.com/chrisguidry/docket/pull/399Full Changelog: https://github.com/chrisguidry/docket/compare/0.19.2...0.20.0
Mark admission-blocked task spans as OK, not ERROR by @joshuastagner in https://github.com/chrisguidry/docket/pull/395
Full Changelog: https://github.com/chrisguidry/docket/compare/0.19.1...0.19.2
`python async with Worker(docket, dependencies=[Depends(transaction), Retry(attempts=3)]: ... `
Worker-level dependencies!
async with Worker(docket, dependencies=[Depends(transaction), Retry(attempts=3)]:
...
You can now define dependencies on your worker that are merged with the dependencies of each task. This allows for adding cross-cutting/orthogonal concerns (instrumentation, observability, environment setup, etc) without repeating them for each task! Those worker-level dependencies can themselves have dependencies, including looking at the current task's task argument, task key, the current execution, or any other dependency.
More on this in the docs!
Full Changelog: https://github.com/chrisguidry/docket/compare/0.19.0...0.19.1
Bump the all-dependencies group with 13 updates by @dependabot[bot] in https://github.com/chrisguidry/docket/pull/364
Full Changelog: https://github.com/chrisguidry/docket/compare/0.18.2...0.19.0
Replace croniter with cronsim by @chrisguidry in https://github.com/chrisguidry/docket/pull/363
Full Changelog: https://github.com/chrisguidry/docket/compare/0.18.1...0.18.2
Bump the all-dependencies group with 5 updates by @dependabot[bot] in https://github.com/chrisguidry/docket/pull/358
Full Changelog: https://github.com/chrisguidry/docket/compare/0.18.0...0.18.1
The big news with this release is that I've extracted Docket's dependency system to it's own library called uncalled-for (https://github.com/chrisguid
The big news with this release is that I've extracted Docket's dependency system to it's own library called uncalled-for (https://github.com/chrisguidry/uncalled-for and https://pypi.org/project/uncalled-for/). This should be a transparent change for all Docket users, and I've done everything I could to make sure that the import surface area is completely compatible.
I also took this opportunity to implement some ideas that we've been bouncing around for a bit, where we have Annotated dependencies specifically for dependencies that need to modify their behavior based on a parameter. For example, if you want to set a concurrency limit by customer, that looks like:
async def hit_customer_webhook(customer_id: Annotated[int, ConcurrencyLimit(2)]):
...
(note, the prior style continues to work for ConcurrencyLimit)
Inspired by this new style, I've implemented some additional modifiers to runtime behavior/admissions, Debouce, Cooldown, and RateLimit, which all hopefully do what they sound like they do. More on those new behavior dependencies in the docs.
Please note that with Annotated dependencies, they are still activated for the lifecycle of the task, but their return values aren't accessible as parameters. This is a design choice and we will not be supporting some_parameter: Annotated[SomeType, Depends(some_function)]. Our stance is that any dependency like that should be provided via a kwarg default to keep the intention clear. I want to thank @omikader for helping me think through this and bravely taking a stab at one version of Annotated dependencies.
I've tested both FastMCP 2.x and FastMCP 3.x with no other code changes and both are operating correctly. Prefect doesn't use any relevant imports from Docket and is using only the public API that's remained unchanged.
Full Changelog: https://github.com/chrisguidry/docket/compare/0.17.9...0.18.0
Fix flaky test_task_duration_is_measured on Windows by @chrisguidry in https://github.com/chrisguidry/docket/pull/345
<img width="888" height="499" alt="image" src="https://github.com/user-attachments/assets/19290c51-f4b6-4618-a6e3-7fbdf79a3e45" />
Full Changelog: https://github.com/chrisguidry/docket/compare/0.17.8...0.17.9
Clear known from runs hash on cancel so add() can reschedule by @chrisguidry in https://github.com/chrisguidry/docket/pull/336
known from runs hash on cancel so add() can reschedule by @chrisguidry in https://github.com/chrisguidry/docket/pull/336Full Changelog: https://github.com/chrisguidry/docket/compare/0.17.7...0.17.8
Bump the all-dependencies group with 2 updates by @dependabot[bot] in https://github.com/chrisguidry/docket/pull/333
Full Changelog: https://github.com/chrisguidry/docket/compare/0.17.6...0.17.7
Fix Perpetual rescheduling race condition by @chrisguidry in https://github.com/chrisguidry/docket/pull/331
Fix Perpetual rescheduling race condition by @chrisguidry in https://github.com/chrisguidry/docket/pull/331
Batch dependency updates by @chrisguidry in https://github.com/chrisguidry/docket/pull/319
Batch dependency updates by @chrisguidry in https://github.com/chrisguidry/docket/pull/327
Group Dependabot updates into single PRs by @chrisguidry in https://github.com/chrisguidry/docket/pull/328
Bump the all-dependencies group with 9 updates by @dependabot[bot] in https://github.com/chrisguidry/docket/pull/329
Full Changelog: https://github.com/chrisguidry/docket/compare/0.17.5...0.17.6
feat(cron): add support for custom timezones by @omikader in https://github.com/chrisguidry/docket/pull/312
Full Changelog: https://github.com/chrisguidry/docket/compare/0.17.4...0.17.5
Big thanks to @omikader who's been a partner in thinking through some big refactorings, culminating in a very clean addition of a new Cron dependency!
Big thanks to @omikader who's been a partner in thinking through some big refactorings, culminating in a very clean addition of a new Cron dependency!
from docket.dependencies import Cron
async def hourly_session_cleanup(cron: Cron = Cron("15 * * * *")):
... clean up user sessions at the :15 mark of every hour ...
# @daily is equivalent to "0 0 * * *" (midnight every day)
async def daily_report(cron: Cron = Cron("@daily")):
... run the daily report ...
Cron dependencies default to automatic=True (so they just automatically get scheduled for their next appropriate run) but you can disable them if you want more control by setting automatic=False.
Full Changelog: https://github.com/chrisguidry/docket/compare/0.17.3...0.17.4
Fix memory leak in _tasks_by_key cleanup by @chrisguidry in https://github.com/chrisguidry/docket/pull/309
Full Changelog: https://github.com/chrisguidry/docket/compare/0.17.2...0.17.3
That persistent memory leak may just be fixed !
That persistent memory leak may just be fixed :pray:!
But there are a lot of other goodies here, with a major refactoring of the Worker to move more hard-coded behavior into dependencies! Retries, perpetuals, timeouts, and concurrency limiting are all now driven entirely by their dependencies, with a well-defined interface to the Worker that keeps the worker simpler and leaner while enabling more extension by user code.
Full Changelog: https://github.com/chrisguidry/docket/compare/0.17.1...0.17.2
Fix memory leak in fakeredis Lua script execution by @chrisguidry in https://github.com/chrisguidry/docket/pull/300
Full Changelog: https://github.com/chrisguidry/docket/compare/0.17.2b2...0.17.2b3
Introduce Runtime base class for execution-controlling dependencies by @chrisguidry in https://github.com/chrisguidry/docket/pull/298
Full Changelog: https://github.com/chrisguidry/docket/compare/0.17.2b1...0.17.2b2
Unify cancellation and cleanup handling by @chrisguidry in https://github.com/chrisguidry/docket/pull/296
Full Changelog: https://github.com/chrisguidry/docket/compare/0.17.1...0.17.2b1
Re-export _Depends and _parameter_cache from dependencies package by @chrisguidry in https://github.com/chrisguidry/docket/pull/294
Full Changelog: https://github.com/chrisguidry/docket/compare/0.17.0...0.17.1
We finally have *Redis cluster support* thanks to some initial research and exploration by @zzstoatzz, who helped me realize that we could in fact do
This is a big one!
We finally have Redis cluster support thanks to some initial research and exploration by @zzstoatzz, who helped me realize that we could in fact do it! Point your Docket to a redis+cluster://... or rediss+cluster:// URL and everything should just work :pray:.
Second, we have a new kind of dependency function called a Shared dependency, and the idea is that these are shared across all your tasks for the lifespan of the Worker. Think FastAPI lifespan functions, but you declare them on your tasks instead of separately outside of them. It looks like this:
from contextlib import asynccontextmanager
from docket import Depends, Shared, task
async def load_config():
"""Worker-scoped: loaded once at startup, same config for all tasks."""
return await fetch_config_from_vault()
@asynccontextmanager
async def db_pool():
"""Worker-scoped: created once, shared by all tasks, closed at shutdown."""
pool = await create_pool("postgresql://...")
yield pool
await pool.close()
@asynccontextmanager
async def db_connection(pool: Pool = Shared(db_pool)):
"""Task-scoped: fresh connection per task, returned to pool after."""
async with pool.connection() as conn:
yield conn
@task
async def process_order(
order_id: int,
db: Connection = Depends(db_connection),
config: Config = Shared(load_config),
):
await db.execute(
"UPDATE orders SET status = $1 WHERE id = $2",
config.default_status,
order_id,
)
Big thanks to @omikader for the feature request and brainstorming that brought us to this.
Full Changelog: https://github.com/chrisguidry/docket/compare/0.16.6...0.17.0
Use separate connection pool for result storage by @chrisguidry in https://github.com/chrisguidry/docket/pull/276
Full Changelog: https://github.com/chrisguidry/docket/compare/0.16.5...0.16.6
Use docket.key() for remaining inline key constructions by @chrisguidry in https://github.com/chrisguidry/docket/pull/274
Full Changelog: https://github.com/chrisguidry/docket/compare/0.16.4...0.16.5
Add pragma no cover to redis connection retry in conftest by @chrisguidry in https://github.com/chrisguidry/docket/pull/264
Full Changelog: https://github.com/chrisguidry/docket/compare/0.16.3...0.16.4
Fix worker __aexit__ hanging on early cancellation by @chrisguidry in https://github.com/chrisguidry/docket/pull/263
Full Changelog: https://github.com/chrisguidry/docket/compare/0.16.2...0.16.3
Refactor StrikeList into standalone class with optional Redis sync by @joshuastagner in https://github.com/chrisguidry/docket/pull/242
Full Changelog: https://github.com/chrisguidry/docket/compare/0.16.1...0.16.2
Allow memory:// URLs for docket worker command by @chrisguidry in https://github.com/chrisguidry/docket/pull/257
Full Changelog: https://github.com/chrisguidry/docket/compare/0.16.0...0.16.1
Docket 0.16 makes a subtle change that should make longer-running tasks much more reliable: workers will now periodically renew the leases for all of
Docket 0.16 makes a subtle change that should make longer-running tasks much more reliable: workers will now periodically renew the leases for all of the tasks they are currently managing so that they aren't redelivered to new workers while they are still healthily executing. Over docket's lifetime so far, the redelivery mechanism has been one of the flakiest and maddening things, and this simple change should make things much more easy to think about for task developers.
Prior to this change, you'd have to think about redelivery in terms of the slowest tasks you intended to run on that docket, and would have to suffer long redelivery delays to accomodate those slow tasks. Worse, the implicit timeout at redelivery_timeout caused a race between Docket and Redis, resulting in occasional duplication of those tasks.
Docket in versions prior to 0.16 would add an implicit timeout to all tasks that didn't declare one itself. This timeout was set to the redelivery_timeout. This timeout is no longer added automatically so you may want to add your own Timeout if you were depending on that.
Full Changelog: https://github.com/chrisguidry/docket/compare/0.15.6...0.16.0
Fix markdown lists in documentation by @davidbrochart in https://github.com/chrisguidry/docket/pull/235
Full Changelog: https://github.com/chrisguidry/docket/compare/0.15.5...0.15.6
Suppress internal Redis polling spans by default by @chrisguidry in https://github.com/chrisguidry/docket/pull/234
Full Changelog: https://github.com/chrisguidry/docket/compare/0.15.4...0.15.5
This release is all about squashing tiny flakes in the test suite (and tiny timing bugs in Docket!), as well as getting Docket's security posture up t
This release is all about squashing tiny flakes in the test suite (and tiny timing bugs in Docket!), as well as getting Docket's security posture up to snuff. This enables just about the full gamut of Github's automated security features.
Full Changelog: https://github.com/chrisguidry/docket/compare/0.15.3...0.15.4
Lazy stream/consumer group bootstrap by @chrisguidry in https://github.com/chrisguidry/docket/pull/215
Full Changelog: https://github.com/chrisguidry/docket/compare/0.15.2...0.15.3
Move signal handling to CLI entry point only by @chrisguidry in https://github.com/chrisguidry/docket/pull/214
Full Changelog: https://github.com/chrisguidry/docket/compare/0.15.1...0.15.2
Add Redis 8.0 to CI test matrix by @chrisguidry in https://github.com/chrisguidry/docket/pull/210
Full Changelog: https://github.com/chrisguidry/docket/compare/0.15.0...0.15.1
Important note: prior to this release, it was possible for a task to re-add itself during its own execution with docket.add(...), but that ability exp
Important note: prior to this release, it was possible for a task to re-add itself during its own execution with docket.add(...), but that ability exposes a race condition. Instead, in that scenario, you'd do a docket.replace(...) instead (see the test changes in #209 for the example). Also, if you have tasks that reschedule themselves (by key) this way, try using a Perpetual dependency instead, it may be more ergonomic.
Full Changelog: https://github.com/chrisguidry/docket/compare/0.14.1...0.15.0
Fix flaky concurrency test and reorganize test suite by @chrisguidry in https://github.com/chrisguidry/docket/pull/202
python-json-logger by @zzstoatzz in https://github.com/chrisguidry/docket/pull/203Full Changelog: https://github.com/chrisguidry/docket/compare/0.14.0...0.14.1
Refactor progress interface to use Progress instead of ExecutionProgress by @chrisguidry in https://github.com/chrisguidry/docket/pull/201
Full Changelog: https://github.com/chrisguidry/docket/compare/0.13.4...0.14.0
bump py kv by @zzstoatzz in https://github.com/chrisguidry/docket/pull/200
Full Changelog: https://github.com/chrisguidry/docket/compare/0.13.3...0.13.4
With the magnanimous help of @zzstoatzz, pydocket is getting a Conda feedstock! This is one step along the way :steam_locomotive:
With the magnanimous help of @zzstoatzz, pydocket is getting a Conda feedstock! This is one step along the way :steam_locomotive:
Full Changelog: https://github.com/chrisguidry/docket/compare/0.13.2...0.13.3
Add CANCELLED state for task cancellation tracking by @chrisguidry in https://github.com/chrisguidry/docket/pull/193
Full Changelog: https://github.com/chrisguidry/docket/compare/0.13.1...0.13.2
Add Docket.get_execution() method for claim check pattern by @chrisguidry in https://github.com/chrisguidry/docket/pull/192
Full Changelog: https://github.com/chrisguidry/docket/compare/0.13.0...0.13.1
This was a pretty substantial release, bringing some old ideas to fruition:
This was a pretty substantial release, bringing some old ideas to fruition:
Full Changelog: https://github.com/chrisguidry/docket/compare/0.12.0...0.13.0
Add support for execution_ttl=0 and timeout/deadline parameters by @chrisguidry in https://github.com/chrisguidry/docket/pull/189
Full Changelog: https://github.com/chrisguidry/docket/compare/0.13.0b2...0.13.0b3
Reset contextvar tokens in resolved_dependencies by @chrisguidry in https://github.com/chrisguidry/docket/pull/178
Full Changelog: https://github.com/chrisguidry/docket/compare/0.12.0...0.13.0b2
Nothing published for this version
Register greet function with the worker by @chrisguidry in https://github.com/chrisguidry/docket/pull/169
Depends by @desertaxle in https://github.com/chrisguidry/docket/pull/172Full Changelog: https://github.com/chrisguidry/docket/compare/0.11.1...0.12.0
Add Agenda class for task scattering over time periods by @chrisguidry in https://github.com/chrisguidry/docket/pull/159
Full Changelog: https://github.com/chrisguidry/docket/compare/0.11.0...0.11.1
Your coding agent can read these notes before it upgrades. Set up the MCP server →