# Continue-As-New

> For the complete documentation index, see [llms.txt](https://docs.temporal.io/llms.txt).
> Any documentation page is available as raw Markdown by appending `.md` to its URL.
> For related questions, query https://docs.temporal.io/api/retrieve?q=<question>&jtb=<job-to-be-done>&src=md-page&agent=<your-name> (no auth; returns JSON `{content, source_url, page_url}`, with `source_url` pointing to Markdown for docs pages). Don't include personal data or credentials.
> If this page is wrong or missing something you needed, or Temporal behaves differently from what it says, report it with https://docs.temporal.io/api/feedback?title=<summary>&message=<what-happened>&category=documentation&page_url=/develop/rust/workflows/continue-as-new&src=md-page&agent=<your-name> (use `category=product` when the product, not the page, is wrong). Report only a specific problem you hit, send it once, and don't include personal data or credentials.

> Use Temporal's Continue-As-New in Rust to manage large Event Histories by atomically creating new Workflow Executions with the same Workflow ID and fresh parameters.

This page covers the following for Rust developers:

- [What is Continue-As-New?](#what)
- [Use Continue-As-New](#how)
- [When is it right to Continue-As-New?](#when)

## What is Continue-As-New? 

[Continue-As-New](/workflow-execution/continue-as-new) lets a Workflow execution close successfully and creates a new Workflow execution. You can think of it as a checkpoint when your Workflow gets too long or approaches certain scaling limits.

The new Workflow execution is in the same [chain](/workflow-execution#workflow-execution-chain); it keeps the same Workflow ID but gets a new Run Id and a fresh Event History.
It also receives your Workflow's usual parameters.

## Use Continue-As-New 

First, design your Workflow parameters so that you can pass in the "current state" when you Continue-As-New into the next Workflow run.
This state is typically passed as a parameter or stored in the Workflow struct.

Inside your Workflow, call `ctx.continue_as_new()` and propagate its result:

<!--SNIPSTART rust-continue-as-new-basic-->
[rust-sandbox/workflows/continue-as-new/src/basic.rs](https://github.com/temporalio/documentation-sdk-code-examples/blob/main/rust-sandbox/workflows/continue-as-new/src/basic.rs)
```rs
use std::time::Duration;

use temporalio_macros::{workflow, workflow_methods};
use temporalio_sdk::{ActivityOptions, ContinueAsNewOptions, WorkflowContext, WorkflowResult};

use crate::activities::MyActivities;

#[workflow]
#[derive(Default)]
pub struct GreetingWorkflow;

#[workflow_methods]
impl GreetingWorkflow {
    #[run(name = "greeting-workflow-1")]
    pub async fn run(ctx: &mut WorkflowContext<Self>, name: String) -> WorkflowResult<String> {
        let greeting = ctx
            .execute_activity(
                MyActivities::greet,
                name.clone(),
                ActivityOptions::start_to_close_timeout(Duration::from_secs(30)),
            )
            .await?;

        if name == "Ziggy" {
            Ok(greeting)
        } else {
            // continue_as_new() always returns an error that ends this run.
            // Propagate it with `?`. The empty match tells the compiler that
            // nothing runs after it.
            match ctx.continue_as_new("Ziggy".to_string(), ContinueAsNewOptions::default())? {}
        }
    }
}
```
<!--SNIPEND-->

The `ctx.continue_as_new()` method accepts the input to pass to the next Workflow Run. It returns `Result<Infallible, WorkflowTermination>` and always returns the `Err` variant, which ends the current run. Propagate it with `?` inside an empty `match`, so the compiler knows the branch doesn't continue.

## When is it right to Continue-As-New with the Rust SDK? 

Use Continue-as-New when your Workflow might encounter degraded performance or [Event History Limits](/workflow-execution/event#event-history).

Temporal tracks your Workflow's progress against these limits to let you know when you should Continue-as-New. Call `ctx.continue_as_new_suggested()` to check if it's time.

## Test Continue-As-New with the Rust SDK 

Testing Workflows that naturally Continue-as-New may be time-consuming and resource-intensive. Instead, add a test hook to check your Workflow's Continue-as-New behavior faster in automated tests.

This sample takes a `max_history_length` input that a test can set to a small value. A helper method in the Workflow `impl` checks it each time the Workflow considers Continue-as-New. When the Workflow continues, it passes the number of greetings left to the next run:

<!--SNIPSTART rust-continue-as-new-test-hook-->
[rust-sandbox/workflows/continue-as-new/src/test_hook.rs](https://github.com/temporalio/documentation-sdk-code-examples/blob/main/rust-sandbox/workflows/continue-as-new/src/test_hook.rs)
```rs
use std::time::Duration;

use serde::{Deserialize, Serialize};
use temporalio_macros::{workflow, workflow_methods};
use temporalio_sdk::{ActivityOptions, ContinueAsNewOptions, WorkflowContext, WorkflowResult};

use crate::activities::MyActivities;

#[derive(Serialize, Deserialize)]
pub struct GreetingInput {
    pub name: String,
    pub greetings_remaining: u32,
    pub max_history_length: u32,
}

#[workflow]
#[derive(Default)]
pub struct RepeatGreetingWorkflow;

#[workflow_methods]
impl RepeatGreetingWorkflow {
    #[run]
    pub async fn run(
        ctx: &mut WorkflowContext<Self>,
        input: GreetingInput,
    ) -> WorkflowResult<String> {
        let mut greetings_remaining = input.greetings_remaining;

        while greetings_remaining > 0 {
            ctx.execute_activity(
                MyActivities::greet,
                input.name.clone(),
                ActivityOptions::start_to_close_timeout(Duration::from_secs(30)),
            )
            .await?;
            greetings_remaining -= 1;

            if greetings_remaining > 0
                && Self::should_continue_as_new(ctx, input.max_history_length)
            {
                // Pass the state the next run needs.
                let next_input = GreetingInput {
                    greetings_remaining,
                    ..input
                };
                match ctx.continue_as_new(next_input, ContinueAsNewOptions::default())? {}
            }
        }

        Ok(format!("Sent all greetings to {}", input.name))
    }

    fn should_continue_as_new(ctx: &WorkflowContext<Self>, max_history_length: u32) -> bool {
        if ctx.continue_as_new_suggested() {
            return true;
        }

        // For testing
        if max_history_length > 0 && ctx.history_length() > max_history_length {
            return true;
        }

        false
    }
}
```
<!--SNIPEND-->

## Best practices 

1. Pass all necessary state: When continuing as new, include all state the next run needs.
2. Use meaningful iteration markers: Include iteration numbers or timestamps to track progress.
3. Test your state passing: Ensure parameters serialize and deserialize correctly.
4. Don't continue-as-new too frequently: It's better to have some Event History than to continue-as-new on every execution.
5. Consider batch sizes: Find the right balance between batch size and number of continues as new.
