Windmill: A great addition to every low code stack

Windmill: A great addition to every low code stack

Originally I was just going to discuss how to set up SSO in Windmill using authentik, but I thought it made sense to introduce Windmill first, so here you go. The separate Windmill + authentik post is over here.

I recently started using Windmill (which is a combined workflow engine and app builder) in addition to my standard stack of n8n + Budibase. Building workflows is usually faster with n8n, and apps built in Budibase usually look better, but Windmill complements the two quite nicely in certain scenarios. Here are the main differences I noticed between n8n and Windmill:

Workflow building

  • n8n truly embraces the no/low code idea. It comes with a large number of pre-built integrations (called nodes) which all have a good UI, letting users start in no time after authenticating. As a result, workflows relying on these existing integrations are typically built in no time at all. While its UI is sometimes a bit slow to respond (when working with larger amounts of data or complex workflows), n8n looks better and makes it really easy to understand what's happening in a workflow with just a quick glimpse. This category is a clear win for n8n.
  • Windmill requires users to write code. Instead of pre-built integrations, there is a repository of script templates. Windmill auto-generates a UI based on variables used by these scripts when executed manually which works for developers, but can be confusing for regular users as there is limited input validation and usually no additional context. This makes Windmill scripts harder to use out of the box, but it also means any pre-built logic can be customized on the fly. Windmill workflows are also displayed in a flow diagram (shown in the screenshot at the top of this article), but I find these typically take a bit longer for me to fully understand compared to n8n. The Windmill approach also means that implementing any new logic will typically take longer.

Coding

  • Code can also be added to n8n if needed, but managing dependencies is a bit cumbersome. For example, using an npm module in a typical container environment requires users to build a new container image and change environment variables to use that module. JavaScript and Python code is supported by n8n's Code node.
  • While writing code in n8n is more of a fallback solution if there is no pre-built integration for a job, Windmill embraces code completely. Windmill's user interface is completely code-centric. Out of the box, users can manage and execute JavaScript/TypeScript, Python, Go and Bash scripts (there are also templates for running PostgreSQL queries and Docker images, but these use the above languages). UI fields for all defined input variables appear automatically. Missing dependencies are automatically installed as needed (no need to even call pip or npm). Users who enjoy writing code will appreciate the flexibility this approach provides, Windmill rocks this category.

Performance

It really depends. The memory baseline is significantly lower with Windmill. Running a single n8n instance in main mode takes about 220MB for me, while my Windmill setup with 3 workers takes considerably less (130MB). In terms of CPU usage, it's pretty much the opposite. n8n uses considerably less CPU than Windmill at idle:

docker stats for n8n vs Windmill on the same server

During the execution of a simple workflow (fetching around 32 KB of JSON data and sending it to a REST API), n8n will require a little more CPU power than Windmill. Both handle my typical use cases fairly well though.

Visibility

Windmill does provide details on the memory consumption of a script which can help a lot with debugging:

The "past run" view in Windmill, showing the peak memory usage for the script

n8n requires a separate process manager (or the use of docker stats) to identify how much memory is required by a workflow execution.

In addition, Windmill shows a progress bar for each execution of a workflow (based on the current step and the total steps in a workflow). There is no difference between production and "test" runs, both can be opened at anytime and inspected:

The execution progress in Windmill

This is something n8n doesn't do for production executions. Instead, the progress of a currently running execution in n8n is indicated like so:

A running execution in n8n, showing the runtime

Manual ("test") executions on the other hand are displayed in full detail by n8n and data shows up as it comes in. This makes debugging quite fun:

A running manual execution in n8n

App building

This is a feature n8n doesn't offer out of the box, which is why I use Budibase alongside n8n. Budibase is quite new on the block but feels quite mature. Just like n8n is receives frequent upgrades and they even document the process of connecting n8n and Budibase on their website.

Windmill on the other hand comes with its own app builder. It gets the job done, but this app builder is fairly limited compared to Budibase. Just like with the workflow building part, it requires users quite often to write their own CSS code. So personally, I find the app builder more limiting than the n8n + Budibase combination, but it performs quite well - even large datasets render nicely for me. Plus, it is very simple to access data from the existing Windmill scripts and workflows.

Hosting

While n8n isn't stricly open-source, its source code can still be viewed (and modified). Both n8n and Windmill can be self-hosted using a simple container setup (I shared an example n8n setup earlier over here).

Summary

The "best" solution here depends on the use case. n8n looks great and will remain my standard workflow tool, but Windmill is a great addition to the low code tool belt and I wouldn't want to miss it.