Feature: Rate Limiting
Relevant source files
The following files were used as context for generating this wiki page:The rate limiting feature is a core safeguard within the ralph_loop.sh script, designed to prevent excessive API usage by enforcing a configurable hourly call limit. This system ensures that the autonomous development loop operates within predefined boundaries, automatically pausing execution when the limit is reached and resuming when the next hourly window begins.
The mechanism is primarily managed through a set of state files and bash functions that track API calls against a timestamp. It is distinct from, but complementary to, other control mechanisms like the Circuit Breaker and the specific handling for Claude's 5-hour usage limit.
Sources: create_files.sh:11-13, README.md:165-172, CLAUDE.md:80-83
Architecture and Configuration
The rate limiting system is configured through a combination of shell variables within ralph_loop.sh and a command-line argument. Its state is persisted on the filesystem using hidden files.
Sources: create_files.sh:16-19, README.md:165-168, CLAUDE.md:80-83
Configuration Parameters
| Parameter | Type | Default Value | Description |
|---|---|---|---|
MAX_CALLS_PER_HOUR | Variable / CLI Flag | 100 | The maximum number of Claude API calls allowed per hour. Can be overridden by the --calls flag. |
CALL_COUNT_FILE | Variable | .call_count | A hidden file that stores the number of API calls made in the current hour. |
TIMESTAMP_FILE | Variable | .last_reset | A hidden file storing the timestamp (format YYYYMMDDHH) of the last counter reset. |
-c, --calls | CLI Flag | N/A | A command-line option to override the MAX_CALLS_PER_HOUR default value. |
Sources: create_files.sh:17,20,21,363-366, README.md:435-436
State Management
The system's state is maintained through two simple text files in the project's root directory.
This diagram illustrates the files used for state management.
Sources: create_files.sh:20-21
Core Logic and Flow
The rate limiting logic is integrated directly into the main while loop of ralph_loop.sh. Before each call to the Claude Code CLI, the script checks if it is allowed to proceed.
This flowchart shows the decision-making process for rate limiting within each loop iteration.
Sources: create_files.sh:300-309
Key Functions
The system is implemented through a series of shell functions in ralph_loop.sh.
| Function | Description |
|---|---|
init_call_tracking() | Initializes or resets the call counter. It compares the current hour with the timestamp in .last_reset and resets .call_count to 0 if a new hour has started. |
can_make_call() | Checks if the current call count in .call_count is less than MAX_CALLS_PER_HOUR. Returns exit code 0 (true) if a call can be made, and 1 (false) otherwise. |
increment_call_counter() | Reads the value from .call_count, increments it by one, and writes the new value back to the file. |
wait_for_reset() | Triggered when can_make_call() returns false. It calculates the remaining time until the next hour, displays a countdown timer, and then resets the counter files. |
Sources: create_files.sh:28-50, 116-125, 127-137, 139-165
Wait and Reset Sequence
When the rate limit is reached, the wait_for_reset function orchestrates a pause and reset.
This sequence diagram details the interactions during the wait and reset process.
Sources: create_files.sh:139-165
The wait time is calculated based on the current system time to determine the number of seconds remaining until the start of the next hour.
# From create_files.sh
local current_minute=$(date +%M)
local current_second=$(date +%S)
local wait_time=$(((60 - current_minute - 1) * 60 + (60 - current_second)))
Sources: create_files.sh:145-147
Testing
The rate limiting logic is validated through a dedicated suite of unit tests in tests/unit/test_rate_limiting.bats. These tests ensure the core functions behave as expected under various conditions.
Key test scenarios include:
can_make_callreturns success when the call count is under the limit.can_make_callreturns failure when the call count is at the limit.increment_call_countercorrectly increases the count in the state file.- The hourly reset logic correctly identifies a new hour and resets the counter.
Sources: TESTING.md:25, CONTRIBUTING.md:170
This is an example test case from the suite:
# From tests/unit/test_rate_limiting.bats (as described in TESTING.md)
@test "can_make_call returns failure when at limit" {
echo "100" > ".call_count"
export MAX_CALLS_PER_HOUR=100
run can_make_call
assert_failure
}
Sources: CONTRIBUTING.md:214-222
Related Mechanisms
The hourly rate limiting system is one of several control mechanisms in Ralph. A related, but distinct, feature is the handling of Claude's 5-hour usage limit, which is detected by parsing the CLI output and prompting the user to wait or exit. Additionally, the SPECIFICATION_WORKSHOP.md outlines a potential future feature for "Automatic retry on API rate limit errors," which would introduce more sophisticated backoff and retry logic for transient API errors, complementing the current hourly limit system.
Sources: README.md:174-182, SPECIFICATION_WORKSHOP.md:213-261