Skip to content

Commit 59bf258

Browse files
authored
Merge pull request #170 from dkliban/redis-worker-blog
Adds blog post about RedisWorker.
2 parents 22f4a3b + b8545ad commit 59bf258

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
---
2+
date: 2026-01-13T00:00:00Z
3+
title: New Worker Type and AI Driven Development
4+
authors:
5+
- dkliban
6+
tags:
7+
- performance
8+
- tasking
9+
- redis
10+
---
11+
# New Worker Type and AI Driven Development
12+
13+
A performance breakthrough came from an innovative collaboration with AI. We explained the PostgreSQL load challenges we were facing to an AI assistant, which designed an algorithm that offloads resource locking to Redis while maintaining task ordering guarantees. The AI then helped write the implementation code and test suite, dramatically accelerating our development process. This approach allowed us to rapidly prototype and validate the solution, demonstrating how AI can be a powerful tool for tackling complex architectural challenges.
14+
15+
We're excited to share that RedisWorker delivers 2.3x performance improvement! Our recent performance benchmarking demonstrates significant throughput improvements in Pulp's tasking system. By offloading resource locking from PostgreSQL to Redis and eliminating the task unblocking mechanism, we've achieved more than double the task processing throughput.
16+
17+
<!-- more -->
18+
19+
## Architecture Benefits
20+
21+
By separating resource locking from the main database and eliminating the unblocking subsystem:
22+
23+
1. **Reduced PostgreSQL Load**: Database queries are limited to task CRUD operations, not constant lock checking or unblocking.
24+
2. **Faster Lock Operations**: Redis's in-memory operations are generally faster than PostgreSQL advisory locks.
25+
3. **Better Scalability**: Users can start more workers with less load on the database.
26+
4. **Improved Throughput**: The system can process more than twice as many tasks per second.
27+
28+
## Benchmark Results
29+
30+
Our testing compared the existing `PulpcoreWorker` implementation against the new `RedisWorker` implementation under similar conditions with 80 workers and a db.m7g.large RDS instance on AWS (2 vCPUs, 8GB RAM, AWS Graviton3 physical CPU):
31+
32+
**PulpcoreWorker Performance:**
33+
34+
- Processed: 20,296 completed tasks
35+
- Time window: 671.25 seconds
36+
- **Average throughput: 30.24 tasks/sec**
37+
38+
**RedisWorker Performance:**
39+
40+
- Processed: 21,419 completed tasks
41+
- Time window: 306.91 seconds
42+
- **Average throughput: 69.79 tasks/sec**
43+
44+
The RedisWorker achieved **2.3x higher throughput** (69.79 vs 30.24 tasks/sec) while processing a similar number of tasks in less than half the time.
45+
46+
## How We Achieved This
47+
48+
The performance improvement comes from two key innovations: offloading resource lock coordination to Redis and eliminating the task unblocking mechanism. Here's what changed:
49+
50+
**Existing PulpcoreWorker Approach:**
51+
52+
- Uses PostgreSQL advisory locks for task resource coordination
53+
- At any given time, one worker constantly queries the database to find and unblock waiting tasks
54+
- This unblocking process runs continuously, creating steady database load
55+
- Lock operations create additional load on the PostgreSQL database
56+
- Suitable for most deployments, especially when Redis isn't available
57+
58+
**New RedisWorker Approach:**
59+
60+
- Uses Redis distributed locks for resource coordination
61+
- No unblocking mechanism needed - workers simply attempt to acquire locks for waiting tasks
62+
- If locks can't be acquired, the task remains in the queue for the next worker to try
63+
- Eliminates the continuous database queries for task unblocking
64+
- Significantly reduces both database load and unnecessary CPU work
65+
- Scales better under high task volumes by doing less work overall
66+
67+
## What Work Is Eliminated
68+
69+
RedisWorker achieves its performance gains by completely eliminating several resource-intensive operations:
70+
71+
1. **No PostgreSQL LISTEN/NOTIFY Infrastructure**: PulpcoreWorker subscribes to multiple PostgreSQL notification channels (`pulp_worker_cancel`, `pulp_worker_metrics_heartbeat`, `pulp_worker_wakeup`) and broadcasts notifications via `pg_notify()`. RedisWorker uses Redis-based cancellation signals instead, eliminating this database overhead.
72+
73+
2. **No Continuous Task Unblocking**: PulpcoreWorker's unblocking mechanism queries ALL incomplete tasks from the database on every cycle, iterating through potentially thousands of tasks to calculate resource conflicts. RedisWorker eliminates this entirely - it queries the first 20 waiting tasks and attempts to acquire locks.
74+
75+
3. **No Database Writes for Unblocking**: PulpcoreWorker must update an `unblocked_at` timestamp for each task that becomes eligible to run. RedisWorker has no unblocking concept, so these database writes are eliminated.
76+
77+
4. **Simpler Task Queries**: PulpcoreWorker requires `unblocked_at IS NOT NULL` in its fetch query, creating a dependency chain (dispatch → unblock → fetch → execute). RedisWorker queries tasks directly (dispatch → fetch+lock → execute).
78+
79+
The result: RedisWorker doesn't just move work to Redis - it eliminates an entire subsystem that was creating continuous database load.
80+
81+
## Configuration
82+
83+
The worker type is configurable via the `WORKER_TYPE` setting:
84+
85+
```python
86+
# Use PostgreSQL advisory locks (default, stable)
87+
WORKER_TYPE = "pulpcore"
88+
89+
# Use Redis distributed locks (higher performance)
90+
WORKER_TYPE = "redis"
91+
```
92+
93+
## Important Considerations
94+
95+
While RedisWorker delivers superior performance, there are some trade-offs to consider:
96+
97+
- **Redis Dependency**: Requires a Redis instance to be available
98+
- **Stability**: PulpcoreWorker remains the default and is the more mature implementation
99+
100+
## When to Use RedisWorker
101+
102+
RedisWorker is ideal for:
103+
104+
- High-volume task processing environments
105+
- Deployments where Redis is already part of the infrastructure
106+
- Scenarios where task throughput is critical
107+
- Environments that struggle with database CPU load
108+
109+
## Looking Forward
110+
111+
These performance improvements represent a significant step forward for Pulp's scalability. Before RedisWorker becomes available to users, we need to:
112+
113+
1. Merge the implementation into the main codebase
114+
2. Validate the feature through our CI testing pipeline
115+
3. Include it in an upcoming Pulp release
116+
117+
We encourage users with high-throughput requirements to evaluate RedisWorker in their environments once it's released.
118+
119+
## Upgrading
120+
121+
Switching between worker types requires downtime. More detailed upgrade instructions and best practices will be available in the documentation once the new worker type is released.

0 commit comments

Comments
 (0)