How to send SIGTERM (graceful shutdown) to a .NET Core process in MacOS/Linux

Simulate shutdown during development

How to send SIGTERM (graceful shutdown) to a .NET Core process in MacOS/Linux

When first learning about this I was like "damn, that's cool!". So I thought I must share it here.


How to send termination (SIGTERM) signal:

  1. Start your application with:
    Console.WriteLine($"Process id: {Process.GetCurrentProcess().Id}")
  2. Your application should now be running, and you have the process id in your console. Copy this process id.
  3. Open another terminal, and use the following command to send a SIGTERM:
    kill -s TERM <process_id>
    TERM here means SIGTERM, which means to - in a polite way - to ask the application to shutdown.
    This is equivalent of using Ctrl+C in the terminal running your application.
  4. Watch your application receive a shutdown signal. .NET Core by default uses a ConsoleLifetime class that is wired up by default and listens to this signal.

But shutdown - what do you mean?

Personally I think it's very common to write applications with a state of mind assuming that the application will be running all the time, especially if you're developing a web application or an API which typically is a long-running process. It happens though that our applications crashes and must be restarted, or it happens that we host them in container orchestrators (read Kubernetes) that can decide to kill your application at any give time. In this case, it becomes valuable to think about shutting down you application while causing the least amount of harm possible during this shutdown period. For example, you might want to not start writing to disk if you already know the application is about to shut down.  To add this kind of functionality, extra code with the only responsibility to exit your application gracefully, is called graceful shutdown.

It becomes important to simulate a shutdown signal in order to ensure your application terminates in a reasonable way. For me I had to deal with this when starting to host more and more services in Kubernetes, since Kubernetes can (potentially) kill your pod at any given time. I also had problems with the console itself, and could not send Ctrl+C, which is why I found out about the kill command.


Both these are shutdown signals. The latter is more aggressive than the other. As mentioned, SIGTERM means to - in a polite way - to ask the application to shutdown. SIGKILL on the other hand is a hard exit, where your application has no time to gracefully shutdown, but is just instantly killed. You can read more about the different termination signals here.

The kill command

If we read the man page about the kill command we will see the following:

kill -- terminate or signal a process

And actually, TERM is the default value, so you could omit it. But I like to be explicit sometimes.


kill can be very useful when adding graceful shutdown to your application and want to test it locally. If you want to read more about how graceful shutdown actually works in .NET Core, i'd recommend to start by reading Introducing IHostLifetime and untangling the Generic Host startup interactions by Andrew Lock. And also reading about IHostApplicationLifetime. If you developing ASP.NET Core and hosting in Kubernetes then i'd definitely also recommend you to read Graceful termination in Kubernetes with ASP.NET Core by Mark Vincze (even though the post uses the now deprecated IApplicationLifetime, it's still very valuable).

Addition 2022-04-07: Although not strictly related to SIGTERM or SIGKILL, but more related to "graceful shutdown", I highly recommend this blog post series by Stephen Cleary on cancellation tokens