Instant Issue Navigation: How GitHub Rethought Performance for Developers
The Problem of Latency
When developers move through a backlog—opening an issue, jumping to a linked thread, then returning to the list—every millisecond of delay breaks their focus. These small pauses accumulate, and they feel most painful during those critical moments when staying in flow matters most. GitHub Issues wasn't inherently slow; the real issue was that too many navigations still required redundant data fetching, repeatedly interrupting the user's train of thought.

Earlier this year, our team set out to change that. Instead of chasing marginal backend wins, we transformed how issue pages load end-to-end by shifting work to the client and optimizing perceived latency. The core idea: render instantly from locally available data, then revalidate in the background. To achieve this, we built a client-side caching layer backed by IndexedDB, added a preheating strategy to boost cache hit rates without flooding the server, and introduced a service worker so cached data remains usable even during hard navigations.
A Client-First Approach
In late 2026, “fast enough” is no longer a competitive advantage—especially for developer tools where latency directly impacts product quality. When someone is triaging multiple issues, reviewing a feature request, or reporting a bug, every avoidable wait breaks their rhythm. Modern local-first applications and aggressively optimized clients have raised the bar from “loads in a second” to “feels instant.” Users no longer compare us to older web apps; they compare us to the fastest experience they encounter daily.
GitHub Issues is used by millions weekly to keep codebases running smoothly. As Issues becomes the planning layer for AI-assisted work, perceived performance becomes even more critical. If the loop between intent and feedback is slow, the entire system feels sluggish. We heard from both internal teams and the community that Issues felt heavy compared to tools built with speed as a first principle. The bottleneck wasn't feature depth or correctness—it was architecture and request lifecycle. Too many common paths still bore the full cost of server rendering, network fetches, and client boot, even when the data hadn't changed.
Our solution: shift the architecture to make instant navigation the default, not the exception.
The Architecture: Caching, Preheating, and Service Workers
Client-Side Caching with IndexedDB
We built a caching layer that stores issue data locally using IndexedDB. When a user navigates to an issue, the page first renders from this local cache—providing instantaneous content—then checks for updates in the background. This eliminates the full round-trip delay for the initial render.
Preheating Strategy
To maximize cache hit rates without spamming the server, we implemented a preheating strategy. It proactively fetches and caches issues that are likely to be visited next, based on common navigation patterns (e.g., linked threads, recent activity). This reduces the chance of a cache miss during key interactions.

Service Worker
We introduced a service worker that intercepts navigation requests and serves cached responses even during hard navigations (like a page refresh). This means users can reload an issue page and still see content instantly if it's in the cache, while the worker fetches updates in parallel. This covers paths that used to be slow—like opening an issue from a notification or returning from a deep link.
Measuring the Impact
The results across real-world usage have been significant. Perceived load times dropped by over 60% for typical navigation flows. Cache hit rates now exceed 90% for repeat views, and the preheating strategy reduces cold-start misses by half. Users report feeling less friction when moving between issues, which translates to fewer context switches and more time spent in productive flow.
But these improvements don't come for free. The client-side approach introduces tradeoffs:
- Increased memory usage: IndexedDB stores consume local storage, though we keep the cache bounded to a reasonable size.
- Staleness risk: Since data is served locally before revalidation, there's a small window where the user might see outdated info. We mitigate this with background sync and clear indicators when data is being refreshed.
- Service worker complexity: Managing cache invalidation and updates requires careful logic to avoid serving stale or corrupted data.
Tradeoffs and Future Work
We're proud of the progress, but we know the work isn't done. Our goal is to make “fast” the default across every path into Issues. That includes optimizing initial loads for first-time visitors, handling offline scenarios more gracefully, and extending the caching model to other parts of GitHub (like pull requests and discussions).
If you're building a data-heavy web app, these patterns are directly transferable. You can apply the same model—render locally, revalidate in background—to reduce perceived latency without waiting for a full rewrite. Start with a caching layer, a preheating strategy for common navigation paths, and a service worker to handle hard navigations. The result: your users will feel the speed, and your product will stand out.
Related Articles
- Breaking the WebRTC Forking Cycle: Meta's Modular Approach to Real-Time Communication at Scale
- Open Source Documentary Series Explores Unsung Heroes of the Internet
- Breaking the Forking Trap: How Meta Built a Future-Proof WebRTC Architecture
- Valkey-Swift 1.0 Released – Production-Ready Swift Client for Valkey and Redis with Full Concurrency Safety
- Revolutionizing GitHub Issues: How We Made Navigation Instant
- How to Improve Open Source Documentation: A Case Study with Git
- New Documentary Series Explores Unsung Heroes of Open Source Software
- Rust's Google Summer of Code 2026: A New Wave of Open Source Contributions