Calling all startups: Apply to the Neon Startup program and get up to 100k in credits
/Features/Branching/Branch expiration

Branch expiration

Learn how to use Neon's branch expiration feature to automatically delete temporary branches

Feature coming soon

This feature is currently not available and subject to change. It will soon be made available to members of our Early Access Program.

Overview

Branch expiration allows you to set automatic deletion timestamps on branches. When the expiration time is reached, the branch is automatically deleted.

Quick guide

API/CLI: Use expires_at with RFC 3339 format (e.g., 2025-07-15T18:02:16Z)

Console: Check "Expire branch on:" and select a date and time

What you will learn:

  • When and why to use branch expiration

  • How to set expiration timestamps via API, CLI, and Console

  • How expiration timestamps and TTL intervals work

  • Restrictions and best practices

Why use branch expiration?

Branch expiration is ideal for temporary branches that have predictable lifespans:

  • CI/CD environments - Test branches that should clean up after pipeline completion
  • Feature development - Time-boxed feature branches with known deadlines
  • Automated testing - Ephemeral test environments created by scripts
  • AI workflows - Temporary environments managed without human intervention

Without automatic expiration, these branches accumulate over time, increasing storage costs and project clutter.

tip

Example expiration durations: CI/CD pipelines (2-4 hours), demos (24-48 hours), feature development (1-7 days), long-term testing (30 days).

How it works

Branch expiration uses a time-to-live (TTL) model. When you set an expiration on a branch, you're defining how long the branch should exist before automatic deletion.

When you set an expiration timestamp on a branch:

  1. The system stores both:

    • Expiration timestamp (expires_at) - The scheduled date and time when the branch will be deleted
    • TTL interval (ttl_interval_seconds) - The duration between creation/update and expiration (e.g., 24 hours = 86400 seconds), a read-only value
  2. A background process monitors branches and deletes them after their expiration time is reached

  3. If you reset a branch from its parent, the TTL countdown restarts using the original interval

important

Branch deletion is permanent and cannot be recovered. All associated data and compute endpoints are also deleted. Verify expiration times carefully before setting them.

Setting branch expiration

You can set, update, or remove expiration timestamps through three interfaces:

  • API - Use the expires_at parameter with RFC 3339 format
  • CLI - Use the --expires-at flag when creating or updating a branch with RFC 3339 format
  • Neon Console - Check "Expire branch on:" and define or select a date (automatically handles formatting)

See the Examples section below for detailed usage of each method.

Timestamp format requirements

The expires_at parameter must use RFC 3339 format with second-level precision:

Format patterns:

YYYY-MM-DDTHH:MM:SSZ         (UTC)
YYYY-MM-DDTHH:MM:SS+HH:MM    (Positive UTC offset)
YYYY-MM-DDTHH:MM:SS-HH:MM    (Negative UTC offset)

Valid examples:

  • 2025-07-15T18:02:16Z (UTC)
  • 2025-07-15T18:02:16-05:00 (Eastern Standard Time)
  • 2025-07-15T18:02:16+09:00 (Japan Standard Time)

Requirements:

  • Time zone is required (either Z or numeric offset, not both)
  • Fractional seconds are optional but only second precision is stored
  • Timestamp must be in the future
  • Maximum expiration is 30 days from the current time

note

Common errors include missing timezone (2025-07-15T18:02:16), past timestamps, or combining Z with offset (2025-07-15T18:02:16Z-05:00).

Restrictions

To maintain system integrity, expiration timestamps cannot be added to:

  • Protected branches - Cannot expire protected branches or protect branches with expiration
  • Default branches - Cannot expire default branches or set expiring branches as default
  • Parent branches - Cannot expire branches that have children or create children from expiring branches

Branch expiration is not supported with these Neon features:

  • Data API
  • Neon Auth

note

When a branch expires and is deleted, all associated compute endpoints are also deleted. Ensure any critical workloads are migrated before expiration.

Examples

Creating a branch with expiration

API
CLI
Neon Console
# Create branch that expires in 24 hours
curl --request POST \
     --url https://console.neon.tech/api/v2/projects/{project_id}/branches \
     --header 'Accept: application/json' \
     --header "Authorization: Bearer $NEON_API_KEY" \
     --header 'Content-Type: application/json' \
     --data '{
       "branch": {
         "name": "feature-test",
         "parent_id": "br-main-12345",
         "expires_at": "2026-01-29T18:02:16Z"
       }
     }'

# Example response
{
  "branch": {
    "id": "br-feature-67890",
    "name": "feature-test",
    "parent_id": "br-main-12345",
    "expires_at": "2026-01-29T18:02:16Z",
    "ttl_interval_seconds": 86400,
    "created_at": "2026-01-28T18:02:16Z"
  }
}

Updating branch expiration

API
CLI
Neon Console
# Update branch expiration to specific date
curl --request PATCH \
     --url https://console.neon.tech/api/v2/projects/{project_id}/branches/{branch_id} \
     --header 'Accept: application/json' \
     --header "Authorization: Bearer $NEON_API_KEY" \
     --header 'Content-Type: application/json' \
     --data '{
       "branch": {
         "expires_at": "2026-01-29T12:00:00Z"
       }
     }'

# Remove expiration from a branch
curl --request PATCH \
     --url https://console.neon.tech/api/v2/projects/{project_id}/branches/{branch_id} \
     --header 'Accept: application/json' \
     --header "Authorization: Bearer $NEON_API_KEY" \
     --header 'Content-Type: application/json' \
     --data '{
       "branch": {
         "expires_at": null
       }
     }'

Retrieving branch information

Check expiration status of your branches:

API
CLI
curl --request GET \
     --url https://console.neon.tech/api/v2/projects/{project_id}/branches/{branch_id} \
     --header 'Accept: application/json' \
     --header "Authorization: Bearer $NEON_API_KEY"

API reference

Create project branch

POST /projects/{project_id}/branches

  • expires_at (optional) - Timestamp for automatic deletion in RFC 3339 format

Update project branch

PATCH /projects/{project_id}/branches/{branch_id}

  • expires_at (optional, nullable) - Update or remove expiration
    • Timestamp value: Sets/updates expiration
    • null: Removes expiration
    • Omitted: No change

Response fields

Branches with expiration include two key fields:

  • expires_at - The scheduled deletion timestamp (RFC 3339 format)
  • ttl_interval_seconds - The original TTL duration in seconds (read-only)

How these fields work together

When you create a branch with a TTL of 24 hours, ttl_interval_seconds is set to 86400 (seconds). The expires_at value is calculated as creation time plus 24 hours.

If you reset the branch from its parent, the expires_at value is recalculated using the preserved ttl_interval_seconds value, starting from the reset time. The interval itself remains unchanged.

Example response:

{
  "branch": {
    "id": "br-feature-67890",
    "expires_at": "2026-01-29T18:02:16Z",
    "ttl_interval_seconds": 86400,
    "created_at": "2026-01-28T18:02:16Z"
  }
}

In this example, the branch will be deleted 24 hours after creation.

Need help?

Join our Discord Server to ask questions or see what others are doing with Neon. Users on paid plans can open a support ticket from the console. For more details, see Getting Support.

Last updated on

Was this page helpful?