I shipped a daemon this week. Not a service, not a platform, a daemon: one binary that watches a directory, and when a file lands it moves it somewhere sensible based on its name. My downloads folder had become a midden, and rather than tidy it I automated the tidying, which is the engineer's version of cleaning.
Go is almost unfairly good at this. The whole thing is a fsnotify watcher, a select loop, and a handful of rules. No event framework, no dependency tree to audit, no runtime to install on the target. The standard library does the file handling, fsnotify does the inotify dance, and the concurrency is a goroutine and a channel because that's just how you wait for things in Go.
for {
select {
case ev := <-watcher.Events:
if ev.Op&fsnotify.Create == fsnotify.Create {
sort(ev.Name)
}
case err := <-watcher.Errors:
log.Println("watch error:", err)
}
}
The bit that makes it a joy to deploy is go build. One static binary, no libc to match, no interpreter on the box. I scp it to the home server, drop a systemd unit beside it, and it runs. No pip install going sideways at three in the morning, no version of anything to keep in step. That's the entire pitch for Go on small jobs like this, and it holds up every time.
It's about forty lines. It will run for years and I will forget it exists, which is exactly what I want from it.