Skip to content

perf: Cache project identifier lookups - #24

Closed
matthewelwell wants to merge 1 commit into
mainfrom
perf/cache-project-lookups
Closed

perf: Cache project identifier lookups#24
matthewelwell wants to merge 1 commit into
mainfrom
perf/cache-project-lookups

Conversation

@matthewelwell

@matthewelwell matthewelwell commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

GetFeature and GetSegment resolve their project on every call, purely to populate ProjectUUID — which the API never returns. For a caller working through many features in one project, that's a redundant request per entity.

This caches the immutable identifiers of a project (UUID and organisation ID) and the UUID→ID mapping, so each is fetched at most once per client.

GetFeature   2 requests → 1 after the first entity in a project
GetSegment   2 requests → 1

getProjectID is cached too, so CreateFeature, CreateSegment, UpdateSegment and GetTag benefit as well.

What is and isn't cached

Only immutable fields: a project's UUID and its organisation. GetProject and GetProjectByID stay uncached, so a caller reading a project after updating it still sees current values. That's the whole reason for the narrow projectRef struct rather than caching *Project.

Cache lifetime is the client's lifetime, with no invalidation. That's the right trade for a short-lived client (the Terraform provider builds one per plan/apply); a long-lived process would hold these until restart, which is safe precisely because the cached fields can't change.

Also exported

GetProjectIDByUUID, so callers that need a project ID before they have one — creating a feature, say — can resolve it without a round trip of their own.

🤖 Generated with Claude Code

GetFeature and GetSegment each resolve their project on every call, purely to
populate ProjectUUID, which the API never returns. For a caller working through
many features in one project -- the Terraform provider, for instance -- that is
one redundant request per entity.

Caches the immutable identifiers of a project (UUID and organisation) and the
UUID to ID mapping, so each is fetched at most once per client. GetFeature and
GetSegment drop from two requests to one after the first entity in a project,
and getProjectID is now cached too, which also covers CreateFeature,
CreateSegment, UpdateSegment and GetTag.

Only immutable fields are cached. GetProject and GetProjectByID stay live, so a
caller that reads a project after updating it still sees current values.

Also exports GetProjectIDByUUID, so callers that need a project ID before they
have one -- creating a feature, for example -- can resolve it without a second
round trip of their own.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@matthewelwell
matthewelwell force-pushed the perf/cache-project-lookups branch from 801dcee to fd5b450 Compare August 25, 2026 18:00
@matthewelwell

Copy link
Copy Markdown
Contributor Author

Closing: premature optimisation. GetFeature/GetSegment re-resolving the project on each call is a real redundancy, but not one worth caching for until it's measurably a problem — and caching brings a mutex and a staleness question with it.

If it does become worth doing, the right fix is probably upstream anyway: get-by-uuid could return the project UUID and remove the second request entirely, rather than us caching around its absence.

@matthewelwell
matthewelwell deleted the perf/cache-project-lookups branch August 25, 2026 18:06
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.

1 participant