Sluice vs Flower: A Practical Comparison for Celery Teams
If you're running Celery in production, you've almost certainly used Flower. It's the default answer to "how do I see what my tasks are doing?" -- recommended in Celery's own documentation, installed by millions of teams, and genuinely useful for quick debugging during development.
But if you've ever restarted Flower and watched your entire task history vanish, or been paged at 3am only to discover that Flower can't tell you what failed two hours ago, you already know the gap between a debugging tool and a production monitoring system.
This page is a fair, technical comparison between Flower and Sluice. We'll cover what each tool does well, where they fall short, and when you should use one versus the other.
The State of Celery Monitoring
Celery powers background job processing for thousands of Python applications -- from payment queues at fintech companies to ML pipeline orchestration at AI startups. It has over 28,000 GitHub stars and tens of millions of monthly PyPI downloads. It is, by a wide margin, the most popular task queue in the Python ecosystem.
Flower has been the go-to monitoring tool for Celery since 2012. With over 7,000 GitHub stars and nearly 10 million monthly PyPI downloads, roughly one in four Celery downloads also includes Flower. That's a remarkable adoption rate for a monitoring tool, and it speaks to just how badly Celery teams need visibility into their task queues.
But Flower was designed for a different era of Celery usage. When it launched, most Celery deployments were single-server setups running a handful of task types. Today's Celery deployments span dozens of workers across container orchestration platforms, process millions of tasks per day, and require the same operational rigor as any other production infrastructure.
The gap between what Flower provides and what production Celery teams need has been widening for years -- and the community has noticed.
Where Flower Falls Short
We want to be fair here. Flower served the Celery community well for over a decade, and it remains useful for certain workflows. But there are real, documented limitations that affect production usage. None of these are opinions -- they're architectural constraints and observable behaviors.
No production-grade persistence
Flower stores task state in memory by default. It does have a --persistent flag that writes state to a local file via Python's shelve module, but this feature is widely reported as unreliable -- multiple open issues document data not being saved, unexpectedly large database files, and inconsistent behavior across versions. Even when it works, shelve provides no queryable history, no search, and no retention management.
In practice, when Flower restarts -- whether from a deployment, a crash, or a pod reschedule in Kubernetes -- task history is effectively gone. You cannot answer "what failed last Tuesday?" or "how many retries did we have this week?" because there's no durable, queryable database behind it.
For local debugging, this is fine. For production monitoring where you need to investigate incidents after the fact, it's a fundamental limitation.
No alerting
Flower is a dashboard. It shows you what's happening right now, but it can't notify you when something goes wrong. If a queue backs up at 2am or a critical task starts failing silently, nobody finds out until someone opens Flower and looks -- or until a customer reports the downstream impact.
Most teams work around this by bolting on separate alerting through Prometheus exporters, custom scripts, or cron jobs that poll Flower's API. This works, but it means maintaining two or three systems to get what should be a single capability.
No Beat monitoring
Celery Beat is the scheduler that triggers periodic tasks -- billing runs, data syncs, cache warmups, report generation. If Beat dies, those tasks simply stop running. No error gets raised because there's nothing to raise it. The absence of expected work is invisible.
Flower shows some scheduled task metadata in its Config tab, but it cannot detect missed Beat executions -- if a periodic task fails to fire, Flower has no way to notice or alert. It can't tell you that your generate_daily_report task was supposed to run at midnight but didn't. By the time someone notices the reports are missing, hours or days may have passed.
Scaling issues in containerized environments
Flower identifies workers by hostname. In Docker and Kubernetes environments where multiple workers can share the same container hostname, this creates well-documented issues with worker deduplication. Flower may show one worker where there are actually three, or display stale worker entries that don't correspond to running processes.
There are workarounds -- setting custom hostnames per container, using the --without-mingle flag -- but they add operational complexity that shouldn't be necessary.
Maintenance status
Flower's last PyPI release was in August 2023, and the repository has nearly 200 open issues as of early 2026. Celery core contributors have begun work on a modernized fork with ASGI support, which is a positive sign for the project's future -- but it also reflects the maintenance gap that preceded it.
This isn't a criticism of the maintainers. Open-source maintenance is hard, often thankless work. But for teams relying on Flower in production, the slow pace of updates means known bugs linger and compatibility with newer Celery versions can lag.
No silent failure detection
Some of the worst Celery failures are the ones that produce no error at all. A task that gets published but never arrives at a worker (lost in transit due to broker issues). A worker that gets OOM-killed mid-execution, leaving the task in a permanent PENDING state. A queue that gradually fills because consumers crashed and nobody noticed.
Flower can't detect any of these scenarios because they don't produce the Celery events that Flower relies on. The absence of events is, by definition, invisible to an event-driven dashboard.
Feature Comparison
Here's a detailed comparison of capabilities. We've marked V1 features honestly -- Sluice doesn't claim to have what it hasn't shipped yet.
| Capability | Flower | Sluice |
|---|---|---|
| Individual task visibility | Yes -- real-time task list with state, args, result | Yes -- task list with search, filter, and full detail view |
| Queue depth monitoring | Limited -- shows active tasks per queue | Yes -- real-time queue depth with historical data |
| Worker health | Yes -- online/offline status, active tasks, stats | Yes -- worker status, active tasks, task throughput |
| Task retry/revoke | Yes -- via dashboard UI (sends commands to broker) | Yes -- retry and revoke from dashboard (V0: state tracking only; broker-level commands in V1) |
| Alerting | No | Upcoming in V1 -- Slack, PagerDuty, email, webhooks |
| Data persistence | Limited -- --persistent flag uses shelve (widely reported as buggy) | Yes -- Postgres-backed, survives restarts, full history |
| Setup time | ~30 seconds (basic); longer for production hardening | ~30 seconds (SDK) or ~2 minutes (Docker agent) |
| Maintenance burden | Medium -- self-hosted, must manage process/container | Low -- SaaS, managed infrastructure |
| Beat schedule monitoring | No | Upcoming in V1 -- dead man's switch for periodic tasks |
| Silent stall detection | No | Upcoming in V1 -- detects tasks stuck beyond expected thresholds |
| Search and filter | Limited -- basic task name filtering | Yes -- full-text search, filter by state/queue/worker/time range |
| Real-time updates | Polling-based (auto-refresh) | Yes -- SSE-based with near real-time event delivery |
| API access | Yes -- REST API for task data | Internal API (powers dashboard); public documented API in V1 |
| Traceback display | Yes -- shows exception info | Yes -- full traceback with formatted output |
| PENDING state handling | Treats as "waiting" | Disambiguates "never seen" from "seen and waiting" |
| Multi-worker support | Hostname-based (issues in containers) | Worker-ID-based, container-native |
| Cost | Free (self-hosted) | Free tier: 10K tasks/day. Paid plans coming in V1. |
What Sluice Does Differently
Sluice isn't a Flower fork or a Flower wrapper. It's a different architecture built for a different problem: production Celery monitoring with persistence, real-time visibility, and (soon) alerting.
Postgres-backed persistence
Every task event that Sluice captures gets written to Postgres. Task history survives restarts, deployments, and infrastructure failures. When you need to investigate a 3am incident the next morning, the data is there -- task names, states, tracebacks, timing, retry counts, all of it. Task arguments and return values are available as an opt-in feature in V1.
This is the single biggest architectural difference from Flower. Sluice persists task history to Postgres. Flower's --persistent mode uses a local shelve file that is unreliable in practice and provides no queryable history.
Real-time SSE with sub-5-second latency
Sluice uses Server-Sent Events for real-time dashboard updates. The Go agent captures Celery events from your Redis broker and forwards them to the Sluice platform with sub-5-second end-to-end latency. No polling, no manual refresh. The dashboard updates as tasks flow through your system.
30-second setup
Sluice connects to your Celery infrastructure in two ways, and both are fast:
The Python SDK integrates directly with your Celery application -- two lines of configuration and you're capturing events. The Go agent connects to your Redis broker independently, requiring zero code changes to your application.
Either path gets you from "nothing" to "seeing live task data" in under a minute. Compare that to setting up a Grafana + Prometheus + StatsD pipeline, which typically takes 2--4 hours of configuration and ongoing maintenance.
PENDING state disambiguation
Celery's PENDING state is one of the most misunderstood concepts in the framework. A task in PENDING doesn't mean "waiting in the queue." It means "Celery has no information about this task." The task might be queued, it might have been lost, it might never have been published at all. PENDING is the default state for any task ID, including ones that don't exist.
Flower displays PENDING tasks alongside genuinely queued tasks with no distinction. Sluice tracks whether a task has actually been observed in the broker and separates "never seen" (truly unknown) from "seen and waiting" (genuinely queued). This distinction matters enormously when debugging missing-task scenarios.
For a deeper dive into why this matters, see Understanding Celery's PENDING State.
Built for containers from day one
Sluice identifies workers by their unique IDs rather than hostnames, which eliminates the container hostname deduplication issues that plague Flower in Docker and Kubernetes environments. Three replicas of the same worker image show up as three distinct workers, each with their own health status and task throughput metrics.
Setup Comparison
Flower
pip install flower
celery -A myproject flower --port=5555
Open http://localhost:5555. You have a dashboard. Data lives in RAM. No persistence, no alerting, no external dependencies beyond Celery itself.
To run Flower in production, you'll also need to handle: process management (systemd/supervisor), authentication (Flower has basic auth but no SSO), reverse proxy configuration, and container hostname deduplication if running in Docker/Kubernetes.
Sluice -- Python SDK
pip install sluice
# settings.py or celery.py
import sluice
sluice.init(api_key="sk_live_...")
That's it. The SDK hooks into Celery's event system and forwards task events to Sluice. Your dashboard is live at sluice.sh within seconds.
Sluice -- Docker Agent (zero code changes)
docker run -d \
-e SLUICE_API_KEY=sk_live_... \
-e REDIS_URL=redis://your-broker:6379/0 \
ghcr.io/sluice-project/agent:latest
The Go agent connects directly to your Redis broker and captures Celery events without touching your application code. Useful when you can't or don't want to modify your Celery configuration -- for example, if you're monitoring a third-party service that uses Celery internally, or if your deployment process makes code changes slow to roll out.
When to Use Which
Use Flower if:
- You're debugging locally. Flower is excellent for development-time task inspection.
celery -A proj flowergives you instant visibility with zero infrastructure. - You need zero external dependencies. Flower runs entirely within your environment with no SaaS dependency. If you can't send data to an external service for compliance or air-gap reasons, Flower is self-contained.
- You don't need historical data. If you only care about what's happening right now and never need to look back, Flower's in-memory model is sufficient.
- Budget is truly zero. Flower is free and open-source. Sluice has a free tier (10K tasks/day), but if you exceed that, there's a cost.
Use Sluice if:
- You need to investigate past incidents. "What failed at 3am?" is unanswerable with Flower after a restart. Sluice's Postgres-backed persistence means the full task history is always available.
- You need alerting on failures. Watching a dashboard 24/7 isn't a monitoring strategy. Sluice's upcoming V1 alerting will notify your team via Slack, PagerDuty, email, or webhooks when tasks fail, queues back up, or workers go offline.
- Your team needs shared visibility. A monitoring tool that only one person has open isn't useful during incidents. Sluice provides a shared, persistent view that the whole team can reference.
- You're running Celery in containers. Sluice handles container orchestration environments natively, without the hostname workarounds Flower requires.
- You need to detect silent failures. Tasks lost in transit, workers killed mid-execution, queues filling because consumers died -- Sluice's PENDING state disambiguation separates "never seen" from "seen and waiting," and upcoming V1 alerting will surface silent failures that produce no events for a dashboard to display.
For teams that are currently running no monitoring at all, see The Real Cost of Running Celery Without Monitoring.
Migration Guide
Moving from Flower to Sluice doesn't have to be a hard cutover. Here's the low-risk path most teams follow:
Step 1: Sign up and get an API key
Create an account at sluice.sh. The free tier covers 10,000 tasks per day -- enough to evaluate whether Sluice meets your needs before committing.
Step 2: Install the SDK or run the agent
Choose whichever integration method fits your workflow:
SDK approach -- add sluice to your requirements and call sluice.init() in your Celery configuration. This captures events directly from your Celery application.
Agent approach -- run the Docker agent pointed at your Redis broker. This captures events independently with zero code changes.
Either way, you should see live task data in your Sluice dashboard within seconds.
Step 3: Run both in parallel
Keep Flower running alongside Sluice for a week or two. Use Flower as your familiar reference point while you learn the Sluice dashboard. Compare the data between them to build confidence that Sluice is capturing everything you expect.
This is the step most teams skip, and the one we'd encourage you not to. Monitoring tools earn trust through consistency over time, not through a five-minute demo.
Step 4: Retire Flower when you're ready
Once you're confident in Sluice's coverage, remove Flower from your deployment. There's no urgency here -- Flower and Sluice don't interfere with each other, and running both has negligible overhead.
For common task failure investigation patterns in Sluice, see How to Debug Celery Task Failures.
Frequently Asked Questions
Is Flower dead?
No. The original repository (mher/flower) still receives community contributions, and Celery core contributors have started a modernized fork with ASGI support. That said, the last PyPI release was August 2023, and the pace of development has been slow relative to the nearly 200 open issues in the repository. Flower is alive, but its trajectory has been one of maintenance rather than active feature development.
We genuinely hope Flower continues to improve. A healthy open-source ecosystem benefits everyone, including Sluice.
Can I use both Flower and Sluice?
Yes. They operate independently and don't conflict. Both consume Celery events, and Celery is designed to support multiple event consumers. Many teams run Flower locally for quick debugging and Sluice for production monitoring. There's no performance penalty to running both.
Does Sluice support RabbitMQ?
Sluice V0 supports Redis as the Celery broker. RabbitMQ support is on the roadmap. If you're running Celery with RabbitMQ and interested in Sluice, reach out at hello@sluice.sh -- we'd like to understand your setup.
What happens when I exceed the free tier?
The free tier covers 10,000 tasks per day. When you exceed that limit, Sluice continues capturing events for the rest of the day but pauses ingestion at the next billing boundary until the counter resets. You don't lose access to historical data, and there are no surprise charges. Paid plans with higher limits are coming in V1.
Is Sluice open source?
The Sluice Python SDK is open source. The Go agent is distributed as a container image. The Sluice platform (dashboard, API, persistence layer) is a commercial SaaS product. We believe this is the right balance -- the code that runs in your infrastructure is inspectable, while the hosted platform funds ongoing development and support.
Does Sluice read my task arguments or results?
By default, Sluice captures task metadata -- task name, state transitions, timing, queue, worker, and exception info. Task arguments and return values are redacted by default to protect sensitive data. You can opt in to capturing arguments and results on a per-task basis if you need that level of detail for debugging.
How does Sluice handle Celery's PENDING state?
This is one of the most commonly misunderstood aspects of Celery. PENDING doesn't mean "queued" -- it means "Celery has no information about this task." Sluice tracks whether a task has actually been observed in the system and distinguishes between truly unknown tasks and tasks that are genuinely waiting for execution. See Understanding Celery's PENDING State for the full explanation.
The Bottom Line
Flower is a good tool for what it was designed to do: give you a real-time window into your Celery cluster during development and quick debugging sessions. It's free, it's simple, and it works.
But production Celery monitoring needs more than a real-time window. It needs persistence so you can investigate past incidents. It needs alerting so you find out about failures before your customers do. It needs to handle containerized environments without workarounds. And it needs to detect the silent failures -- stalled tasks, dead schedulers, lost messages -- that produce no events for a dashboard to display.
Sluice is -- to our knowledge -- the first commercial Celery monitoring tool with persistent task history, real-time visibility, and a path to built-in alerting. It's what you'd build internally if you had a month and a team -- a Postgres-backed, SSE-driven monitoring platform purpose-built for Celery in production.
Flower got the community here. Sluice is the next step.
Get started free at sluice.sh -- 30 seconds to connect, 10K tasks/day on the free tier, no credit card required.
For a comparison with the Grafana + Prometheus monitoring stack, see Sluice vs Grafana + Prometheus. For more on Celery Beat monitoring challenges, see How to Monitor Celery Beat Schedules.