When the Service Is Slow or Uneven
Once Fastpotify knows which account and grant may act, a second problem appears: Spotify does not answer every request through the same path or at the same speed. This chapter follows how Fastpotify routes work by capability, splits a search across unequal sessions, and keeps waiting off the egui thread. The result is a useful distinction between a request that is slow, a request that is waiting for the right authority, and a response that has become too old to change the current interface.
Route by capability, not convenience
Fastpotify maintains separate shared and personal Web API sessions. The separation is not only a way to divide traffic. Each session has its own token provider, concurrency limit, cooldown after a rate-limit response, and visible network activity. The gateway chooses a session from the operation being attempted and from what the client has learned about the object involved.
A complete playlist library stays on the shared application because a personal Development Mode application may omit Spotify-owned or external playlists. Playlist search remains shared for the same coverage reason. By contrast, supported catalogue, user-data, playback, playlist-creation, and owned or collaborative-playlist operations can use the personal application when it is ready. An unknown playlist also stays on the shared route until a response reveals enough ownership information to classify it. Fastpotify is not choosing the personal route because it is newer or because its quota is separate. It is choosing it only where the source is allowed to answer.
This is a capability matrix hidden behind ordinary UI actions. Opening a playlist page may begin with an unknown access classification and therefore use the shared session. Once the response identifies the playlist as owned or collaborative, later item reads or mutations may be eligible for the personal session. An external playlist remains shared. If Spotify answers that a presumed personal operation is forbidden, Fastpotify can invalidate the stored classification and make a later request reconsider the route. The routing decision is consequently stateful, but it is state about capability, not a guess about user preference.
The classification is deliberately conservative. Unknown is not treated as personal merely because the user can see the playlist, and an empty local record is not treated as proof that Spotify has no such object. The gateway learns from responses and keeps the operation attached to the access category that supports it. That prevents a temporary lack of metadata from turning into a false claim about ownership or a mutation sent through an application that cannot answer the request.
The personal application therefore improves some delays without eliminating shared access. It gives supported requests a separate Development Mode quota, while shared access preserves operations that a personal app cannot answer completely. This is an important trade-off. A simpler design would send everything through the personal app and fail on missing playlist coverage, or send everything through the shared app and give up the available quota isolation. Fastpotify accepts the harder design because the service itself is uneven.
The transport layer applies the same discipline after routing. It limits the number of requests that can be in flight for a session rather than allowing every view and background refresh to compete without a ceiling. When Spotify returns Retry-After, the client pauses that session for the requested period, within a bounded retry policy. A shared session's cooldown does not unnecessarily stop eligible personal work, and a personal session's exhaustion does not make shared playlist coverage disappear. If Spotify returns an unauthorized response, the client can invalidate and refresh once rather than blindly repeating the same request. Persistent rate limiting is surfaced as an error instead of being hidden behind endless retries.
The distinction between a rate limit and a quota boundary matters. A Retry-After response says that a session should wait before trying again.