<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: 40</title>
    <description>The latest articles on DEV Community by 40 (@40_c9e9d448914c1f95a55f68).</description>
    <link>https://dev.to/40_c9e9d448914c1f95a55f68</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4200659%2Fa2869dfd-f1cb-4bb1-9205-bc944a1ee24e.png</url>
      <title>DEV Community: 40</title>
      <link>https://dev.to/40_c9e9d448914c1f95a55f68</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/40_c9e9d448914c1f95a55f68"/>
    <language>en</language>
    <item>
      <title>What your cron schedule does on the two DST nights, tested</title>
      <dc:creator>40</dc:creator>
      <pubDate>Sat, 24 Oct 2026 11:16:05 +0000</pubDate>
      <link>https://dev.to/40_c9e9d448914c1f95a55f68/what-your-cron-schedule-does-on-the-two-dst-nights-tested-2h93</link>
      <guid>https://dev.to/40_c9e9d448914c1f95a55f68/what-your-cron-schedule-does-on-the-two-dst-nights-tested-2h93</guid>
      <description>&lt;p&gt;Disclosure: I maintain &lt;a href="https://cronbell.wavez.lol/?src=devto" rel="noopener noreferrer"&gt;Cronbell&lt;/a&gt;, a heartbeat monitor that evaluates cron schedules in a timezone. The behaviour below is general; the outputs are from my own implementation, so check how your scheduler treats these cases.&lt;/p&gt;

&lt;p&gt;Two nights a year, local wall-clock time lies to schedulers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spring forward: a time that does not exist.&lt;/strong&gt; In &lt;code&gt;Europe/Amsterdam&lt;/code&gt; the clocks jump from 02:00 to 03:00 on 2027-03-28, so &lt;code&gt;30 2 * * *&lt;/code&gt; has no 02:30 that day. In my tests the next run after 2027-03-27 is 2027-03-29 02:30 local (00:30 UTC). The same happens in &lt;code&gt;America/New_York&lt;/code&gt; on 2027-03-14. Some cron daemons run skipped jobs right after the jump instead, others skip them; this is worth looking up for yours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fall back: a time that happens twice.&lt;/strong&gt; On 2026-10-25 Amsterdam repeats 02:00-03:00. &lt;code&gt;30 2 * * *&lt;/code&gt; could fire at 00:30 UTC (CEST) or at 01:30 UTC (CET). I treat the first as the real one and skip the repeat, so the job runs once. That gives a related quirk: &lt;code&gt;0 * * * *&lt;/code&gt; is evaluated once for the repeated 02:00 hour, so after 02:30 CEST the next expected run is 03:00 CET (02:00 UTC), not an extra one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consequences for monitoring&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fixed-interval monitors ("expect a ping every 24h") drift against a local-time cron for two days a year: either false alarms or a late one.&lt;/li&gt;
&lt;li&gt;Evaluate the cron expression in the job's own timezone, and set a grace period of at least an hour for jobs near 02:00-03:00 local.&lt;/li&gt;
&lt;li&gt;Safest of all: schedule jobs at times that are never skipped or repeated (for example 04:00 local), or run the host in UTC.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I found a real bug while writing this: my own implementation returned the later of the two occurrences on the fall-back night, which pushed one day's deadline back an hour. It is fixed and now has a regression test for these cases. If you maintain a scheduler, test your overlap case.&lt;/p&gt;

&lt;p&gt;Related copy-paste heartbeat examples for crontab, systemd timers and Kubernetes (including &lt;code&gt;timeZone&lt;/code&gt;): &lt;a href="https://github.com/jinqo/cron-heartbeat-snippets" rel="noopener noreferrer"&gt;https://github.com/jinqo/cron-heartbeat-snippets&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How does your cron or systemd timer behave on the repeated hour? I'd like to compare notes.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>sysadmin</category>
      <category>timezones</category>
    </item>
    <item>
      <title>Five reasons your cron job failed silently (and how to catch each one)</title>
      <dc:creator>40</dc:creator>
      <pubDate>Fri, 23 Oct 2026 21:52:36 +0000</pubDate>
      <link>https://dev.to/40_c9e9d448914c1f95a55f68/five-reasons-your-cron-job-failed-silently-and-how-to-catch-each-one-eoe</link>
      <guid>https://dev.to/40_c9e9d448914c1f95a55f68/five-reasons-your-cron-job-failed-silently-and-how-to-catch-each-one-eoe</guid>
      <description>&lt;p&gt;Disclosure: I maintain &lt;a href="https://cronbell.wavez.lol/?src=devto" rel="noopener noreferrer"&gt;Cronbell&lt;/a&gt;, a small heartbeat monitor. Everything below works with any heartbeat service, including self-hosted Healthchecks.io.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;MAILTO&lt;/code&gt; is silent when nothing runs.&lt;/strong&gt; It mails only when a job prints output and needs a working mail setup. If crond is stopped, the host is down or the crontab was replaced, you hear nothing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;;&lt;/code&gt; instead of &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;.&lt;/strong&gt; &lt;code&gt;backup.sh ; curl $PING&lt;/code&gt; pings even when the backup failed. Use &lt;code&gt;backup.sh &amp;amp;&amp;amp; curl $PING&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output sent to &lt;code&gt;/dev/null&lt;/code&gt;.&lt;/strong&gt; The failure happened and you discarded the evidence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DST and timezones.&lt;/strong&gt; &lt;code&gt;30 2 * * *&lt;/code&gt; does not exist on the spring DST change in many zones and occurs twice in autumn. A fixed 24-hour interval drifts against it; a monitor that evaluates the cron expression in your IANA timezone does not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grace shorter than the runtime.&lt;/strong&gt; A 40-minute backup with a 15-minute grace alerts every night until you learn to ignore it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The fix is a heartbeat: the job requests a URL on success, and the service alerts when the request is late. Send &lt;code&gt;/start&lt;/code&gt; first and &lt;code&gt;/fail&lt;/code&gt; on error if you want runtime and explicit failures.&lt;/p&gt;

&lt;p&gt;I collected tested, service-agnostic examples (crontab, systemd timers, Kubernetes CronJob with &lt;code&gt;timeZone&lt;/code&gt;, restic, borg, a wrapper script that preserves exit codes) here: &lt;a href="https://github.com/jinqo/cron-heartbeat-snippets" rel="noopener noreferrer"&gt;https://github.com/jinqo/cron-heartbeat-snippets&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which of these has actually bitten you, and how did you find out?&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>sysadmin</category>
      <category>monitoring</category>
    </item>
  </channel>
</rss>
