Skip to content

chore: Rate limit logging#5529

Merged
H2Shami merged 4 commits intomainfrom
rate-limit-logging
Jan 16, 2026
Merged

chore: Rate limit logging#5529
H2Shami merged 4 commits intomainfrom
rate-limit-logging

Conversation

@H2Shami
Copy link
Collaborator

@H2Shami H2Shami commented Jan 16, 2026

Ticket

Link to the ticket(s) this pull request addresses.

Component/Service

What part of Helicone does this affect?

  • Web (Frontend)
  • Jawn (Backend)
  • Worker (Proxy)
  • Bifrost (Marketing)
  • AI Gateway
  • Packages
  • Infrastructure/Docker
  • Documentation

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Performance improvement
  • Refactoring

Deployment Notes

  • No special deployment steps required
  • Database migrations need to run
  • Environment variable changes required
  • Coordination with other teams needed

Screenshots / Demos

Before After

Extra Notes

Any additional context, considerations, or notes for reviewers.

Context

Why are you making this change?

Screenshots / Demos

Copilot AI review requested due to automatic review settings January 16, 2026 00:58
@vercel
Copy link

vercel bot commented Jan 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Review Updated (UTC)
helicone Skipped Skipped Jan 16, 2026 1:00am
helicone-bifrost Skipped Skipped Jan 16, 2026 1:00am
helicone-eu Skipped Skipped Jan 16, 2026 1:00am

Review with Vercel Agent

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@supabase
Copy link

supabase bot commented Jan 16, 2026

This pull request has been ignored for the connected project bolqqmqbrciybnypvklh because there are no changes detected in supbase/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@supabase
Copy link

supabase bot commented Jan 16, 2026

This pull request has been ignored for the connected project lmahfbbnchpworytrrqk because there are no changes detected in .supabase/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@claude
Copy link
Contributor

claude bot commented Jan 16, 2026

Claude finished @H2Shami's task —— View job


Code Review Complete ✅

Score: 7/10 - Good implementation with minor improvement opportunities

This PR successfully implements comprehensive rate limiting logging with DataDog tracing integration. The code quality is good overall, with proper error handling and structured monitoring. However, there are some performance considerations and minor improvements that could enhance the implementation.

Suggestions Summary:

🔧 Performance Optimizations:

  • Consider moving trace initialization later to avoid overhead for non-rate-limited requests
  • Implement trace buffering for high-throughput scenarios

📊 Monitoring Enhancements:

  • Add missing metrics like response time for rate limit operations
  • Include cache hit/miss status in traces for better debugging

🏗️ Code Quality:

  • Improve variable naming and add JSDoc for key functions
  • Consider extracting tracing logic to reduce coupling

Detailed Review:

✅ Strengths:

  1. Comprehensive tracing: Well-structured DataDog integration with proper span management
  2. Error handling: Good error handling with fallback behavior when tracing fails
  3. Structured logging: Clear policy IDs and segment values for dashboard grouping
  4. Type safety: Proper TypeScript types maintained across all changes

🔍 Areas for Improvement:

ProxyForwarder.ts:67-73 - Move tracer initialization:

// Consider moving this after rate limit check to reduce overhead
// Only initialize tracer when rate limiting is actually needed
if (finalRateLimitOptions || proxyRequest.isRateLimitedKey) {
  const tracer = createDataDogTracer(env);
  const traceContext = tracer.startTrace(/*...*/);
}

DurableObjectRateLimiterClient.ts:109 - Enhance policy ID generation:

// More descriptive policy ID for better dashboard grouping
const policyId = `${organizationId}_${segment ?? "global"}_quota_${quota}_window_${time_window}s_unit_${unit}`;

DurableObjectRateLimiterClient.ts:154-165 - Add response time metric:

// Add timing information to spans
if (tracer && spanId) {
  const duration = performance.now() - startTime; // Add startTime variable
  tracer.setTag(spanId, "duration_ms", duration);
  // ... existing tags
}

DataDogTracer.ts:308-311 - Environment variable naming:
The dual support for DATADOG_APM_ENABLED and DATADOG_ENABLED is good for compatibility, but consider documenting this in the PR description.

🚨 Minor Issues:

  1. Type definition changes: The removal of Partial_VectorOperators_ in type files seems unrelated to rate limiting. Ensure this doesn't break existing functionality.

  2. Missing JSDoc: Key functions like getSegmentKeyValue and getRawSegmentValue could benefit from documentation.

  3. Error message improvement in DataDogTracer.ts:168 - while the change is minor, it's a good defensive programming practice.

🔒 Security & Performance:

  • ✅ Security: No security issues identified. Proper data sanitization in trace tags.
  • ⚠️ Performance: Trace initialization happens for every request, even when not needed. Consider lazy initialization.
  • ✅ Error handling: Proper fallbacks ensure rate limiting continues to work even if tracing fails.

🧪 Testing Recommendations:

  1. Test rate limiting behavior with tracing disabled
  2. Verify DataDog integration doesn't impact request latency significantly
  3. Test error scenarios (DO failures, DataDog API failures)
  4. Validate policy ID generation for various segment types

📝 Documentation:

Consider adding a comment explaining the policy ID format and its use in DataDog dashboards.


Overall Assessment: This is a solid implementation that adds valuable observability to rate limiting operations. The code follows good practices and maintains backward compatibility. The suggested improvements are primarily optimizations rather than critical fixes.


@vercel vercel bot temporarily deployed to Preview – helicone January 16, 2026 01:00 Inactive
@vercel vercel bot temporarily deployed to Preview – helicone-bifrost January 16, 2026 01:00 Inactive
@vercel vercel bot temporarily deployed to Preview – helicone-eu January 16, 2026 01:00 Inactive
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds comprehensive DataDog tracing and monitoring for rate limiting operations in the Worker (Proxy) component. The changes enable detailed observability of rate limit checks and updates, allowing teams to monitor rate limiting behavior through DataDog dashboards.

Changes:

  • Added DataDog tracing instrumentation to rate limit operations with policy IDs and segment values for dashboard grouping
  • Updated default APM sampling rate from 0.01 to 1 for non-production environments
  • Added support for alternative DATADOG_ENABLED environment variable alongside DATADOG_APM_ENABLED
  • Removed VectorOperators type from generated API schema files, replacing with TextOperators for request_body and response_body fields

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
worker/wrangler.toml Updated default DATADOG_APM_SAMPLING_RATE from "0.01" to "1" for comprehensive tracing in development
worker/src/lib/monitoring/DataDogTracer.ts Added DATADOG_ENABLED as alternative config variable and refactored error message assignment
worker/src/lib/clients/DurableObjectRateLimiterClient.ts Added comprehensive tracing spans for rate limit check and update operations with policy IDs and segment metadata
worker/src/lib/HeliconeProxyRequest/ProxyForwarder.ts Integrated DataDog tracer into proxy request flow and passed tracer context through the logging chain
web/lib/clients/jawnTypes/public.ts Removed VectorOperators schema and updated request_body/response_body to use TextOperators
web/lib/clients/jawnTypes/private.ts Removed VectorOperators schema and updated request_body/response_body to use TextOperators
helicone-mcp/src/types/public.ts Removed VectorOperators schema and updated request_body/response_body to use TextOperators
docs/swagger.json Removed VectorOperators schema definition and updated references to TextOperators
bifrost/lib/clients/jawnTypes/public.ts Removed VectorOperators schema and updated request_body/response_body to use TextOperators
bifrost/lib/clients/jawnTypes/private.ts Removed VectorOperators schema and updated request_body/response_body to use TextOperators
.claude/settings.local.json Added npm eslint and run_all_workers.sh to allowed bash commands

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


// Generate a policy_id for grouping in dashboards
// Format: org_segment_quota_window_unit (e.g., "abc123_tenant-id_100_60_request")
const policyId = `${organizationId}_${segment ?? "global"}_${quota}_${time_window}_${unit}`;
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The policyId format is duplicated in both checkRateLimit (line 109) and updateRateLimitCounter (line 208). Consider extracting this into a shared helper function to ensure consistency and easier maintenance.

Copilot uses AI. Check for mistakes.
"rate_limited",
response.status === "rate_limited" ? "true" : "false"
);
tracer.setTag(spanId, "remaining", response.remaining);
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The remaining value should be converted to a string since setTag expects string | number for the value parameter. While numbers are accepted, the other numeric tags in this section (lines 161-163) are already numbers, so this is consistent. However, on line 260, new_remaining is being set without conversion. Ensure consistent handling of numeric values.

Suggested change
tracer.setTag(spanId, "remaining", response.remaining);
tracer.setTag(spanId, "remaining", String(response.remaining));

Copilot uses AI. Check for mistakes.
@H2Shami H2Shami merged commit 7b92b89 into main Jan 16, 2026
12 of 14 checks passed
@H2Shami H2Shami deleted the rate-limit-logging branch January 16, 2026 02:21
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.

3 participants