Reliability and resources

Model startup order and readiness

Express real dependencies and application readiness instead of adding arbitrary sleep commands.

8 minute lesson

~~~

Ordering a service after the network target does not prove that a remote database or API is ready. network-online.target means the local network stack came up. Your database on another machine can still be rebooting, slow, or down.

That gap is where sleep hacks come from:

[Service]
ExecStartPre=/bin/sleep 15
ExecStart=/usr/bin/node /opt/demo-api/server.js

This works until the database takes sixteen seconds. Then it fails, someone bumps the sleep to thirty, and every deploy gets slower. The sleep encodes a guess, not a dependency.

Model what systemd can actually see

systemd can order units on the same machine. Use that for local dependencies:

[Unit]
Wants=network-online.target
After=network-online.target postgresql.service

If PostgreSQL runs on this host, After=postgresql.service is a real, checkable ordering. Use Requires= instead of Wants= only when your service is useless without the dependency and should fail with it.

For anything remote, the dependency is invisible to systemd. Let the application retry temporary remote failures with bounded backoff: try the connection, wait, try again, and give up with a clear error after a budget. Combined with the restart policy from the previous lesson, this recovers from slow dependencies without a single sleep.

Readiness is a separate claim

“Started” and “ready to serve” are different events. Type=notify closes that gap: the application calls sd_notify() with READY=1 only when it can really handle traffic, and units ordered After= it wait for that signal. Use it only when the application can report readiness — check its documentation before switching the type.

You can see how long a service took to reach ready:

systemd-analyze blame | head -5

Services with sleep hacks stand out immediately in that list.

Try it

Take one sleep-based startup workaround from a design you know. Replace it with either a real local dependency (After= a unit on the same host) or an application-level retry with backoff. Then write one sentence stating the boundary: which part systemd guarantees, and which part the application handles.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →