Fairwinds | Blog

How We Deployed, Maintained, and Migrated Production n8n on EKS

Written by Husne Ozmen | Sep 23, 2026, 9:01:24 PM

n8n is easy to try and harder to run under production traffic. A single container with SQLite works great for a quick demo. Production is a different story entirely. You need workers, webhook processors, PostgreSQL, Redis, object storage, external secrets, ingress routing, and an upgrade plan that preserves workflow history.

Engineering teams rely on n8n to connect internal systems, process webhooks, and automate critical business data pipelines. It is also showing up in AI workloads, including self-hosted agents and RAG pipelines. Those workloads can put more pressure on workers, secrets management, and state handling.

We deployed n8n on Amazon EKS, ran it under real traffic, and later moved from a community Helm chart to n8n’s official Helm chart. The platform stayed in place, and we kept the database, queue, object storage, IAM role, and secrets intact through the cutover.

Why We Started With the Community Chart

The community chart got us to production. It supported queue mode, additional ingress configuration, and StatefulSet-based main pods, which matched our architectural requirements at the time.

We ran it for about a year. Over time, maintaining unsupported features and local patches became harder to justify. We compared the available options and decided to move to the official chart, where ongoing maintenance and active community support gave us a clearer path for future upgrades.

How We Ran n8n

We ran n8n in queue mode on EKS. In queue mode, the main instance manages workflow information and triggers, while worker instances execute jobs from the Redis queue. Dedicated webhook processors handled production webhook traffic separately. We split ingress by traffic type. Public webhooks ran behind an internet-facing load balancer, while internal webhooks used a private hostname.

That separation fit our traffic patterns. Workers handled workflow execution. PostgreSQL stored workflow and execution data, Redis handled queued jobs, and S3 stored binary files.

Because licensing multi-replica main pods is an Enterprise capability, we needed a secure, consistent way to handle shared application configuration and encryption key secrets across pods. We stored those secrets in AWS Secrets Manager and synced them into Kubernetes using External Secrets Operator (ESO). This synchronized application credentials, API keys, and environment variables into Kubernetes Secrets.

What Changed With the Official Chart

The community chart ran the main pod as a StatefulSet with one persistent volume per replica. Workers and webhook processors already ran as Deployments. That StatefulSet configuration avoided multi-attach issues on AWS gp3 ReadWriteOnce (RWO) EBS volumes when running more than one main pod.

In our configuration, the official chart used a different workload model, with main running as a Deployment and persistence relying on a single shared PVC. Our gp3 volume could not attach to multiple main pods across nodes, so an in-place Helm upgrade did not fit the deployment. We treated the migration as a full cutover instead.

The shared persistence requirement was our main design decision. We checked what was stored on disk before carrying it forward:

  • PostgreSQL held workflow and execution data.
  • Redis held queued jobs.
  • S3 held files.
  • AWS Secrets Manager held the encryption key and application secrets.

We found nothing on the main pod volume that needed to persist. With PostgreSQL, Redis, S3, and Secrets Manager holding the required application state, a replacement main pod could start and reconnect without relying on a pod-specific disk. We disabled main persistence entirely for the official chart deployment.

Moving Traffic Safely

The platform stayed in place: we kept the database, object storage, IAM role, and secrets through the cutover. Everything else was recreated from the new chart values.

Before the production migration, we:

  • Tested rollback in a non-prod environment
  • Took a database snapshot
  • Saved secrets to a secondary location
  • Did not change the n8n image version. A version bump could trigger a database migration, and we wanted to keep the database out of the cutover story

We tested in non-production first with a restored database snapshot: pods healthy, known workflows completing, required endpoints reachable. We verified rollback there before touching live traffic.

The Helm release changed. PostgreSQL, Redis, S3, IAM, and secrets stayed.

For a public example of how we structure official-chart values for external Postgres/Redis, queue mode + HPA, resources, ingress/webhooks, optional task runners, see:

github.com/husne-fairwinds/n8n-sample

Need Help Running Production Workloads on EKS?

Running production applications on EKS means managing state, secrets, ingress, upgrades, and the operational work around them. Fairwinds helps teams build and operate production-ready EKS platforms, including Kubernetes add-ons, identity and access controls, GitOps workflows, and application onboarding. Schedule a call with the Fairwinds team.