All Products
Search
Document Center

Function Compute:Lifecycle hooks for function instances

Last Updated:Apr 01, 2026

Function Compute calls lifecycle hooks when specific instance events occur, letting you run setup and teardown code outside your handler. The C# runtime supports two hooks: Initializer and PreStop. For background on instance lifecycle management, see Configure instance lifecycles.

Lifecycle hooks are billed the same way as standard function invocations. Hook execution logs appear in Function Logs, Real-time Logs, and Advanced Logs, but not in the invocation request list.

How Initializer and PreStop work

Initializer

The Initializer hook runs after a function instance starts and before the first handler invocation. Function Compute guarantees it runs exactly once per instance lifetime.

If the Initializer hook fails, the invocation returns an error. On the next invocation, Function Compute creates a new instance and retries the Initializer hook.

Use the Initializer hook for one-time setup — for example, initializing SDK clients or database connections. Because Function Compute reuses warm instances across invocations, setup code in the Initializer hook runs once and its results are available to every subsequent handler call on that instance.

PreStop

The PreStop hook runs before a function instance is destroyed. Use it to flush buffers, close connections, or release resources before the instance shuts down.

Method signature

Both Initializer and PreStop hooks use the same method signature: one IFcContext input parameter and no return value.

Instance method:

public void FunctionName(IFcContext context);

Static method:

public static void FunctionName(IFcContext context);

Example

The following example shows a class that implements both hooks alongside a stream handler.

using System;
using System.IO;
using System.Threading.Tasks;
using Aliyun.Serverless.Core;
using Microsoft.Extensions.Logging;

namespace Example
{
    public class Hello
    {
        public void Initialize(IFcContext context)
        {
            IFcLogger logger = context.Logger;
            logger.LogInformation("Initialize start");
            logger.LogInformation("Handle initializer: {0}", context.RequestId);
            logger.LogInformation("Initialize end");
        }

        public void PreStop(IFcContext context)
        {
            IFcLogger logger = context.Logger;
            logger.LogInformation("PreStop start");
            logger.LogInformation("Handle PreStop: {0}", context.RequestId);
            logger.LogInformation("PreStop end");
        }

        public async Task<Stream> StreamHandler(Stream input, IFcContext context)
        {
            IFcLogger logger = context.Logger;
            logger.LogInformation("Handle request: {0}", context.RequestId);

            MemoryStream copy = new MemoryStream();
            await input.CopyToAsync(copy);
            copy.Seek(0, SeekOrigin.Begin);
            return copy;
        }

        static void Main(string[] args){}
    }
}

Configure lifecycle hooks

Use the Function Compute console

In the Function Compute console, configure hooks using the same format as a handler: Assembly name::Namespace.Class name::Method name. For details, see Configure instance lifecycles and Handlers.

Based on the example class above:

  • Initializer: HelloFcApp::Example.Hello::Initialize

  • PreStop: HelloFcApp::Example.Hello::PreStop

Use Serverless Devs

Add instanceLifecycleConfig to the function block in your s.yaml file. Each hook requires a handler and a timeout field.

edition: 3.0.0
name: hello-world-app
access: "default"

vars:
  region: "cn-hangzhou"

resources:
  hello_world:
    component: fc3
    actions:
      pre-${regex('deploy|local')}:
        - run: dotnet publish -c Release -o ./target
          path: ./HelloWorldApp
    props:
      region: ${vars.region}
      functionName: "start-dotnetcore-p6jp"
      description: 'hello world by serverless devs'
      runtime: "dotnetcore3.1"
      code: ./HelloWorldApp/target/
      handler: HelloWorldApp::Example.Hello::StreamHandler
      memorySize: 128
      timeout: 10
      instanceLifecycleConfig:
        initializer:
          handler: HelloFcApp::Example.Hello::Initialize
          timeout: 60
        preStop:
          handler: HelloFcApp::Example.Hello::PreStop
          timeout: 60

For YAML syntax details, see Common commands of Serverless Devs.

View lifecycle hook logs

  1. Log on to the Function Compute console. In the left-side navigation pane, click Functions.

  2. In the top navigation bar, select a region. On the Functions page, click the function you want to inspect.

  3. On the function details page, click the Test Function tab, click Test Function, and then choose Logs > Function Logs.

The Logs tab shows both invocation logs and Initializer logs:

2024-03-04 17:57:28  FC Initialize Start RequestId: 1-65e59b07-1520da26-bf73bbb91b69
2024-03-04 17:57:28  2024-03-04 09:57:28.192 1-65e59b07-1520da26-bf73bbb91b69 [info] initializer
2024-03-04 17:57:28  FC Initialize End RequestId: 1-65e59b07-1520da26-bf73bbb91b69
2024-03-04 17:57:28  FC Invoke Start RequestId: 1-65e59b07-1520da26-bf73bbb91b69
2024-03-04 17:57:28  FC Invoke End RequestId: 1-65e59b07-1520da26-bf73bbb91b69

Function instances are cached after invocation and not immediately destroyed, so PreStop logs do not appear right away. To trigger a PreStop hook immediately, update the function configuration or code — this forces existing instances to be replaced. After the update, PreStop logs appear in Function Logs:

2024-03-04 18:33:26  FC PreStop Start RequestId: 93c93603-9fbe-4576-9458-193c8b213031
2024-03-04 18:33:26  2024-03-04 10:33:26.077 93c93603-9fbe-4576-9458-193c8b213031 [info] preStop
2024-03-04 18:33:26  FC PreStop End RequestId: 93c93603-9fbe-4576-9458-193c8b213031

What's next