To add a time limit to a systemd service, use the TimeoutSec= directive in the [Service] section of the service file. This sets the maximum time systemd will wait for the service to start, stop, or complete its execution.

  • For startup time limits: Use TimeoutStartSec= to limit how long systemd waits for the service to start. Example: TimeoutStartSec=300 sets a 5-minute limit.

  • For runtime limits: Starting with systemd 229, use RuntimeMaxSec= to set a maximum duration for the service’s active state. Example: RuntimeMaxSec=1h stops the service after one hour.

  • For stopping time limits: Use TimeoutStopSec= to set how long systemd waits for the service to stop gracefully. Example: TimeoutStopSec=60 allows 60 seconds.

Note: Avoid setting TimeoutSec=infinity as it may block system shutdown indefinitely. Use a large but finite value instead.

To apply changes:

  1. Create an override file: sudo systemctl edit <service-name>

  2. Add the timeout settings under [Service].

  3. Reload systemd: sudo systemctl daemon-reload

  4. Restart the service: sudo systemctl restart <service-name>

For system-wide defaults, edit /etc/systemd/system.conf and adjust:

  • DefaultTimeoutStartSec=

  • DefaultTimeoutStopSec=

My systemd service kept timing out because of how long it would take to boot up also, so this fixed it for me:

  1. Edit your systemd file:

    • For modern versions of systemd: Run systemctl edit --full node.service (replace "node" with your service name).
      • This will create a system file at /etc/systemd/system/node.service.d/ that will override the system file at /usr/lib/systemd/system/node.service. This is the proper way to configure your system files. More information about how to use systemctl edit is here.
    • Directly editing system file: The system file for me is at /usr/lib/systemd/system/node.service. Replace "node" with your application name. However, it is not safe to directly edit files in /usr/lib/systemd/ (See comments)
  2. Use TimeoutStartSec, TimeoutStopSec or TimeoutSec (more info here) to specify how long the timeout should be for starting & stopping the process. Afterwards, this is how my systemd file looked:

    [Unit]
    Description=MyProject
    Documentation=man:node(1)
    After=rc-local.service
    
    [Service]
    WorkingDirectory=/home/myproject/GUIServer/Server/
    Environment="NODE_PATH=/usr/lib/node_modules"
    ExecStart=-/usr/bin/node Index.js
    Type=simple
    Restart=always
    KillMode=process
    TimeoutSec=900
    
    [Install]
    WantedBy=multi-user.target
    
    • You can also view the current Timeout status by running any of these (but you'll need to edit your service to make changes! See step 1). Confusingly, the associated properties have a "U" in their name for microseconds. See this Github issue for more information:
      • systemctl show node.service -p TimeoutStartUSec
      • systemctl show node.service -p TimeoutStopUSec
      • systemctl show node.service -p TimeoutUSec
  3. Next you'll need to reload the systemd with systemctl reload node.service

  4. Now try to start your service with systemctl start node.service

  5. If that didn't work, try to reboot systemctl with systemctl reboot

  6. If that didn't work, try using the --no-block option for systemctl like so: systemctl --no-block start node.service. This option is described here: "Do not synchronously wait for the requested operation to finish. If this is not specified, the job will be verified, enqueued and systemctl will wait until the unit's start-up is completed. By passing this argument, it is only verified and enqueued."

    • There is also the option to use systemctl mask instead of systemctl start. For more info see here.

Updates from Comments:

  • TimeoutSec=infinity: Instead of using "infinity" here, put a large amount of time instead, like TimeoutSec=900 (15 min). If the application takes "forever" to exit, then it's possible that it will block a reboot indefinitely. Credit @Alexis Wilke and @JCCyC
  • Instead of editing /usr/lib/systemd/system, try systemctl edit instead or edit /etc/systemd/system to override them instead. You should never edit service files in /usr/lib/. Credit @ryeager and @0xC0000022L

** Update from systemd source docs ** When specified "infinity" as a value to any of these timeout params, the timeout logic is disabled.

JobTimeoutSec=, JobRunningTimeoutSec=,TimeoutStartSec=,  TimeoutAbortSec=

The default is "infinity" (job timeouts disabled), except for device units where JobRunningTimeoutSec= defaults to DefaultTimeoutStartSec=.

Reference: enter link description here

Similarly this logic applies to service level and laid out clearly in URL below. Reference: enter link description here

Answer from Katie on Stack Exchange
Top answer
1 of 4
144

My systemd service kept timing out because of how long it would take to boot up also, so this fixed it for me:

  1. Edit your systemd file:

    • For modern versions of systemd: Run systemctl edit --full node.service (replace "node" with your service name).
      • This will create a system file at /etc/systemd/system/node.service.d/ that will override the system file at /usr/lib/systemd/system/node.service. This is the proper way to configure your system files. More information about how to use systemctl edit is here.
    • Directly editing system file: The system file for me is at /usr/lib/systemd/system/node.service. Replace "node" with your application name. However, it is not safe to directly edit files in /usr/lib/systemd/ (See comments)
  2. Use TimeoutStartSec, TimeoutStopSec or TimeoutSec (more info here) to specify how long the timeout should be for starting & stopping the process. Afterwards, this is how my systemd file looked:

    [Unit]
    Description=MyProject
    Documentation=man:node(1)
    After=rc-local.service
    
    [Service]
    WorkingDirectory=/home/myproject/GUIServer/Server/
    Environment="NODE_PATH=/usr/lib/node_modules"
    ExecStart=-/usr/bin/node Index.js
    Type=simple
    Restart=always
    KillMode=process
    TimeoutSec=900
    
    [Install]
    WantedBy=multi-user.target
    
    • You can also view the current Timeout status by running any of these (but you'll need to edit your service to make changes! See step 1). Confusingly, the associated properties have a "U" in their name for microseconds. See this Github issue for more information:
      • systemctl show node.service -p TimeoutStartUSec
      • systemctl show node.service -p TimeoutStopUSec
      • systemctl show node.service -p TimeoutUSec
  3. Next you'll need to reload the systemd with systemctl reload node.service

  4. Now try to start your service with systemctl start node.service

  5. If that didn't work, try to reboot systemctl with systemctl reboot

  6. If that didn't work, try using the --no-block option for systemctl like so: systemctl --no-block start node.service. This option is described here: "Do not synchronously wait for the requested operation to finish. If this is not specified, the job will be verified, enqueued and systemctl will wait until the unit's start-up is completed. By passing this argument, it is only verified and enqueued."

    • There is also the option to use systemctl mask instead of systemctl start. For more info see here.

Updates from Comments:

  • TimeoutSec=infinity: Instead of using "infinity" here, put a large amount of time instead, like TimeoutSec=900 (15 min). If the application takes "forever" to exit, then it's possible that it will block a reboot indefinitely. Credit @Alexis Wilke and @JCCyC
  • Instead of editing /usr/lib/systemd/system, try systemctl edit instead or edit /etc/systemd/system to override them instead. You should never edit service files in /usr/lib/. Credit @ryeager and @0xC0000022L

** Update from systemd source docs ** When specified "infinity" as a value to any of these timeout params, the timeout logic is disabled.

JobTimeoutSec=, JobRunningTimeoutSec=,TimeoutStartSec=,  TimeoutAbortSec=

The default is "infinity" (job timeouts disabled), except for device units where JobRunningTimeoutSec= defaults to DefaultTimeoutStartSec=.

Reference: enter link description here

Similarly this logic applies to service level and laid out clearly in URL below. Reference: enter link description here

2 of 4
13

Running systemctl show SERVICE_NAME.service -p TimeoutStopUSec I could at least see the timeout set by systemd to my service.

I changed the script to a regular unit file one in order for it work properly.

🌐
GitHub
github.com › systemd › systemd › blob › main › man › sd_event_add_time.xml
systemd/man/sd_event_add_time.xml at main · systemd/systemd
<listitem><para>The passed relative time is outside of the allowed range for time values (i.e. the · specified value added to the current time is outside the 64 bit unsigned integer range).</para>
Author   systemd
🌐
Cody Bonney
codybonney.com › change-default-timeouts-starting-stopping-systemd-units
Change default timeouts for starting and stopping systemd units
December 1, 2016 - Uncomment them and change them to whatever you want the new timeouts to be. DefaultTimeoutStartSec=65s DefaultTimeoutStopSec=65s · You don't want to set these too low. Otherwise, systemd may not have enough time to safely start amd stop units (for example: properly mounting/unmounting filesystems).
🌐
Reddit
reddit.com › r/archlinux › systemd timeout question
r/archlinux on Reddit: Systemd Timeout Question
March 17, 2023 -

Hey all, I was reading up on the systemd timeout parameters in the system.conf file (/etc/systemd/system.conf) and was curious if anyone has any input as to problems that can arise if we set the #DefaultTimeoutStopSec=90s to something like 5 seconds rather than letting it stay at 90 seconds.

This is something I do from time to time on systems if I get an SDDM timeout when shutting down the PC and never have had a problem but wondered if it could cause an issue other than the journal not logging.

Top answer
1 of 3
4
This timer sets the max time after which systemd will SIGKILL services when a SIGTERM didn't succeed in time. This 90s default value is chosen very liberally, because systemd has to cover any kind of system where it's running on, and Arch doesn't modify upstream configs/defaults. The idea is to give services enough time to complete their termination, which can take some time depending on what needs to be done. Think of cleanup actions, storing user data, etc... On a regular desktop system, you're most likely not running any services which require a long termination time, so these 90s are way too long. You're much more likely to run into issues where the processes of a service didn't terminate because they got stuck (waiting for a resource, or due to a software bug, etc.). AFAIK, Fedora recently reduced the default value to 45s or so, because 90s is much more of an annoyance than it's actually useful for the vast majority of users and systems. If there's a service which actually requires a larger timeout value, then this can be overridden in the service itself, or the user can choose a longer default timeout value on their system themself. Instead of 5s, I'd set it to something like 10s or 15s, just to be sure that it doesn't harm any non-bugged-out services. Five or ten more seconds won't hurt you. https://www.freedesktop.org/software/systemd/man/systemd-system.conf.html#DefaultTimeoutStartSec= https://www.freedesktop.org/software/systemd/man/systemd.service.html#TimeoutStopSec=
2 of 3
3
The problems that can arise is data corruption/issues if you have a process that legitimately requires more time than 5 seconds to properly fix itself. You can override this setting on a per service basis, and in this particular case you should actually fix the issue by opting for sddm-git which has fixes for the long delay shutdown (I'm not sure why they haven't done a release in well over a year but I do hope they wrap something up soon)
🌐
GitHub
github.com › systemd › systemd › issues › 31641
Put time limit on systemd-tmpfiles-setup by default · Issue #31641 · systemd/systemd
August 10, 2023 - There should be a limit on how long the job can run during boot. Let's say 3 minutes. ... It doesn't block the user for undetermined amount of time.
Published   Mar 05, 2024
🌐
Linux.org
linux.org › home › forums › general linux forums › general linux topics
Why startup timeout for service in systemd has no effect on it. | Linux.org
April 14, 2024 - This is how long the service can take to startup before it times out. Very few services will take 90 seconds to start up. If you're wanting a delay, before a service starts, there are at least two ways to do this. ... [Service] ExecStartPre=/bin/sleep 10 ExecStart=/path/to/your/service or the other way is a little more complicated. systemd-time-wait-sync.service: Follow these steps: This is for Debian/Ubuntu, but Redhat/Fedora is similar.
Find elsewhere
Top answer
1 of 5
62

To have a service restart 3 times at 90 second intervals include the following lines in your systemd service file:

[Unit]
StartLimitIntervalSec=400
StartLimitBurst=3
[Service]
Restart=always
RestartSec=90

Before systemd-230 it was called just StartLimitInterval:

[Unit]
StartLimitInterval=400
StartLimitBurst=3
[Service]
Restart=always
RestartSec=90

This worked worked for me for a service that runs a script using Type=idle. Note that StartLimitIntervalSec must be greater than RestartSec * StartLimitBurst otherwise the service will be restarted indefinitely.

It took me some time with a lot of trial and error to work out how systemd uses these options, which suggests that systemd isn't as well documented as one would hope. These options effectively provide the retry cycle time and maximum retries that I was looking for.

References: https://manpages.debian.org/testing/systemd/systemd.unit.5.en.html for Unit section https://manpages.debian.org/testing/systemd/systemd.exec.5.en.html for Service section

2 of 5
25

Some years later and with systemd 232 it dosn't work anymore as described in the question and in the answers from 2016. Option name StartLimitIntervalSec and Sections have changed. Now it has to look like this example:

[Unit]
StartLimitBurst=5
StartLimitIntervalSec=33

[Service]
Restart=always
RestartSec=5
ExecStart=/bin/sleep 6

This will do 5 restarts in 30 sec (5*6) plus one restart in 33 sec. So we have 6 restarts in 33 sec. This exceeds the limit of 5 restarts in 33 sec. So restarts will stop at 5 counts after about 31 sec.

🌐
freedesktop.org
freedesktop.org › software › systemd › man › latest › systemd.timer.html
systemd.timer
The arguments to the directives are time spans configured in seconds. Example: "OnBootSec=50" means 50s after boot-up. The argument may also include time units. Example: "OnBootSec=5h 30min" means 5 hours and 30 minutes after boot-up. For details about the syntax of time spans, see systemd.time(7).
🌐
Techiescamp
blog.techiescamp.com › systemd-timers
Systemd Timers: A Comprehensive Guide For Beginners
January 17, 2025 - If the restart limit has been reached, it will wait for 10 minutes before triggering another restart. After this period, the restart counter resets, allowing the service to try again. You can use the man command to know more about the timer configuration. ... Let's create a system timer that writes in a file every 2 minutes from Monday to Friday. Important Note: This is a demo example to help understand systemd ...
🌐
ArchWiki
wiki.archlinux.org › title › Systemd › Timers
systemd/Timers - ArchWiki
OnCalendar time specifications can be tested in order to verify their validity and to calculate the next time the condition would elapse when used on a timer unit file with the calendar option of the systemd-analyze utility. For example, one can use systemd-analyze calendar weekly or systemd-analyze calendar "Mon,Tue *-*-01..04 12:00:00". Add --iterations=N to ask for more iterations to be printed.
🌐
Ravenhub Blog
blog.theravenhub.com › post › ht-limit-service-ressources-systemd
Limit CPU, Memory, and Other Resources for a Service Using systemd - Ravenhub Blog
January 25, 2025 - [Service] # CPU resource controls ...system/myservice.service.d/override.conf and then reload systemd with sudo systemctl daemon-reload to apply the changes....
Top answer
1 of 2
157

The mappings of systemd limits to ulimit

Directive        ulimit equivalent     Unit
LimitCPU=        ulimit -t             Seconds      
LimitFSIZE=      ulimit -f             Bytes
LimitDATA=       ulimit -d             Bytes
LimitSTACK=      ulimit -s             Bytes
LimitCORE=       ulimit -c             Bytes
LimitRSS=        ulimit -m             Bytes
LimitNOFILE=     ulimit -n             Number of File Descriptors 
LimitAS=         ulimit -v             Bytes
LimitNPROC=      ulimit -u             Number of Processes 
LimitMEMLOCK=    ulimit -l             Bytes
LimitLOCKS=      ulimit -x             Number of Locks 
LimitSIGPENDING= ulimit -i             Number of Queued Signals 
LimitMSGQUEUE=   ulimit -q             Bytes
LimitNICE=       ulimit -e             Nice Level 
LimitRTPRIO=     ulimit -r             Realtime Priority  
LimitRTTIME=     ulimit -R             Microseconds

If a ulimit is set to 'unlimited' set it to 'infinity' in the systemd config

ulimit -c unlimited is the same as LimitCORE=infinity
ulimit -v unlimited is the same as LimitAS=infinity
ulimit -m unlimited is the same as LimitRSS=infinity

So a final config would look like

[Unit]
Description=Apache Solr
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
WorkingDirectory=/opt/solr/server
User=solr
Group=solr
LimitAS=infinity
LimitRSS=infinity
LimitCORE=infinity
LimitNOFILE=65536
ExecStart=/opt/solr/bin/solr-foo
Restart=on-failure
SuccessExitStatus=143 0
SyslogIdentifier=solr


[Install]
WantedBy=multi-user.target

In this particular case, I don't know the full java path (since it changes based on server type), and systemd isn't happy about relative paths, I wrap the java command in a simple bash script located at /opt/solr/bin/solr-foo

#!/bin/bash

. /opt/solr/bin/solr.in.sh

# Load $JAVA_HOME from 1 of 2 places where it could be defined
# Last one wins
if [[ -f "/etc/profile.d/jdk.sh" ]]; then
  . /etc/profile.d/jdk.sh
fi

if [[ -f "/etc/profile.d/zing.sh" ]]; then
  . /etc/profile.d/zing.sh
fi

exec ${JAVA_HOME}/bin/java -server \
  -Djetty.port=${SOLR_PORT} \
  ${SOLR_JAVA_MEM} \
  ${GC_TUNE} \
  ${GC_LOG_OPTS} \
  -DzkClientTimeout=${ZK_CLIENT_TIMEOUT} \
  -DzkHost=${ZK_HOST} \
  -DSTOP.PORT=7900 \
  -DSTOP.KEY=foobar \
  -Dhost=${SOLR_HOST} \
  -Duser.timezone=${SOLR_TIMEZONE} \
  -Djetty.home=/opt/solr/server \
  -Dsolr.solr.home=${SOLR_HOME} \
  -Dsolr.install.dir=/opt/solr \
  -Dlog4j.configuration=file:/var/solr/log4j.properties \
  -Xss256k \
  -Dbootstrap_conf=true \
  -Dbootstrap_confdir=/opt/solr/server/solr/configsets/foobar/conf \
  -Dcollection.configName=foobar \
  -jar start.jar --module=http
2 of 2
0

The syntax for setting the limits you asked for is:

# Equivalent of ulimit -c 2
LimitCORE=2
# Functional replacement for both ulimit -m and ulimit -v
MemoryMax=1024M

The equivalent of ulimit -v is LimitAS, however, the systemd documentation states "Don't use. This limits the allowed address range, not memory use! Defaults to unlimited and should not be lowered. To limit memory use, see MemoryMax= in systemd.resource-control(5)".

The equivalent of ulimit -m is LimitRSS, however, the systemd documentation states "Don't use. No effect on Linux." and further explains "Note that most process resource limits configured with these options are per-process, and processes may fork in order to acquire a new set of resources that are accounted independently of the original process, and may thus escape limits set. Also note that LimitRSS= is not implemented on Linux, and setting it has no effect. Often it is advisable to prefer the resource controls listed in systemd.resource-control(5) over these per-process limits, as they apply to services as a whole, may be altered dynamically at runtime, and are generally more expressive. For example, MemoryMax= is a more powerful (and working) replacement for LimitRSS=.".

The full list of systemd equivalents of ulimit is listed here: https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Process%20Properties

MemoryMax, from systemd resource control documentation: https://www.freedesktop.org/software/systemd/man/latest/systemd.resource-control.html#MemoryMax=bytes

🌐
Stack Exchange
unix.stackexchange.com › questions › 382465 › how-do-i-change-the-time-limit-on-systemd-shutdown-scripts
centos - How do I change the time limit on systemd shutdown scripts? - Unix & Linux Stack Exchange
Running systemctl show SERVICE_NAME.service -p TimeoutStopUSec you could see the timeout set by systemd to service. Instead of editing the package's service file in /usr/lib/systemd/system/ which will get overridden on package upgrade, use: sudo EDITOR=/bin/vi systemctl edit <service-name> This will safely edit the file /etc/systemd/system/service-name.service.d/override.conf.
🌐
freedesktop.org
freedesktop.org › software › systemd › man › latest › systemd.service.html
systemd.service
Added in version 188. ... This option configures the time to wait for the service to terminate when it was aborted due to a watchdog timeout (see WatchdogSec=). If the service has a short TimeoutStopSec= this option can be used to give the system more time to write a core dump of the service. Upon expiration the service will be forcibly terminated by SIGKILL (see KillMode= in systemd.kill(5)).
🌐
Manjaro Linux
forum.manjaro.org › support
Reduce timeout for "stop job is running" systemd - Support - Manjaro Linux Forum
October 26, 2020 - I want to reduce the timeout for the following message when shutting down: “A stop job is running for … (1m 30s)” It is usually set to 90 seconds. I found this: https://unix.stackexchange.com/questions/328317/reducin…