Module 2 · Lesson 5 of 25

Just-enough Lua for KumoMTA

Part of KumoMTA: High-Volume Sending Engine — Installation, Lua Primer & systemd.

KumoMTA's config is Lua. You don't need to be a Lua dev — you need to read it and copy patterns.

The five constructs you'll see everywhere:

1. Module + function:

local kumo = require 'kumo'

kumo.on('init', function()
  kumo.start_esmtp_listener { listen = '0.0.0.0:25' }
end)

2. Tables (KumoMTA's "config blocks"):

kumo.on('init', function()
  kumo.define_spool { name='data', path='/var/spool/kumomta/data', kind='RocksDB' }
  kumo.define_spool { name='meta', path='/var/spool/kumomta/meta', kind='RocksDB' }
end)

3. Event hooks:

kumo.on('smtp_server_message_received', function(msg)
  -- inspect/modify the message
  msg:set_meta('tenant', 'acme-marketing')
end)

4. Pattern-based throttles:

kumo.on('get_queue_config', function(domain, tenant, campaign)
  return kumo.make_queue_config {
    max_connection_rate = '10/s',
    max_message_rate = '500/s',
  }
end)

5. Pattern matching for destination tuning:

if domain == 'gmail.com' then ...
elseif domain:match('%.protection%.outlook%.com$') then ...
end

That's 90% of what you'll write. The docs at docs.kumomta.com mirror these patterns relentlessly.

Sign in to keep track of what you have read.

Pulse · self-hosted sending

Own the infrastructure your pipeline depends on.

One install script on your own server. Pulse sets up the MTA, mailboxes, certificates and dashboard; you add domains and start sending.

# on a fresh Ubuntu server
$ cd pulse && sudo ./install.sh
→ docker compose up · kumomta · stalwart · caddy
→ dashboard ready on https://pulse.yourdomain.com
$

Also from us:Beat — monitoring that tells you the fixConsulting — $65/hr, no retainer