Show network · sACN ↔ Art-Net
DMX Gateway
sACN ↔ Art-Net conversion in both directions, built to run unattended in a show network.
Both directions run at the same time, on interfaces you pick yourself. The forwarding path adds a few microseconds. The native Mac app and the 1.6 MB Docker server run the same core, so what you tested on a laptop behaves the same in the rack. The Mac app is on the App Store; the server is licensed here, one key for five machines.
One-time payments · updates included · no telemetry
Screens
The Mac app, and the server's status endpoint
Captured on a demo configuration: four endpoints on the loopback interface with a test signal from dmxgwd send, so every number is real traffic through the real forwarding path, on no network at all.
Mac app or Linux server
Which one do you need?
Both are a single payment with no subscription, and both run the same forwarding core. The difference is where the gateway lives.
macOS · App Store
Mac app
$12.99
For the gateway on your laptop at FOH or on a Mac mini beside the console. Apple handles payment and updates, there is no key and no account, and it keeps working offline.
Linux · Docker
DMX Gateway Server
14 990 Ft
For the gateway that lives in the rack and runs unattended: a rack PC, a Proxmox host or an arm64 board. Sold here with a licence key for up to five machines at once, seats freed by you on the manage page.
- Compared
- Mac app
- Linux server
- Runs on
- Mac appAn Apple Silicon Mac, macOS 14 or later
- Linux serverAny Linux host with Docker, x86_64 or arm64: a rack PC, a Proxmox VM, a Raspberry Pi 4 or 5 on a 64-bit OS
- Interface
- Mac appSix panes: monitor, routes, interfaces, settings, benchmark, log. Menu bar status
- Linux serverHeadless: a TOML file or environment variables, JSON status and health endpoints, structured logs
- Licence
- Mac appThrough Apple. No key, no account, works offline
- Linux serverOne key for up to five machines, activated online once, then offline for up to 30 days per token
- Core
- Mac appThe same Rust core
- Linux serverThe same Rust core
- Measured
- Mac app512 universes, zero loss, 6 µs median
- Linux server256 universes, zero loss, 3 µs median, in a container
Prices are final: the Mac app in USD through Apple, the server in HUF here. The seller is VAT-exempt under the Hungarian small business scheme, so no VAT is added to the server licence. Both are perpetual licences, paid once.
The server
Built to sit in a rack and be forgotten
The headless daemon is the same Rust core as the Mac app without the UI. You configure it once, with a file or with environment variables, watch it through its status endpoint, and leave it running through the tour.
01
Both directions, interfaces by name
sACN → Art-Net and Art-Net → sACN are just routes. Every socket is pinned to an interface you name; the gateway never falls back to the default route, which is how a two-network rig usually goes wrong.
02
Past Linux's 20-group limit
Linux allows 20 multicast memberships per socket by default and many sACN tools lose the 21st universe without an error. The server shards its groups across as many sockets as it needs, so 40 or 256 universes need no kernel setting.
03
A health endpoint for the rack
/health answers 200 only while every endpoint runs, /stats serves the same figures the Mac app shows as JSON, /log the event stream. The image's own HEALTHCHECK uses it, and SIGHUP reloads the config without dropping traffic.
04
Licensed for the road
The key is activated once online and the server keeps a signed 30-day token that renews in the background every 24 hours. Offline is fine while the token is valid, and a running gateway is never stopped or degraded because of licensing: a problem is logged and shown in /health, enforced at the next start.
05
Five machines, moved by you
One key runs on up to five machines at once. Each shows up by name on the manage page, where you free a seat yourself when a rack PC is retired, no email needed.
06
Small and unprivileged
A 1.6 MB image on scratch: the statically linked binary and nothing else, no shell, no package manager, running as an unprivileged user with every capability dropped. The compose file ships read-only with a tmpfs.
Design
Built around the faults you meet on a job
Gateways usually fail quietly. DMX Gateway is built around the faults I have run into on site: the wrong network card, a switch that drops multicast, a node that never joins its group, a second console that starts sending while the first one is still live.
You name the interface
Every socket is bound to an interface you choose, separately for input and output. Multicast groups are joined on that interface, and packets can be checked against the interface they arrived on. A machine on two lighting networks will not leak one into the other.
Nodes that ignore IGMP
Plenty of cheaper nodes and LED bars ignore IGMP and never see multicast, so they stay dark while the console shows output. Point an sACN output at broadcast and the same stream reaches them.
Priority, not merging
Several sACN sources are arbitrated by priority: the highest live source owns a universe, ties stay with whoever had it first, so two consoles at the default priority cannot make the rig strobe. A source silent for 2.5 seconds hands over to the best standby at once.
Counters on every route
Each route shows its own live packet rate. Malformed packets, out-of-order frames, loops and lower-priority sources are counted separately, so you can see where a fault is. The gateway drops and counts its own packets coming back, so a mirrored configuration shows up as a number, not a broadcast storm.
Recovery without a restart
If an interface disappears, comes back or returns with a new address, only its own endpoint goes into fault. That endpoint retries every two seconds and joins its groups again while the other routes keep running.
Benchmark
Measured performance
These tables come from the benchmark built into the app. It sends real frames through the kernel's sockets, reads a timestamp back out of the DMX payload and raises the universe count until something gives. You can run the same test on your own machine.
Apple Silicon Mac, 18 cores
| Universes | Packets/s | Mbps | Loss | p50 | p99 | CPU |
|---|---|---|---|---|---|---|
| 64 | 2 817 | 11.9 | 0.000% | 6 µs | 25 µs | 7% |
| 256 | 11 267 | 47.8 | 0.000% | 6 µs | 12 µs | 29% |
| 512 | 22 524 | 95.5 | 0.000% | 6 µs | 25 µs | 82% |
Linux container, host networking
| Universes | Packets/s | Mbps | Loss | p50 | p99 | CPU |
|---|---|---|---|---|---|---|
| 32 | 1 408 | 6.0 | 0.000% | 3 µs | 49 µs | 4% |
| 128 | 5 640 | 23.9 | 0.000% | 2 µs | 25 µs | 8% |
| 256 | 11 270 | 47.8 | 0.000% | 3 µs | 25 µs | 13% |
p50 and p99 are the time spent inside the forwarding path. Loss is counted from gaps in a packet index carried in the payload, so a frame still in flight at the end of a measurement window is not counted as lost. Measured over loopback, which tests the machine and leaves the cabling out. A 30-second soak at 64 universes and 44 fps forwarded every frame with 8.1 MB of resident memory and no growth, while a parallel flood of 1.1 million malformed packets was counted and discarded.
Mac app
Presets for the usual jobs
The presets already handle the offset between sACN, which counts universes from one, and Art-Net, which counts from zero. That offset is the usual reason a rig ends up one universe out. Everything a preset creates shows up on the routes page, where you can read and change it. The server writes the same offset into its config file, explicitly, for the same reason.
grandMA3 → Resolume
sACN multicast in one network, Art-Net broadcast out the other, with the universe offset already right.
grandMA3 ↔ Resolume
Both directions at once, on separate interfaces. What most shows actually want.
sACN multicast → broadcast
For nodes and LED bars that ignore IGMP and never see multicast at all.
sACN → Art-Net node
Unicast straight to the addresses you list, so a busy network stays quiet.
Server requirements
What the rack needs
- Host
- Linux with Docker Engine and the compose plugin, x86_64 or arm64. The image is built for linux/amd64 and linux/arm64.
- Networking
- Host networking (network_mode: host) is required: a bridged container cannot join a multicast group on a host interface. Both protocol ports are above 1024, so nothing runs as root.
- State
- A persistent /data volume for this machine's id and the licence token. A fresh /data counts as a new machine and takes a new seat.
- Internet
- Once, at the first start, to activate the key. After that the server also starts offline while its token is valid, and renews it whenever the site is reachable.
- Networks
- sACN (ANSI E1.31) multicast, broadcast or unicast on one side, Art-Net 4 broadcast or unicast on the other, each on the interface you choose.
Install
Running in five steps
The package you download after payment holds the image for both architectures, a compose file and a README with these steps written out.
- 01
tar xzf dmx-gateway-server.tar.gz && cd dmx-gateway-serverUnpack the download from your order page.
- 02
docker load -i dmx-gateway-$(uname -m).tarLoad the image for your architecture.
- 03
DMXGW_LICENSE_KEY: "RG-DMXG-XXXX-XXXX-XXXX"Put your key into compose.yaml. DMXGW_MACHINE_NAME names this machine on the manage page.
- 04
docker run --rm --network host dmx-gateway:1.0.0 ifacesList the interfaces, then write them into gateway.toml with your universes and the offset.
- 05
docker compose up -d && docker compose logs -fStart it. The first start activates the key and the log shows every route with its packet rate.
Check the licence any time with docker compose exec dmx-gateway /dmxgwd license status. Free this machine's seat locally with docker compose run --rm dmx-gateway license deactivate, or from the manage page. The token format and the API are documented on the licence page.
Questions
Licence, offline, updates, refunds
- Mac app or server?
- If the gateway sits on your laptop at FOH, the Mac app: no key, Apple handles payment and updates. If it has to live in a rack, on a Proxmox host or on a small arm64 box and run unattended, the server. Both run the same core, so what you tested on the laptop behaves the same in the rack.
- How does the licence behave?
- One key, up to five machines at once. Each machine activates once online and then holds a signed 30-day token, renewed every 24 hours in the background. Deactivating a machine on the manage page frees its seat immediately; the machine keeps running and learns about it at its next renewal.
- What if the venue has no internet?
- The server starts from its cached token and runs for as long as the token is valid, up to 30 days from the last renewal. A running gateway is never stopped because of licensing, whatever happens to the token.
- Updates?
- The key is valid for the version you bought and its updates. New packages appear on your order page and in the mail; the key does not change.
- Refunds and support
- Digital goods delivered immediately, so the EU withdrawal right ends with delivery, which you consent to at checkout. If the product does not do what this page says and I cannot fix it in a reasonable time, you get a full refund. Support is email to me, the developer; send the log and the cause is usually in it.
- Does it send anything home?
- No telemetry and no analytics. The only network traffic is the lighting data on the interfaces you configure, plus the licence activation and renewal of the server version.
Support
Write to gergo@riegergeri.com. If something went wrong during a show, use the Reveal File button on the Mac app's log page, or send the server's log and the output of its /health endpoint. The cause is usually in there.
Privacy
The app collects no data and sends nothing outside your lighting network. The server's only outside call is the licence activation and renewal. Details are in the privacy policy.
Other products
- CrewCompassevent and tour management for production crews →
- Cue Monitora cue countdown on show timecode →
- SWCTRLa switch console for show networks →
- TourTaglabels for touring gear, in exact millimetres →
- HomeVaultan offline-first inventory for iPhone and iPad →
- ROGGERa free Resolume remote for the ROG Ally X →