Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Choosing Linux or Windows

Ductus runs on both, from one code base and one project format: the same interfaces, the same YAML, the same TypeScript, the same database. A project moves from one to the other with only its file paths changed. Where they differ is in how each operating system starts, stops and upgrades a service, how it logs in to other Windows systems, and how much the build has been exercised. This page lists every difference we know of, each with the measurement or nuance behind it.

Our recommendation: Linux, unless the engine must log in to SQL Server with Windows accounts, or your team runs only Windows servers and would rather not keep one Linux server. Both are supported, and both behave the same in everything not in this table.

The differences

Linux (recommended)WindowsWhat it means for you
Install.deb or .rpm (Ubuntu 22.04+, Debian 12+, RHEL/Rocky/Alma 9), or the .tar.gzThe MSI, or the .zipSame engine and project files on both; a project moves between them, paths aside.
Runs asA systemd service, user ductus, sandboxed by the unit: it can write only /var/lib/ductus (the unit)A Windows service, NT SERVICE\Ductus by default; a gMSA, or a password account that needs one command after each upgrade (nuance)On Windows the account is what SQL Server and file shares see; on both, the engine can touch only what you give it (Windows).
Restart, crashsystemd keeps the listening sockets: 0 connections refused; senders wait 0.2–0.3 s for a restart, ~5 s after a crash (measured)Restart-Service: 0 refused, a few connections reset, longest wait ~1.1 s (measured)Senders resend on their own in both cases.
UpgradeThe handover: 0 refused, sending paused ~35 ms (1 interface) to ~0.6 s (1,001 interfaces), receiving never stops; a broken new version leaves the old one running (measured, broken version)The MSI: the engine is down 3.1–3.5 s (a few refused, nothing lost); where Group Policy turns Restart Manager off, msiexec first waits 100–160 s while the engine keeps running (measured, why the wait). Zero-downtime Windows upgrades are planned for v1.0Linux upgrades need no quiet moment; on Windows, pick one.
Deploy project changessystemctl reload ductus: the same handover (nuance)Restart-Service Ductus: the same short gap as a restartAs above.
SQL Server Windows loginsNTLM only, with a warning; no Kerberos before v1.0 (nuance)Integrated: Kerberos, with NTLM as Windows falls back; as a gMSA or a named account (nuance)A DBA who allows only Windows logins: prefer Windows.
An outgoing connection refusedKnown at onceTakes ~1 s (Windows tries again before it says so); localhost may be ::1 first (measured)Write 127.0.0.1, not localhost; keep an MLLP destination's timeout_ms above ~2 s on Windows.
LogsThe journal: journalctl -u ductusFiles in C:\ProgramData\Ductus\logs (14 days), and the Event Log for what operations watch: IDs 1000–1100, each kind at most once a minute (nuance)SCOM, Splunk and Event Viewer read the Event Log on Windows; the journal feeds the same tools on Linux.
CertificatesThe system's store; a private CA (for LDAP, Postgres, a partner) usually needs ca: (nuance)The machine's store; the domain's CA is usually there already (nuance)Name a private CA per connection on both; it always works.
Paths/etc/ductus, /var/lib/ductusC:\ProgramData\Ductus; a path without a drive is read from the project's drive; single-quote backslashes in YAML (nuance)ductus validate warns about Linux paths on Windows.
ContainersThe Docker image (a development build, not published before v1.0)NoneKubernetes is planned for v1.2.
Tested on every pushEvery test, all the end-to-end demos, the packages under real systemd (255 and 252), the web UI in a browserEvery Rust test except those needing Linux helpers (a TLS Postgres, OpenLDAP, sending from 127.0.0.2), SQL Server Express with Windows logins, the MSI (install, service, Event Log, upgrades, uninstall) (the workflow)Linux has more mileage. Neither has been tested against a real Active Directory yet: the first pilot with a domain does that.

Plan for these on either

  • Reboots (patch nights): a reboot is a stop and a start. The engine stops cleanly (Windows gives the service its preshutdown time, 90 s; systemd sends SIGTERM and waits 45 s), and it starts with the server. While the server is down, senders are refused and retry, as with any engine; systemd's socket store doesn't survive a reboot. Reboot in a quiet moment, or move the interfaces to another engine first (several engines).
  • Antivirus and endpoint protection that scans every file write slows the database far more than the engine: the engine writes only its logs; Postgres writes every message. Ask for the usual exclusions for Postgres's data and WAL folders on its server (your DBA will know them), and for the engine's project folder if a scan on read slows its start.
  • Postgres is the same on both: the DBA's server, on Linux or Windows, whatever the engine runs on (PostgreSQL).
  • Time zone: cron schedules, quiet hours and monitor: times are in the server's local time on both. A server (or container) that runs on UTC reads "06:00-22:00" as UTC.

How the two are kept the same

One code base and one project format; the whole Rust test suite runs on both on every push; Windows-only behaviour is written down as a nuance the day it's found (the Windows section, and the Windows rows in other sections). When a difference is fixed (a resident launcher for zero-downtime Windows upgrades is planned for v1.0, a Kerberos keytab on Linux too), its row here changes in the same commit.