
Adding Personhog RPC
FreeStreamline the process of adding RPCs to Personhog.
Free · Opens the source repo
What Adding Personhog RPC does
The Adding Personhog RPC skill provides a comprehensive guide for developers looking to integrate new Remote Procedure Calls (RPCs) into the Personhog service. This skill covers the entire process, from defining the proto messages to implementing the necessary code in Rust, and generating client stubs for both Python and Node.js. By following the structured steps outlined in the skill, developers can ensure that their new RPCs are compatible with existing data structures and maintain the integrity of the Personhog API.
Before starting the implementation, the skill emphasizes the importance of performing eligibility checks to confirm that the data being accessed resides within the appropriate tables. This ensures that only relevant data is processed through Personhog, thereby maintaining the system's efficiency and reliability. The skill also guides users through the design of the data access pattern, highlighting the need for valid SQL queries and index compatibility, which are crucial for optimal performance.
The skill details the steps to define proto messages and RPCs, including where to place the new definitions within the project structure. It also outlines best practices for implementing the RPC in Rust, ensuring that developers understand the requirements for both leader and replica RPCs. Additionally, the skill provides clear instructions for generating client stubs, allowing seamless integration with existing Python and Node.js clients. This comprehensive approach makes the Adding Personhog RPC skill an essential resource for developers working with the Personhog service.
When to use it
Use this skill when you need to add a new gRPC endpoint or migrate a Django ORM query to Personhog.
When not to use it
This skill is not suitable for data that does not reside in the specified Personhog tables or for operations that do not conform to the RPC requirements.
What you can build with it
Adding a New Feature Flag RPC
When implementing a new feature flag in Personhog, this skill provides the necessary steps to create the corresponding RPC.
Migrating Django ORM Queries
Use this skill to convert existing Django ORM queries into RPCs that are compatible with the Personhog architecture.
Extending the Personhog API
If you need to extend the Personhog service API, this skill outlines the process for adding new RPCs effectively.
How to install Adding Personhog RPC
View source1. Install with the skills CLI
npx skills add posthog/posthog/adding-personhog-rpc --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by posthogAdding a personhog RPC
This skill walks through adding a new RPC end-to-end: proto definition, code generation, Rust implementation, and client updates.
Before you start: eligibility check
Personhog serves person, distinct ID, group, group type mapping, cohort membership, and feature flag hash key override data. If the data being accessed doesn't live in one of these tables, this RPC doesn't belong in personhog:
| Table | Data category | Routing |
|---|---|---|
posthog_person | PersonData | Reads: replica (eventual) or leader (strong). Writes: leader |
posthog_persondistinctid | PersonData | Same as person |
posthog_group | NonPersonData | All ops: replica |
posthog_grouptypemapping | NonPersonData | All ops: replica |
posthog_cohortpeople | NonPersonData | All ops: replica |
posthog_featureflaghashkeyoverride | NonPersonData | All ops: replica |
posthog_personoverride | PersonData | Reads/writes follow person routing |
posthog_personlessdistinctid | PersonData | Same as person |
If the table is not listed above, stop — this data should not go through personhog.
Step 0: design the data access pattern
Before writing any proto, figure out the SQL query you need. Then validate it against the available indexes — see references/database-indexes.md.
Key questions:
- What table(s) does this query hit?
- Does the WHERE clause match an existing index? Every query must be an index scan, never a sequential scan.
- Is this a read or write? This determines routing (see table above).
- For reads: does the caller need strong consistency (primary pool) or is eventual (replica pool) acceptable?
- For batch lookups: is the batch within a single team or cross-team?
Step 1: define proto messages and RPC
All proto files live in proto/personhog/.
See references/proto-conventions.md for message conventions and a worked example.
Where to add what
- Message types →
proto/personhog/types/v1/<domain>.proto(person.proto, group.proto, cohort.proto, feature_flag.proto, or common.proto) - Service RPC →
proto/personhog/service/v1/service.proto(the public API clients call) - Replica RPC →
proto/personhog/replica/v1/replica.proto(the internal API the router delegates to) - Leader RPC →
proto/personhog/leader/v1/leader.proto(only if this is a person-data write routed to leader)
The service and replica protos must both declare the RPC with identical signature. The router delegates from service → replica (or leader) transparently.
Leader RPCs must be safe under at-least-once delivery
A leader-path request can be delivered more than once: clients retry UNAVAILABLE after ambiguous failures,
and the router internally replays fence- and transport-bounced requests.
Every leader RPC must therefore converge under redelivery —
read-only lookups, merges that re-apply to the same state, tombstone-style deletes, max-merge version floors —
or carry explicit operation identity so duplicates can be detected.
Note the precise contract: a convergent merge still loses to interleaving
(a replay can clobber a same-field write another caller made in between);
that residual is accepted today and closes with operation identity (see personhog-leader's README).
An RPC that neither converges nor carries identity (an unguarded increment, an append) must not be added.
If the operation you need fits neither shape, redesign it to carry an idempotency key before defining the proto.
Step 2: generate client stubs
Python
bin/generate_personhog_proto.sh
Then update three files:
posthog/personhog_client/proto/__init__.py— add re-exports for new request/response message typesposthog/personhog_client/client.py— add a wrapper method matching the pattern of existing methodsposthog/personhog_client/fake_client.py— implement the method for test use
Node.js
cd nodejs && pnpm run generate:personhog-proto
Then update:
nodejs/src/common/personhog/groups.tsorpersons.ts— add a wrapper method to the matching operations class (PersonHogGroupOperations/PersonHogPersonOperations), following the pattern of existing methods.client.tsonly constructs and exposes these operation objects; it holds no RPC wrappers itself.nodejs/src/common/personhog/client.test.ts— add a default stub toSERVICE_DEFAULTSfor the new RPC
Rust
No generation step needed — tonic regenerates on cargo build.
But you must implement the RPC (next step), or the build will fail.
Step 3: implement in Rust
The compiler guides you — once the proto is defined, cargo build errors tell you exactly which trait methods are missing.
3a. Storage layer (personhog-replica)
- Add a trait method in
rust/personhog-replica/src/storage/traits/<domain>.rs - Implement the query in
rust/personhog-replica/src/storage/postgres/<domain>.rs- Use
sqlx::query_as!orsqlx::query!macros - Add timing instrumentation via
DB_QUERY_DURATIONandDB_ROWS_RETURNEDmetrics - Use
self.replica_poolfor reads,self.primary_poolfor writes - Return early for empty batch inputs
- Use
- Add storage tests in
rust/personhog-replica/tests/storage_tests.rs
3b. Service layer (personhog-replica)
- Add the RPC handler in
rust/personhog-replica/src/service/mod.rs- Extract fields from the proto request
- Call the storage trait method
- Convert storage results to proto responses
- Map storage errors to tonic
Statuscodes
- Add service tests in
rust/personhog-replica/tests/service_tests.rs
3c. Router wiring (personhog-router)
- Add the method to
rust/personhog-router/src/router/mod.rs- Use the
route_requestfunction (imported fromrouting.rs) with the correctDataCategoryandOperationType - Call the replica (or leader) backend
- Use the
call_backend!macro for instrumentation
- Use the
- Add the service impl to
rust/personhog-router/src/service/mod.rs- Invoke the
route_request!macro (defined at the top of this file) to delegate to the router
- Invoke the
- Add to the backend trait in
rust/personhog-router/src/backend/mod.rsand implement inreplica.rs - Add router tests in
rust/personhog-router/tests/
Use rstest parameterized tests where multiple variations of the same behavior are being tested.
Step 4: verify
cargo build -p personhog-proto
cargo build -p personhog-replica
cargo build -p personhog-router
cargo test -p personhog-replica
cargo test -p personhog-router
Checklist
- Query uses an existing index (no seq scans)
- Proto messages added to
types/v1/<domain>.proto - RPC added to both
service.protoandreplica.proto(andleader.protoif needed) - Leader RPCs only: operation is safe under at-least-once delivery (convergent under redelivery — read-only, re-appliable merge, tombstone, max-merge — or carries explicit operation identity)
- Python stubs generated,
proto/__init__.pyupdated,client.pymethod added,fake_client.pyupdated - Node.js stubs generated,
client.test.tsSERVICE_DEFAULTS updated - Rust storage trait + postgres impl + service handler + router wiring all implemented
- Tests added at storage, service, and router layers
-
cargo buildandcargo testpass for all three crates
Frequently asked questions about Adding Personhog RPC
Similar skills
WinMD API Search
Easily find and explore Windows desktop APIs.
WebMCPify
Transform any web app into an agent-ready platform.
Phoenix Tracing
Instrument LLM applications with OpenInference tracing.
Foundry Hosted Agent CopilotKit
Guidance for developing agentic web apps on Azure.
Power Automate Foundation
Connect AI agents to Power Automate seamlessly.
Power Automate Flow Builder
Efficiently build and deploy Power Automate flows programmatically.
