Back to Articles

Windmill: The Postgres-Backed Developer Platform That's 13x Faster Than Airflow

[ View on GitHub ]

Windmill: The Postgres-Backed Developer Platform That's 13x Faster Than Airflow

Hook

What if every Python script you wrote automatically became a shareable web app with a generated UI, webhook endpoint, and scheduled execution—without writing a single line of frontend code?

Context

The modern developer infrastructure stack has become absurdly fragmented. You need Airflow or Temporal for workflows, Retool or internal React apps for tooling, cron jobs for scheduling, API Gateway for webhooks, and a patchwork of scripts held together with hope and SSH. Each tool requires its own deployment pipeline, authentication system, and operational overhead.

Windmill emerged from this chaos as a unified developer platform that refuses to accept this fragmentation as inevitable. Built by developers frustrated with the complexity of orchestrating simple tasks across multiple systems, it treats scripts as first-class infrastructure primitives. The core insight: if you can express logic in code (Python, TypeScript, Go, Bash, or Rust), Windmill can turn it into a webhook, scheduled job, workflow step, or auto-generated UI without requiring you to learn proprietary DSLs or deploy separate services. It's self-hostable, Postgres-backed, and claims 13x performance improvements over Airflow—a bold assertion backed by benchmarks showing superior throughput through a Rust-based execution engine.

Technical Insight

Windmill's architecture centers on a Postgres-backed job queue with stateless Rust API servers and worker nodes that execute scripts in sandboxed environments. This isn't just another workflow engine—it's a rethinking of how developer platforms should handle state, execution, and UI generation.

The automatic UI generation is particularly elegant. Write a Python function with type hints, and Windmill parses those annotations to create form inputs:

def send_alert(message: str, severity: Literal["info", "warning", "critical"], recipients: list[str]):
    """Send alert notification to team members"""
    # Your notification logic here
    return {"sent": True, "count": len(recipients)}

This function automatically becomes a web UI with a text input for message, a dropdown for severity (populated from the Literal type), and a dynamic list builder for recipients. No React components, no form validation code, no API boilerplate. The type system becomes your UI specification language. The same approach works for TypeScript using TypeScript types and Go using struct tags. This is possible because Windmill's runtime performs static analysis on your scripts before execution, extracting parameter schemas that drive the UI layer.

The workflow engine differentiates itself through Postgres-centric design. Unlike Temporal's event sourcing or Airflow's SQLAlchemy DAGs, Windmill stores all job state, execution history, and dependencies directly in Postgres tables with JSONB columns for flexible metadata. Workers poll the queue using SELECT ... FOR UPDATE SKIP LOCKED, a Postgres-specific pattern that enables lock-free, concurrent job claiming across distributed workers. This eliminates the need for Redis or external message brokers—Postgres becomes the single source of truth.

Performance claims are backed by architectural choices. The Rust-based worker runtime minimizes overhead per job execution. Scripts run in nsjail sandboxes with pre-warmed language runtimes (Python via uv, TypeScript via Bun/Deno), avoiding cold-start penalties. For TypeScript specifically:

// This runs in Bun with sub-50ms startup time
export async function process_webhook(payload: { user_id: string, action: string }) {
    const db = await wmill.getResource('postgres_db')
    const result = await db.query('INSERT INTO events VALUES ($1, $2)', [payload.user_id, payload.action])
    return { processed: true, id: result.insertId }
}

The wmill SDK provides access to Windmill-managed resources (database connections, API keys, secrets) through a permission system integrated with Postgres RLS policies. Resources are versioned, encrypted at rest, and scoped to workspaces—eliminating the hardcoded credentials problem that plagues most script-based automation.

Bidirectional Git sync enables true GitOps workflows. Scripts, workflows, and resources sync to Git repositories as YAML/JSON files. Push to main, and Windmill automatically deploys changes. The VS Code extension provides local development with type checking and autocomplete against your production instance's resource schemas. This bridges the gap between local iteration and production deployment without sacrificing the immediacy of script-based development.

The flow builder supports both visual DAG construction and code-based workflow definitions. Flows can branch based on previous step results, run steps in parallel, handle retries with exponential backoff, and trigger sub-flows. Each step can be written in a different language—Python for data processing, TypeScript for API calls, Bash for system commands—composed into cohesive workflows without polyglot runtime complexity.

Gotcha

The AGPLv3 license is a significant consideration. Any modifications to Windmill's source code that you deploy as a networked service must be open-sourced. If you're building proprietary internal modifications or white-labeling the platform, you'll need a commercial license. This isn't a limitation per se, but it's a business consideration that catches teams off-guard who assume 'open-source' means unrestricted commercial use.

Postgres as the exclusive backend is both a strength and a constraint. While Windmill optimizes Postgres heavily (connection pooling, prepared statements, JSONB indexing), it remains a single database dependency. For extremely high-throughput scenarios exceeding hundreds of jobs per second, Postgres can become a bottleneck despite optimizations. The architecture doesn't support sharding or multi-database deployments, which limits horizontal scaling options compared to systems built on distributed queues like Kafka or RabbitMQ. Teams already operating multi-region, multi-database infrastructures may find this centralization limiting.

Sandboxing via nsjail requires Linux kernel features (namespaces, cgroups) that aren't universally available. This complicates deployment on macOS for local development (requiring Docker), certain cloud platforms with restricted kernel access, and nested containerized environments. While Docker deployment is well-supported, teams wanting serverless-style deployments or running on non-Linux systems will encounter friction. The sandboxing is essential for security—executing untrusted code requires isolation—but it's a hard dependency that eliminates some deployment patterns.

Verdict

Use Windmill if you're consolidating fragmented internal tooling and automation into a self-hosted platform, need automatic UI generation from scripts without frontend development, want Git-native workflows with local development support, or require multi-language script execution with centralized permission management. The performance improvements over Airflow make it compelling for high-throughput workflow scenarios, and the combination of workflow orchestration plus internal tooling eliminates the Temporal+Retool stack split. Skip it if you cannot comply with AGPLv3 licensing and won't pay for commercial licenses, need multi-database or multi-region deployment patterns beyond Postgres replication, require deployment on platforms without Linux kernel namespace support, or already have deeply integrated separate solutions for workflows and internal tools where migration costs outweigh consolidation benefits.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/automation/windmill-labs-windmill.svg)](https://starlog.is/api/badge-click/automation/windmill-labs-windmill)