---
key: lesson/performance-budget
type: lesson
id: performance-budget
lang: en
title: A performance budget
summary: >-
  Set a measurable target, locate the bottleneck with a profiler, and compare
  changes under the same conditions.
updatedAt: '2026-10-20'
status: active
url: 'https://gamemechanics.pro/en/lessons/performance-budget/'
jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/en/lesson/performance-budget.json'
markdownUrl: 'https://gamemechanics.pro/content/knowledge/en/lesson/performance-budget.md'
aliases: []
tags:
  - performance
  - profiling
  - frame-time
sourceIds:
  - source-657cab2680b01317
sources:
  - id: source-657cab2680b01317
    title: 'Godot: General optimization tips'
    url: >-
      https://docs.godotengine.org/en/stable/tutorials/performance/general_optimization.html
    verifiedAt: null
relations:
  - type: requires
    direction: outgoing
    label: Before you start
    key: lesson/game-loop
    title: The game loop and time
    url: 'https://gamemechanics.pro/en/lessons/game-loop/'
    jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/en/lesson/game-loop.json'
    markdownUrl: 'https://gamemechanics.pro/content/knowledge/en/lesson/game-loop.md'
  - type: related
    direction: outgoing
    label: Related materials
    key: lesson/gameplay-acceptance
    title: Verifying gameplay behavior
    url: 'https://gamemechanics.pro/en/lessons/gameplay-acceptance/'
    jsonUrl: >-
      https://gamemechanics.pro/api/v1/knowledge/en/lesson/gameplay-acceptance.json
    markdownUrl: >-
      https://gamemechanics.pro/content/knowledge/en/lesson/gameplay-acceptance.md
  - type: contains
    direction: incoming
    label: Learning paths
    key: path/first-prototype
    title: Your first verifiable prototype
    url: 'https://gamemechanics.pro/en/learn/first-prototype/'
    jsonUrl: 'https://gamemechanics.pro/api/v1/knowledge/en/path/first-prototype.json'
    markdownUrl: 'https://gamemechanics.pro/content/knowledge/en/path/first-prototype.md'
  - type: uses
    direction: outgoing
    label: Sources in the selection
    key: resource/godot-performance
    title: 'Godot: performance measurement'
    url: 'https://gamemechanics.pro/en/resources/#resource-godot-performance'
    jsonUrl: >-
      https://gamemechanics.pro/api/v1/knowledge/en/resource/godot-performance.json
    markdownUrl: >-
      https://gamemechanics.pro/content/knowledge/en/resource/godot-performance.md
placements: []
supersededBy: []
attributes:
  category: engineering
  level: intermediate
  minutes: 6
endsAt: null
provenance: >-
  Original gamemechanics.pro material. Check illustrative examples in your own
  project.
license: CC-BY-4.0
codeLicense: MIT
attribution: gamemechanics.pro contributors
---
# A performance budget

id: performance-budget
type: lesson
key: lesson/performance-budget
lang: en
status: active
url: https://gamemechanics.pro/en/lessons/performance-budget/

Set a measurable target, locate the bottleneck with a profiler, and compare changes under the same conditions.

## Prerequisites

You need a playable scene and access to the target device, or an explicitly identified intermediate environment. This lesson turns “make it faster” into a measurement of a particular workload. Low-level optimization expertise is not required.

## The principle

Start with platform, resolution, build configuration, and target frame rate. At 60 frames per second, the interval between frames is about 16.67 ms; at 30, it is about 33.33 ms. This arithmetic provides a frame-pacing target, not a promise that any scene can finish within it.

Do not automatically add every CPU and GPU timing together, because their work may overlap. Learn what a measurement tool reports and identify what delays the next completed frame. Speeding up one function cannot resolve a bottleneck elsewhere.

[Godot's optimization guidance](https://docs.godotengine.org/en/stable/tutorials/performance/general_optimization.html) recommends finding bottlenecks through measurement and checking the effect of changes. It also distinguishes sustained slow execution, individual stalls, and long loading operations. Each needs an appropriate observation scenario.

<span id="example-an-enemy-arena"></span>

## Practical example

### An enemy arena

Suppose an empty arena feels smooth, but spawning a wave causes a stall. Do not start by rewriting movement. Create a repeatable scenario with the same arena, enemy count, random seed (the generator’s initial value), and spawn timing.

```text
scenario: spawn-wave
device: exact model and power mode
build: production configuration
resolution: fixed value
warmup: 20 seconds
record: 60 seconds
report: median, p95, p99 frame time and longest frame
compare: baseline versus one isolated change
```

This is an example procedure. Choose durations that fit your game and keep them constant across comparisons. p95 and p99 mark the bounds within which roughly 95% and 99% of measured frames fall, exposing occasional slow frames hidden by an average. A short recording can still miss rare failures.

Capture a profile around the spawn event. If object creation and resource preparation dominate, investigate preloading or spreading the work over time. If updating every object is consistently expensive, inspect update frequency and workload. Choose a fix from the evidence instead of selecting a fashionable optimization technique.

## Common mistakes

An object pool needs correct state reset. A reused enemy that retains old health or event subscriptions is still broken, even if it spawns faster. Verify gameplay outcomes alongside timing.

Comparing an editor run with a production build on another computer cannot isolate one code change. Record device, power mode, build, settings, and background workload. A run on a powerful laptop does not verify your minimum supported hardware.

Do not measure FPS alone. Initial loading, download size, peak memory, or menu response time may matter more for the problem being investigated. Select metrics that describe the observed issue and leave headroom for ordinary environmental variation.

## Verify it

- The target specifies a platform, scene, and settings.
- A baseline recording exists from before the change.
- Profile evidence explains the chosen optimization.
- Comparison runs use the same workload and conditions.
- Slow frames are inspected rather than relying only on average FPS.
- Gameplay and memory use have not silently regressed.
- Target devices that were not tested are named explicitly.

## Prompt for an AI agent

> First define a repeatable scenario and collect baseline measurements. Identify the main bottleneck with a profiler and suggest one small change. Compare frame times under the same conditions, then check gameplay behavior and memory. If target hardware is unavailable, state that limitation and do not claim its performance has been verified.

## Connected materials

- Before you start: [The game loop and time](https://gamemechanics.pro/en/lessons/game-loop/) (key: lesson/game-loop)
- Related materials: [Verifying gameplay behavior](https://gamemechanics.pro/en/lessons/gameplay-acceptance/) (key: lesson/gameplay-acceptance)
- Learning paths: [Your first verifiable prototype](https://gamemechanics.pro/en/learn/first-prototype/) (key: path/first-prototype)
- Sources in the selection: [Godot: performance measurement](https://gamemechanics.pro/en/resources/#resource-godot-performance) (key: resource/godot-performance)

## Sources and provenance

Original gamemechanics.pro material. Check illustrative examples in your own project.

- [Godot: General optimization tips](https://docs.godotengine.org/en/stable/tutorials/performance/general_optimization.html) (id: source-657cab2680b01317)

CC-BY-4.0 · gamemechanics.pro contributors
