Agent skill

Relay Performance

by hackers-pub in hackers-pub/hackerspub

Performance best practices for Relay applications. An agent skill from hackers-pub/hackerspub.

AGPL-3.0Auto-check passedBackend & APIs

Install Relay Performance

skills CLI
$ npx skills add hackers-pub/hackerspub --skill relay-performance -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install hackers-pub/hackerspub relay-performance --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/hackers-pub/hackerspub.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/relay-performance .claude/skills/relay-performance && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
relay-performance
GitHub stars
165
Token cost
~2.2k tokens
SKILL.md length
621 words
Files
1
Skills in repo
5
Repo updated
First seen
Licence
AGPL-3.0

At a glance

Performance best practices for Relay applications. An agent skill from hackers-pub/hackerspub.

  • Optimizing data fetching
  • SKILL.md covers One Query Per Screen, Preload Before Rendering the…, Use @defer for Non-Critical… and Fetch Policies, plus 7 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md
  • Reducing re-renders

What it does

Relay Performance is an agent skill from hackers-pub/hackerspub. Performance best practices for Relay applications. Use when optimizing data fetching, reducing re-renders, configuring caching, or improving time to first meaningful paint. Covers query placement, @defer, pagination, fetch policies, garbage collection, fragment granularity, and server-side filtering. Companion to the relay-best-practices skill which covers correctness and architecture.

Its SKILL.md is about 2.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Backend & APIs, covering Backend development and Caching. The repository describes itself as: ActivityPub-enabled social network for hackers. The licence is AGPL-3.0.

When your agent uses it

  • Optimizing data fetching
  • Reducing re-renders
  • Configuring caching
  • Improving time to first meaningful paint

Example prompts

  • “/relay-performance”

What it can do on your machine

Read from SKILL.md and the folder at commit 7280aa7. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript and graphql).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Relay Performance loads about 2.2k tokens when it runs. Until then it costs about 102 tokens; SKILL.md has 621 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~102
When it runs · the whole SKILL.md, loaded when a task matches
~2.2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from hackers-pub/hackerspub at commit 7280aa7, republished under its AGPL-3.0 licence (© hackers-pub). 621 words, ~2,205 tokens.

Download SKILL.mdSave it as .claude/skills/relay-performance/SKILL.md (or your agent's skills folder).
name
relay-performance
description
Performance best practices for Relay applications. Use when optimizing data fetching, reducing re-renders, configuring caching, or improving time to first meaningful paint. Covers query placement, @defer, pagination, fetch policies, garbage collection, fragment granularity, and server-side filtering. Companion to the relay-best-practices skill which covers correctness and architecture.

Relay Performance Best Practices

Performance-focused guidance for Relay applications. For correctness, naming, and architectural patterns, see the relay-best-practices skill.

For detailed API documentation, read the relevant page from <llm-docs>/ (available in node_modules/relay-runtime/llm-docs/ after v20.1.1).

One Query Per Screen

Each screen or route should have one (or very few) root queries. Relay coalesces all fragment data needs into a single network request per query. Multiple root queries on the same screen defeat this optimization — the browser makes multiple parallel requests that each carry redundant overhead (HTTP headers, connection setup, response parsing).

GOOD:                              BAD:
Route → 1 query                    Route → 3 queries
  ├─ Header (fragment)               ├─ Header (query #1)
  ├─ Content (fragment)               ├─ Content (query #2)
  └─ Sidebar (fragment)               └─ Sidebar (query #3)

Preload Before Rendering the Root

Fetch the initial query before calling createRoot().render(). This overlaps the network request with React's initialization, minimizing time to first meaningful paint.

tsx
// Start fetch immediately — before React even initializes
const queryRef = loadQuery(environment, AppQuery, initialVariables);

// Then render — data may already be available
const root = createRoot(document.getElementById('root'));
root.render(
  <RelayEnvironmentProvider environment={environment}>
    <Suspense fallback={<AppSkeleton />}>
      <App queryRef={queryRef} />
    </Suspense>
  </RelayEnvironmentProvider>
);

Use @defer for Non-Critical Content

Defer secondary or below-the-fold content so primary UI renders faster. Relay streams deferred data progressively via Suspense — the initial response arrives smaller and the critical path renders sooner.

graphql
query ProfileScreenQuery($id: ID!) {
  user(id: $id) {
    ...ProfileHeader_user
    ...ProfileDetails_user @defer
    ...ProfileComments_user @defer
  }
}
tsx
function ProfileScreen({ queryRef }) {
  const data = usePreloadedQuery(ProfileScreenQuery, queryRef);

  return (
    <ScrollView>
      <ProfileHeader user={data.user} />
      <Suspense fallback={<DetailsSkeleton />}>
        <ProfileDetails user={data.user} />
      </Suspense>
      <Suspense fallback={<CommentsSkeleton />}>
        <ProfileComments user={data.user} />
      </Suspense>
    </ScrollView>
  );
}

Good candidates for @defer:

  • Sidebar content
  • Below-the-fold sections
  • Tabs and accordions not visible on initial load
  • Heavy item details in paginated lists

Fetch Policies

store-or-network (the default) is correct for most cases — it reuses cached data and only hits the network for missing or stale data.

PolicyWhen to use
store-or-networkDefault. Best balance of speed and freshness.
store-and-networkShow cached data immediately, update in background.
network-onlyFreshness is critical (e.g., after a mutation with wide side effects).
store-onlyOffline-first or reading data already guaranteed to be in the store.

Reserve network-only for rare cases. Overusing it turns Relay into a no-cache client and eliminates the benefit of the normalized store.

Configure Garbage Collection

Set gcReleaseBufferSize on the Relay Store to retain recently-used queries after their components unmount. The default is 10. This makes navigating back to a previously visited screen instant (data is still in the store) instead of triggering a new network request.

tsx
const store = new Store(new RecordSource(), {
  gcReleaseBufferSize: 20,
});

For apps with many screens or heavy navigation, increase the buffer. For memory-constrained environments (mobile), keep it conservative.

Filter and Sort on the Server

Use GraphQL field arguments to filter and sort data on the server rather than fetching everything and processing in JavaScript.

tsx
// BAD: fetch all tasks, filter on client
const data = useFragment(graphql`
  fragment TaskList_user on User {
    tasks { id, title, status }
  }
`, user);
const active = data.tasks.filter(t => t.status === 'ACTIVE');

// GOOD: filter on server via field argument
const data = useFragment(graphql`
  fragment TaskList_user on User {
    tasks(status: ACTIVE) { id, title }
  }
`, user);

Server-side filtering reduces payload size, avoids unnecessary network transfer, and reduces memory usage on the client.

Show full SKILL.md (257 more words)Show less

Never Fetch Unbounded Collections

Always paginate list fields using @connection + usePaginationFragment. Fetching an entire collection at once risks transferring megabytes of data, stalling the UI during normalization, and exhausting device memory.

Start with a page size appropriate for the viewport (e.g., 10–20 items) and load more on scroll.

graphql
# BAD: fetches every item — unbounded
fragment NotificationList_user on User {
  notifications {
    id
    message
  }
}

# GOOD: paginated with a bounded first page
fragment NotificationList_user on User
  @argumentDefinitions(
    count: { type: "Int", defaultValue: 10 }
    cursor: { type: "String" }
  )
  @refetchable(queryName: "NotificationListPaginationQuery") {
  notifications(first: $count, after: $cursor)
    @connection(key: "NotificationList_notifications") {
    edges {
      node {
        id
        message
      }
    }
  }
}

Keep Fragments Granular

Split large fragments into smaller, component-scoped fragments so Relay can re-render only the components whose data actually changed. A single monolithic fragment shared by many components causes all of them to re-render when any field in the fragment changes.

tsx
// BAD: one large fragment, all children re-render on any field change
function PostCard({ post }) {
  const data = useFragment(graphql`
    fragment PostCard_post on Post {
      title
      body
      author { name, profilePicture { uri } }
      likeCount
      commentCount
    }
  `, post);
  return (
    <>
      <PostHeader title={data.title} author={data.author} />
      <PostBody body={data.body} />
      <PostFooter likes={data.likeCount} comments={data.commentCount} />
    </>
  );
}

// GOOD: each child owns its fragment, re-renders independently
function PostHeader({ post }: { post: PostHeader_post$key }) {
  const data = useFragment(graphql`
    fragment PostHeader_post on Post {
      title
      author { name }
    }
  `, post);
  // Only re-renders when title or author.name changes
}

function PostFooter({ post }: { post: PostFooter_post$key }) {
  const data = useFragment(graphql`
    fragment PostFooter_post on Post {
      likeCount
      commentCount
    }
  `, post);
  // Only re-renders when like/comment counts change
}

One Connection Per Component

Use a single usePaginationFragment per component. Multiple connections in one component make pagination state harder to reason about — cursor tracking, loading states, and hasNext flags become tangled. Split each connection into its own component instead.

Avoid Unnecessary Refetches

After a mutation, let Relay's normalized store auto-update components by spreading relevant fragments in the mutation response. Do not call refetch() or fetchQuery() when the store update is sufficient.

graphql
# GOOD: updated data comes back with the mutation response
mutation UpdateUserMutation($input: UpdateUserInput!) {
  updateUser(input: $input) {
    user {
      ...UserProfile_user
      ...UserAvatar_user
    }
  }
}

# BAD: requires a separate round-trip after mutation
mutation UpdateUserMutation($input: UpdateUserInput!) {
  updateUser(input: $input) {
    user { id }
  }
}

Use fetchKey sparingly — changing it forces a full network round trip. Reserve refetchQueries / manual refetch for cases where the mutation's side effects are too broad to capture in the response payload.

Fetch Only What You Need

Each fragment should request only the fields the component actually renders. Do not add fields "just in case" — unused fields increase payload size and slow down parsing and normalization. Relay's unused-fields lint rule catches this.

If a child component needs more data, add a fragment to the child and spread it in the parent — do not widen the parent's fragment.

© hackers-pub, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/relay-performance of hackers-pub/hackerspub.

Open the folder on GitHubat commit 7280aa7

Compare with similar skills

Relay Performance next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Relay Performance compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Relay Performance this skillhackers-pub/hackerspub165—~2.2kAutomated safety check: PassAGPL-3.0
FastAPI-Redis SDK Developmentredis/fastapi-redis-sdk404—~2.5kAutomated safety check: NotesMIT
Nitro Server Toolkitantfu/skills5.9k—~948Automated safety check: PassMIT
Backend Servicesbiersoeckli/QuickStack362—~552Automated safety check: PassGPL-3.0
Dotnet Backend Patternswshobson/agents40k8 repos~6.6kAutomated safety check: PassMIT
Springboot Patternsaffaan-m/ECC275k5 repos~2.5kAutomated safety check: PassMIT

Similar skills

  • FastAPI-Redis SDK Development

    redis/fastapi-redis-sdk

    Official

    Guides development on the fastapi-redis-sdk library itself - its connection lifecycle, dependency-injected caching, and async/sync bridging.

    404 GitHub stars~2.5k tokensUpdated 7 days ago
    Backend & APIsAuto-check: notes
  • Reference for Nitro v3, the server toolkit behind Nuxt: file routing, route rules, caching, storage, tasks, websockets and deployment presets.

    5.9k GitHub stars~948 tokensUpdated 9 days ago
    Backend & APIsAuto-check passed
  • Backend Services

    biersoeckli/QuickStack

    Create and update QuickStack backend services, adapters, standalone services, and server actions using the project's established singleton, adapter, caching, and error-handling patterns.

    362 GitHub stars~552 tokensUpdated yesterday
    Backend & APIsAuto-check passed
  • Master C/.NET backend development patterns for building robust APIs, MCP servers, and enterprise applications.

    40k GitHub starsUsed in 8 repos~6.6k tokens
    Backend & APIsAuto-check passed
  • Spring Boot architecture patterns, REST API design, layered services, data access, caching, async processing, and logging.

    275k GitHub starsUsed in 5 repos~2.5k tokens
    Backend & APIsAuto-check passed
  • AWS SDK Java V2 Secrets Manager

    giuseppe-trisciuoglio/developer-kit

    Provides AWS Secrets Manager patterns for AWS SDK for Java 2.x, including secret retrieval, caching, rotation-aware access, and Spring Boot integration.

    355 GitHub starsUsed in 1 repo~1.5k tokens
    Backend & APIsAuto-check: notes

More from hackers-pub/hackerspub

  • Graphql Schema Design

    hackers-pub/hackerspub

    GraphQL schema design and review. An agent skill from hackers-pub/hackerspub.

    165 GitHub stars~2.5k tokensUpdated yesterday
    Auto-check passed
  • I18n

    hackers-pub/hackerspub

    Fill in missing translations in web-next .po files, add i18n-aware UI labels to components, and ensure translation quality — consistent glossary terminology, correct punctuation/typography per…

    165 GitHub stars~2.5k tokensUpdated yesterday
    Auto-check passed
  • Relay Best Practices

    hackers-pub/hackerspub

    Best practices for writing idiomatic Relay code. An agent skill from hackers-pub/hackerspub.

    165 GitHub stars~4.6k tokensUpdated yesterday
    Auto-check passed
  • Commit

    hackers-pub/hackerspub

    Make a commit in Git with an appropriate commit message for the currently staged changes.

    165 GitHub starsUsed in 1 repo~485 tokens
    Auto-check passed

Categories

Questions about Relay Performance

What does Relay Performance do?

Performance best practices for Relay applications. An agent skill from hackers-pub/hackerspub. Relay Performance is an agent skill from hackers-pub/hackerspub. Performance best practices for Relay applications.

When should I use Relay Performance?

Relay Performance fits situations like: optimizing data fetching; reducing re-renders; configuring caching; improving time to first meaningful paint.

How do I install Relay Performance in Claude Code?

Run `npx skills add hackers-pub/hackerspub --skill relay-performance -a claude-code`. Or copy the skill folder (.agents/skills/relay-performance in hackers-pub/hackerspub) into .claude/skills/relay-performance in your project. Claude Code loads it when a task matches its description.

How do I install Relay Performance in Codex?

Run `npx skills add hackers-pub/hackerspub --skill relay-performance -a codex`. Or copy the skill folder (.agents/skills/relay-performance in hackers-pub/hackerspub) into .agents/skills/relay-performance in your project. Codex loads it when a task matches its description.

Can I use Relay Performance in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add hackers-pub/hackerspub --skill relay-performance -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/relay-performance, .gemini/skills/relay-performance, .github/skills/relay-performance and .opencode/skills/relay-performance in your project.

What does Relay Performance need to run?

SKILL.md names no scripts, command-line tools or credentials: Relay Performance is instructions for the agent only.

Does Relay Performance access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Relay Performance safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Relay Performance use?

Relay Performance is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Relay Performance use?

About 2.2k tokens (SKILL.md is roughly 8.8k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Relay Performance?

Skills that share tags, products or a category with Relay Performance: FastAPI-Redis SDK Development (redis/fastapi-redis-sdk, 404 stars), Nitro Server Toolkit (antfu/skills, 5.9k stars), Backend Services (biersoeckli/QuickStack, 362 stars) and Dotnet Backend Patterns (wshobson/agents, 40k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Relay Performance?

hackers-pub (a GitHub organization) maintains it in hackers-pub/hackerspub, which has 165 GitHub stars. The repository holds 5 skills in this directory. The repository was last updated on October 7, 2026.

Source: hackers-pub/hackerspub on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.