Skip to content

Use int64 for counts/sizes by default - #32

Merged
lberrymage merged 1 commit into
mainfrom
int64-by-default
Oct 16, 2026
Merged

lberrymage merged 1 commit into
mainfrom
int64-by-default

Conversation

@lberrymage

Copy link
Copy Markdown
Member

Until now, we've been using uint32 to represent "small", non-negative values in our protobuf schema. However, there are a couple of issues with doing this:

  • Multiple languages including Kotlin/Java (which we use extensively on both our main client and server) don't have unsigned integer types either in the language or in protobuf generated code, forcing us to transfer unsigned values in and out of signed integer types and perform fallible conversions when interoperating with other code.
  • "small" is not well-defined, and while unlikely for many fields, it is quite possible for us to outgrow a uint32 for certain APIs.

int64 has the same wire encoding as uint32 while mostly resolving the first issue and clearly resolving the second, so it seems to make sense to use it instead of uint32 everywhere (with appropriate protovalidate annotations to forbid negative values). Admittedly, one downside of int64 over int32 is that it isn't the "native" collection size type on the JVM on in JavaScript, so conversions might be necessary in some places. However, int32 -> int64 conversion is lossless, TypeScript/JavaScript have bigint literals for convenience, and overall it looks like using int64 by default across the API will reduce the number of conversions we have to do in our code, though we might need slightly more in TypeScript code.

The "by default" is because some fields clearly have a different integer type which is defined by some external system and so should be represented similarly in our API for better interoperability. For example, right now AppPackage.target_sdk is still int32 because that's the type defined by the Android platform.

Until now, we've been using uint32 to represent "small", non-negative
values in our protobuf schema. However, there are a couple of issues
with doing this:

- Multiple languages including Kotlin/Java (which we use extensively on
  both our main client and server) don't have unsigned integer types
  either in the language or in protobuf generated code, forcing us to
  transfer unsigned values in and out of signed integer types and
  perform fallible conversions when interoperating with other code.
- "small" is not well-defined, and while unlikely for many fields, it is
  quite possible for us to outgrow a uint32 for certain APIs.

int64 has the same wire encoding as uint32 while mostly resolving the
first issue and clearly resolving the second, so it seems to make sense
to use it instead of uint32 everywhere (with appropriate protovalidate
annotations to forbid negative values). Admittedly, one downside of
int64 over int32 is that it isn't the "native" collection size type on
the JVM on in JavaScript, so conversions might be necessary in some
places. However, int32 -> int64 conversion is lossless,
TypeScript/JavaScript have bigint literals for convenience, and overall
it looks like using int64 by default across the API will reduce the
number of conversions we have to do in our code, though we might need
slightly more in TypeScript code.

The "by default" is because some fields clearly have a different integer
type which is defined by some external system and so should be
represented similarly in our API for better interoperability. For
example, right now AppPackage.target_sdk is still int32 because that's
the type defined by the Android platform.
@lberrymage lberrymage added the buf skip breaking Skip Buf breaking change detection for this PR label Oct 16, 2026
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

The latest Buf updates on your PR. Results from workflow Buf CI / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed⏩ skippedOct 16, 2026, 3:06 AM

@lberrymage
lberrymage merged commit fdb2509 into main Oct 16, 2026
6 checks passed
@lberrymage
lberrymage deleted the int64-by-default branch October 16, 2026 03:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

buf skip breaking Skip Buf breaking change detection for this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant