Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

optimize ApiFromModules type performance #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ssalbdivad wants to merge 13 commits into get-convex:main
base: main
Choose a base branch
Loading
from ssalbdivad:type-optimizations

Conversation

@ssalbdivad
Copy link

@ssalbdivad ssalbdivad commented Aug 21, 2025
edited
Loading

This pull request optimizes ApiFromModules and adds type-level benchmarks using @ark/attest so that they can be tested and added to CI if desired.

A large portion of the diff will consist of fake_chef files copied from a generated Convex project as a realistic benchmark and can generally be ignored. All meaningful optimizations occurred in src/server/api.ts.

The biggest improvements come from avoiding the creation of intermediate object types, additional intersections, and adding a fast path for modules with no segmented (i.e. A/B) paths.

This lead to a ~27% improvement in type performance on the fast path and ~14% for segmented modules. Similar strategies could be applied to other types in the repo for further improvements, but generally I found the types I reviewed to be relatively efficient and well-written, so props to the team 👏

As mentioned to @thomasballinger, another promising avenue for followup type optimization would be deduplicating object literals defined in _generated/api.d.ts. Here's an example of how that could be achieved:

// current
export declare const components: {
 rateLimiter: {
 lib: {
 checkRateLimit: FunctionReference<
 "query",
 "internal",
 {
 config:
 | {
 capacity?: number
 kind: "token bucket"
 maxReserved?: number
 period: number
 rate: number
 shards?: number
 }
 | {
 capacity?: number
 kind: "fixed window"
 maxReserved?: number
 period: number
 rate: number
 shards?: number
 start?: number
 }
 count?: number
 key?: string
 name: string
 reserve?: boolean
 throws?: boolean
 },
 | { ok: true; retryAfter?: number }
 | { ok: false; retryAfter: number }
 >
 }
 }
}
// example optimization (should be reused for other components as well)
interface BaseConfig {
 capacity?: number
 maxReserved?: number
 period: number
 rate: number
 shards?: number
}
interface FixedWindowConfig extends BaseConfig {
 kind: "fixed window"
 start?: number
}
interface TokenBucketConfig extends BaseConfig {
 kind: "token bucket"
}
interface CommonArgs {
 config: FixedWindowConfig | TokenBucketConfig
 count?: number
 key?: string
 name: string
 reserve?: boolean
 throws?: boolean
}
type ReturnType =
 | { ok: true; retryAfter?: number }
 | { ok: false; retryAfter: number }
export declare const components: {
 rateLimiter: {
 lib: {
 checkRateLimit: FunctionReference<
 "query",
 "internal",
 CommonArgs,
 ReturnType
 >
 }
 }
}

Applying a similar approach to a large number of object literals in Prisma's generated types led to a ~50% performance improvement, so this could be very impactful for large projects with many such components.


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

1 participant

AltStyle によって変換されたページ (->オリジナル) /