Skip to content
B
All projects
Flagship project Odoo Developer (lead) Jul 15, 2024

Odoo ERP + n8n + Twilio automation platform

Architected scalable Odoo modules across Accounting, Inventory, HR and CRM, then wired them into n8n + Twilio pipelines that removed 40% of manual workflows.

Manual workflows
−40%
Postgres / AWS perf
+25%
Modules shipped
4 domains
Channels integrated
SMS · Voice · WhatsApp

Stack

OdooPythonPostgreSQLn8nTwilioAWSTerraform

Problem

The client ran on spreadsheets, scattered SaaS tools, and one over-worked operations team. Same data lived in three places. Invoicing waited on whoever opened the right email first. Reports were copy-pasted into PowerPoint on Sunday nights.

They had also tried Odoo before — it was installed, but barely used. Modules were either misconfigured for their workflow or so heavy with custom fields that nobody trusted the data.

Constraints

  • Production ERP for a real business (not a sandbox)
  • PostgreSQL with millions of rows already in legacy tables
  • Strict cutover — finance had to keep closing the books every month
  • Budget for one engineer leading, plus a junior pairing for knowledge transfer

My role

Senior Odoo Developer leading the work at ETTA Solutions (Jan 2024 – Jul 2024). I owned module architecture, database performance, AWS deployment, and the automation layer end to end. I also ran knowledge-transfer sessions for the internal team.

Architecture

Three layers, deliberately decoupled so each could be replaced without touching the others.

        ┌───────────────────────────────────────────────┐
        │                 Odoo (Python)                 │
        │  Accounting · Inventory · HR · CRM modules    │
        └──────────────┬────────────────────────────────┘
                       │ REST + XML-RPC
        ┌──────────────▼────────────────────────────────┐
        │                  n8n workflows                │
        │  CRM ↔ marketing · ERP ↔ comms · ETL jobs    │
        └──────────────┬────────────────────────────────┘

        ┌──────────────▼─────────────┐    ┌─────────────┐
        │   Twilio (SMS / WA / Voice)│    │    AWS S3   │
        └────────────────────────────┘    └─────────────┘

Infra was deployed on AWS via Terraform, behind an Nginx load balancer with autoscaling Odoo workers and a managed PostgreSQL instance.

Why n8n and not a SaaS automation tool

n8n self-hosts, has first-class HTTP + custom JS nodes, and lets us run private webhooks inside the same VPC as Odoo. For ERP data, "don't send our pricing to a third-party server" is a hard requirement.

Key decisions

1. Custom modules, but as thin as possible

Earlier attempts had over-customized core models. I kept each module focused:

  • acc_extensions — only the fields finance actually closes books with
  • inv_warehouses_local — regional warehouse rules and unit conversions
  • hr_local — payroll + leave with region-specific rules
  • crm_automation_bridge — the contract surface for n8n

The bridge module is the only place Odoo talks to the automation layer. That meant changing automation logic never required redeploying Odoo.

2. Postgres tuning before scaling out

Before adding workers, I profiled the slow queries. Most of the pain came from a handful of unindexed foreign keys, plus a couple of reports doing N+1 joins through ir.translation.

-- Example: invoice listing was scanning 2.1M rows
CREATE INDEX CONCURRENTLY idx_account_move_partner_state
  ON account_move (partner_id, state)
  WHERE state IN ('draft', 'posted');

That single index, plus three more like it, cut p95 invoice list latency from ~1.4s to ~280ms. Only after that did we scale workers horizontally.

3. Terraform for everything, no console clicks

module "odoo_app" {
  source            = "./modules/ecs-service"
  name              = "odoo-prod"
  desired_count     = 3
  min_capacity      = 2
  max_capacity      = 8
  cpu_target        = 60
  task_definition   = data.template_file.odoo_task.rendered
  subnets           = module.vpc.private_subnets
}

Disaster recovery went from "we hope" to "we restore in 22 minutes" because the entire environment is in code.

4. n8n + Twilio as the customer-facing layer

Every customer-facing event — order confirmed, invoice due, delivery dispatched — flowed through one n8n workflow set. Twilio handled the multi-channel delivery (SMS for cheap, WhatsApp for rich content, voice for high-value reminders).

The team no longer copy-pasted phone numbers into anything.

Results

  • −40% time spent on manual processes (measured against the team's own weekly time logs)
  • +25% performance gain across Odoo workloads after the Postgres and Terraform/AWS work
  • 4 module domains stabilized: Accounting, Inventory, HR, CRM
  • Multi-channel comms (SMS, voice, WhatsApp) running inside ERP workflows, not bolted on
  • Two junior engineers fully ramped through paired implementation and weekly sessions

What I would do differently

  • Set up structured logging (OpenSearch) on day one — debugging multi-system flows without it was painful for the first month
  • Introduce a feature-flag layer for Odoo modules earlier — staging vs production drift was the most expensive bug class
  • Treat n8n workflows as code from the start — versioned exports + a CI check, not the in-app editor as source of truth

Stack at a glance

  • Backend / ERP: Odoo (Python), PostgreSQL
  • Automation: n8n (self-hosted), Twilio
  • Infra: AWS (ECS, RDS, S3), Nginx, Terraform, GitHub Actions
  • Storage: S3 for documents, RDS Postgres for transactional data

Want a similar setup?

This is the engagement I take on most often as a freelancer — Odoo + automation + sane infra. See services or get in touch.

Next case study

SMSAI — AI-powered SMS services on AWS

An AI application that delivers LLM-powered services over plain SMS — built with React, FastAPI and DynamoDB on AWS, designed for low-bandwidth markets.