Skip to content

Conversation

@NathanFlurry
Copy link
Member

No description provided.

@railway-app
Copy link

railway-app bot commented Jan 11, 2026

🚅 Deployed to the rivet-pr-3824 environment in rivet-frontend

Service Status Web Updated (UTC)
website 😴 Sleeping (View Logs) Web Jan 14, 2026 at 8:11 am
frontend-inspector 😴 Sleeping (View Logs) Web Jan 13, 2026 at 2:24 am
frontend-cloud 😴 Sleeping (View Logs) Web Jan 13, 2026 at 2:21 am

@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-3824 January 11, 2026 07:53 Destroyed
Copy link
Member Author


How to use the Graphite Merge Queue

Add the label merge-queue to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@claude
Copy link

claude bot commented Jan 11, 2026

PR Review: Platform Limits Configuration

Summary

This PR introduces comprehensive configuration for platform limits, making previously hardcoded timeouts, message sizes, and rate limits configurable. The changes improve flexibility for self-hosted deployments and properly document all limits.

✅ Strengths

1. Excellent Documentation Sync

  • The PR follows the new documentation sync guidelines added to CLAUDE.md
  • Both limits.mdx and configuration.mdx are properly updated
  • Clear distinction between soft limits (RivetKit) and hard limits (Engine)

2. Comprehensive Configuration Structure

  • Well-organized config groups: guard, gateway_*, api_*, runner_*
  • Sensible defaults for all new config values
  • Proper separation between actor traffic and API traffic settings

3. Good Error Handling

  • New RequestBodyTooLarge error with proper metadata (size, max_size)
  • Consistent error handling across guard-core and pegboard-gateway
  • Proper use of RivetError derive macro

4. Clean Code Organization

  • Config validation methods follow consistent naming pattern
  • Middleware function properly differentiates between actor and API traffic
  • WebSocket config properly scoped per connection

🔍 Issues & Recommendations

Critical Issues

1. Inconsistent Default Value: gateway_response_start_timeout_ms

// packages/config/src/config/pegboard.rs:219
pub fn gateway_response_start_timeout_ms(&self) -> u64 {
    self.gateway_response_start_timeout_ms
        .unwrap_or(5 * 60 * 1000) // 5 minutes
}
// website/src/content/docs/self-hosting/configuration.mdx:100
gateway_response_start_timeout_ms?: number;       // Default: 15000 (ms)

Issue: The code defaults to 5 minutes (300,000ms) but documentation says 15 seconds (15,000ms). This is a 20x difference!

Impact: Users relying on documentation will be surprised by actual behavior.

Recommendation: Update documentation to reflect the actual 5 minute default, or change the code if 15 seconds was intended.


2. Missing Fallback for WebSocket Message Size in Error Proxy Path

// packages/guard-core/src/proxy_service.rs:329
websocket_max_message_size: usize,

The comment says "Fallback WebSocket max message size (used for error proxy path)" but this fallback is stored but never actually used in the codebase. The error proxy path doesn't appear to use this value.

Recommendation: Either use this value in the error proxy path or remove it if not needed.


3. Configuration Documentation Incomplete

The configuration.mdx file is missing several config options that exist in the code:

  • gateway_rate_limit_requests
  • gateway_rate_limit_period_secs
  • gateway_max_in_flight
  • gateway_actor_request_timeout_secs
  • gateway_api_request_timeout_secs
  • gateway_retry_max_attempts
  • gateway_retry_initial_interval_ms
  • gateway_ws_proxy_timeout_secs
  • gateway_ws_connect_timeout_secs
  • gateway_ws_send_timeout_secs
  • gateway_ws_flush_timeout_secs
  • api_rate_limit_requests
  • api_rate_limit_period_secs
  • api_max_in_flight
  • api_retry_max_attempts
  • api_retry_initial_interval_ms
  • api_max_http_request_body_size

Recommendation: Add all configurable options to the documentation for completeness.


Minor Issues

4. Duplicate Error Definition

// engine/packages/guard-core/src/errors.rs:114
#[derive(RivetError, Serialize, Deserialize)]
#[error("guard", "request_body_too_large", ...)]
pub struct RequestBodyTooLarge { ... }

// engine/packages/pegboard-gateway/src/lib.rs:47
#[derive(RivetError, Serialize, Deserialize)]
#[error("guard", "request_body_too_large", ...)]
pub struct RequestBodyTooLarge { ... }

Issue: Same error is defined in two places. This could lead to inconsistencies if one is updated but not the other.

Recommendation: Keep only one definition (in guard-core/src/errors.rs) and import it where needed.


5. Comment Style Issues

Per CLAUDE.md guidelines, comments should be complete sentences without fragmented structures:

// packages/config/src/config/guard.rs:14
/// Route cache TTL in milliseconds.

Some doc comments are sentence fragments. While these are acceptable for field documentation, ensure consistency.


6. Response Body Streaming Comment Inconsistency

// packages/guard-core/src/proxy_service.rs:1003-1004
// Stream response through without buffering
// Response body size limits are enforced in pegboard-runner

The code removed the buffering logic entirely, which is good. However, it would be helpful to have a comment explaining why we always stream (to support large responses, SSE, etc.) rather than just stating the fact.

Recommendation: Expand the comment to explain the rationale: "Always stream responses to support large payloads, SSE, and chunked transfer encoding. Response body size limits are enforced in pegboard-runner.".


7. Middleware Timeout Handling

// packages/guard-core/src/proxy_service.rs:501-503
Err(_) => {
    // Fallback to config-based defaults if middleware times out
    tracing::warn!("middleware timed out, using fallback config");

Issue: The timeout error is discarded. This could hide issues with middleware performance.

Recommendation: Log more details about the timeout, including the actor_id: tracing::warn!(?actor_id, "middleware timed out, using fallback config")


8. WebSocket Config Creation

// packages/guard-core/src/proxy_service.rs:372-374
fn client_websocket_config(max_message_size: usize) -> WebSocketConfig {
    WebSocketConfig::default().max_message_size(Some(max_message_size))
}

Issue: The method name suggests it's only for client connections, but WebSocketConfig has separate settings for incoming vs outgoing messages. This method only sets max_message_size (incoming).

Recommendation: Either rename to client_websocket_config_incoming or add a parameter for outgoing size as well.


9. Type Conversion Safety

Multiple places use .unwrap_or() with large numbers:

self.gateway_hws_max_pending_size.unwrap_or(128 * 1024 * 1024) // 128 MiB

These are fine, but consider using constants for common sizes to avoid magic numbers:

const MIB: u64 = 1024 * 1024;
const GIB: u64 = 1024 * MIB;

self.gateway_hws_max_pending_size.unwrap_or(128 * MIB)

🎯 Testing Recommendations

  1. Test default value changes: Ensure all defaults work as expected for typical workloads
  2. Test limit enforcement: Verify that request/response body size limits are enforced correctly
  3. Test WebSocket message limits: Verify both incoming and outgoing message size limits
  4. Test middleware timeout fallback: Verify graceful degradation when middleware times out
  5. Test configuration override: Verify that config file values properly override defaults

📊 Performance Considerations

Good: Using Moka cache with proper TTLs for route and proxy state caching
Good: Streaming responses instead of buffering reduces memory pressure
Good: Per-actor configuration allows fine-tuning performance per workload

⚠️ Watch: Middleware timeout is set to 5 seconds. If middleware involves database lookups or external calls, this might be tight under load.


🔒 Security Considerations

Good: Rate limiting is configurable and has sensible defaults
Good: Request/response body size limits protect against DoS
Good: WebSocket message size limits prevent memory exhaustion
Good: Proper error messages don't leak internal details


📝 Summary

This is a well-structured PR that makes the platform more flexible and better documented. The main issues are:

  1. Critical: Fix the gateway_response_start_timeout_ms default value mismatch between code and docs
  2. Important: Complete the configuration documentation with all available options
  3. Minor: Deduplicate the RequestBodyTooLarge error definition

The code follows Rivet conventions well and the changes are backward compatible (all new config is optional with defaults).


Checklist

  • ✅ Code quality and best practices: Good overall structure
  • ⚠️ Potential bugs: Default value inconsistency needs fixing
  • ✅ Performance: Streaming responses improve memory usage
  • ✅ Security: Good limits and validation
  • ⚠️ Documentation: Needs completion with all config options

Recommendation: Request changes to fix the critical default value mismatch and complete the documentation before merging.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 11, 2026

More templates

@rivetkit/cloudflare-workers

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/cloudflare-workers@3824

@rivetkit/db

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/db@3824

@rivetkit/framework-base

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/framework-base@3824

@rivetkit/next-js

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/next-js@3824

@rivetkit/react

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/react@3824

rivetkit

pnpm add https://pkg.pr.new/rivet-dev/rivet/rivetkit@3824

@rivetkit/sql-loader

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sql-loader@3824

@rivetkit/virtual-websocket

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/virtual-websocket@3824

@rivetkit/engine-runner

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@3824

@rivetkit/engine-runner-protocol

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@3824

commit: caa66ae

@NathanFlurry NathanFlurry marked this pull request as draft January 12, 2026 22:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants